1 /*****************************************************************************
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
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 /*****************************************************************************
29 * Revision 1.1.3.1 2011-02-28 14:53:20 lothar
30 * imported Ka-Ro specific additions to U-Boot 2009.08 for TX28
32 * Revision 1.102 2002/12/16 14:03:24 tschilli
33 * VCT code in Vct() changed.
35 * Revision 1.101 2002/12/16 09:04:10 tschilli
36 * Code for VCT handling added.
38 * Revision 1.100 2002/09/26 14:28:13 tschilli
39 * For XMAC the values in the SK_PNMI_PORT Port struct are copied to
40 * the new SK_PNMI_PORT BufPort struct during a MacUpdate() call.
41 * These values are used when GetPhysStatVal() is called. With this
42 * mechanism you get the best results when software corrections for
43 * counters are needed. Example: RX_LONGFRAMES.
45 * Revision 1.99 2002/09/17 12:31:19 tschilli
46 * OID_SKGE_TX_HW_ERROR_CTS, OID_SKGE_OUT_ERROR_CTS, OID_GEN_XMIT_ERROR:
47 * Double count of SK_PNMI_HTX_EXCESS_COL in function General() removed.
48 * OID_PNP_CAPABILITIES: sizeof(SK_PM_WAKE_UP_CAPABILITIES) changed to
49 * sizeof(SK_PNP_CAPABILITIES) in function PowerManagement().
51 * Revision 1.98 2002/09/10 09:00:03 rwahl
52 * Adapted boolean definitions according sktypes.
54 * Revision 1.97 2002/09/05 15:07:03 rwahl
57 * Revision 1.96 2002/09/05 11:04:14 rwahl
58 * - Rx/Tx packets statistics of virtual port were zero on link down (#10750)
59 * - For GMAC the overflow IRQ for Rx longframe counter was not counted.
60 * - Incorrect calculation for oids OID_SKGE_RX_HW_ERROR_CTS,
61 * OID_SKGE_IN_ERRORS_CTS, OID_GEN_RCV_ERROR.
62 * - Moved correction for OID_SKGE_STAT_RX_TOO_LONG to GetPhysStatVal().
63 * - Editorial changes.
65 * Revision 1.95 2002/09/04 08:53:37 rwahl
66 * - Incorrect statistics for Rx_too_long counter with jumbo frame (#10751)
67 * - StatRxFrameTooLong & StatRxPMaccErr counters were not reset.
68 * - Fixed compiler warning for debug msg arg types.
70 * Revision 1.94 2002/08/09 15:42:14 rwahl
71 * - Fixed StatAddr table for GMAC.
72 * - VirtualConf(): returned indeterminated status for speed oids if no
75 * Revision 1.93 2002/08/09 11:04:59 rwahl
76 * Added handler for link speed caps.
78 * Revision 1.92 2002/08/09 09:43:03 rwahl
79 * - Added handler for NDIS OID_PNP_xxx ids.
81 * Revision 1.91 2002/07/17 19:53:03 rwahl
82 * - Added StatOvrflwBit table for XMAC & GMAC.
83 * - Extended StatAddr table for GMAC. Added check of number of counters
84 * in enumeration and size of StatAddr table on init level.
85 * - Added use of GIFunc table.
86 * - ChipSet is not static anymore,
87 * - Extended SIRQ event handler for both mac types.
88 * - Fixed rx short counter bug (#10620)
89 * - Added handler for oids SKGE_SPEED_MODE & SKGE_SPEED_STATUS.
90 * - Extendet GetPhysStatVal() for GMAC.
91 * - Editorial changes.
93 * Revision 1.90 2002/05/22 08:56:25 rwahl
94 * - Moved OID table to separate source file.
95 * - Fix: TX_DEFFERAL counter incremented in full-duplex mode.
96 * - Use string definitions for error msgs.
98 * Revision 1.89 2001/09/18 10:01:30 mkunz
99 * some OID's fixed for dualnetmode
101 * Revision 1.88 2001/08/02 07:58:08 rwahl
102 * - Fixed NetIndex to csum module at ResetCounter().
104 * Revision 1.87 2001/04/06 13:35:09 mkunz
105 * -Bugs fixed in handling of OID_SKGE_MTU and the VPD OID's
107 * Revision 1.86 2001/03/09 09:18:03 mkunz
108 * Changes in SK_DBG_MSG
110 * Revision 1.85 2001/03/08 09:37:31 mkunz
111 * Bugfix in ResetCounter for Pnmi.Port structure
113 * Revision 1.84 2001/03/06 09:04:55 mkunz
114 * Made some changes in instance calculation
116 * Revision 1.83 2001/02/15 09:15:32 mkunz
117 * Necessary changes for dual net mode added
119 * Revision 1.82 2001/02/07 08:24:19 mkunz
120 * -Made changes in handling of OID_SKGE_MTU
122 * Revision 1.81 2001/02/06 09:58:00 mkunz
124 * -OID_SKGE_MTU added
125 * -pnmi support for dual net mode. Interface function and macros extended
127 * Revision 1.80 2001/01/22 13:41:35 rassmann
128 * Supporting two nets on dual-port adapters.
130 * Revision 1.79 2000/12/05 14:57:40 cgoos
131 * SetStruct failed before first Link Up (link mode of virtual
132 * port "INDETERMINATED").
134 * Revision 1.78 2000/09/12 10:44:58 cgoos
135 * Fixed SK_PNMI_STORE_U32 calls with typecasted argument.
137 * Revision 1.77 2000/09/07 08:10:19 rwahl
138 * - Modified algorithm for 64bit NDIS statistic counters;
139 * returns 64bit or 32bit value depending on passed buffer
140 * size. Indicate capability for 64bit NDIS counter, if passed
141 * buffer size is zero. OID_GEN_XMIT_ERROR, OID_GEN_RCV_ERROR,
142 * and OID_GEN_RCV_NO_BUFFER handled as 64bit counter, too.
143 * - corrected OID_SKGE_RLMT_PORT_PREFERRED.
145 * Revision 1.76 2000/08/03 15:23:39 rwahl
146 * - Correction for FrameTooLong counter has to be moved to OID handling
147 * routines (instead of statistic counter routine).
148 * - Fix in XMAC Reset Event handling: Only offset counter for hardware
149 * statistic registers are updated.
151 * Revision 1.75 2000/08/01 16:46:05 rwahl
152 * - Added StatRxLongFrames counter and correction of FrameTooLong counter.
153 * - Added directive to control width (default = 32bit) of NDIS statistic
154 * counters (SK_NDIS_64BIT_CTR).
156 * Revision 1.74 2000/07/04 11:41:53 rwahl
157 * - Added volition connector type.
159 * Revision 1.73 2000/03/15 16:33:10 rwahl
160 * Fixed bug 10510; wrong reset of virtual port statistic counters.
162 * Revision 1.72 1999/12/06 16:15:53 rwahl
163 * Fixed problem of instance range for current and factory MAC address.
165 * Revision 1.71 1999/12/06 10:14:20 rwahl
166 * Fixed bug 10476; set operation for PHY_OPERATION_MODE.
168 * Revision 1.70 1999/11/22 13:33:34 cgoos
169 * Changed license header to GPL.
171 * Revision 1.69 1999/10/18 11:42:15 rwahl
172 * Added typecasts for checking event dependent param (debug only).
174 * Revision 1.68 1999/10/06 09:35:59 cgoos
175 * Added state check to PHY_READ call (hanged if called during startup).
177 * Revision 1.67 1999/09/22 09:53:20 rwahl
178 * - Read Broadcom register for updating fcs error counter (1000Base-T).
180 * Revision 1.66 1999/08/26 13:47:56 rwahl
181 * Added SK_DRIVER_SENDEVENT when queueing RLMT_CHANGE_THRES trap.
183 * Revision 1.65 1999/07/26 07:49:35 cgoos
184 * Added two typecasts to avoid compiler warnings.
186 * Revision 1.64 1999/05/20 09:24:12 cgoos
187 * Changes for 1000Base-T (sensors, Master/Slave).
189 * Revision 1.63 1999/04/13 15:11:58 mhaveman
190 * Moved include of rlmt.h to header skgepnmi.h because some macros
193 * Revision 1.62 1999/04/13 15:08:07 mhaveman
194 * Replaced again SK_RLMT_CHECK_LINK with SK_PNMI_RLMT_MODE_CHK_LINK
195 * to grant unified interface by only using the PNMI header file.
196 * SK_PNMI_RLMT_MODE_CHK_LINK is defined the same as SK_RLMT_CHECK_LINK.
198 * Revision 1.61 1999/04/13 15:02:48 mhaveman
199 * Changes caused by review:
200 * -Changed some comments
201 * -Removed redundant check for OID_SKGE_PHYS_FAC_ADDR
202 * -Optimized PRESET check.
203 * -Meaning of error SK_ADDR_DUPLICATE_ADDRESS changed. Set of same
204 * address will now not cause this error. Removed corresponding check.
206 * Revision 1.60 1999/03/23 10:41:23 mhaveman
209 * Revision 1.59 1999/02/19 08:01:28 mhaveman
210 * Fixed bug 10372 that after counter reset all ports were displayed
213 * Revision 1.58 1999/02/16 18:04:47 mhaveman
214 * Fixed problem of twisted OIDs SENSOR_WAR_TIME and SENSOR_ERR_TIME.
216 * Revision 1.56 1999/01/27 12:29:11 mhaveman
217 * SkTimerStart was called with time value in milli seconds but needs
220 * Revision 1.55 1999/01/25 15:00:38 mhaveman
221 * Added support to allow multiple ports to be active. If this feature in
222 * future will be used, the Management Data Base variables PORT_ACTIVE
223 * and PORT_PREFERED should be moved to the port specific part of RLMT.
224 * Currently they return the values of the first active physical port
225 * found. A set to the virtual port will actually change all active
226 * physical ports. A get returns the melted values of all active physical
227 * ports. If the port values differ a return value INDETERMINATED will
228 * be returned. This effects especially the CONF group.
230 * Revision 1.54 1999/01/19 10:10:22 mhaveman
231 * -Fixed bug 10354: Counter values of virtual port were wrong after port
233 * -Added check if a switch to the same port is notified.
235 * Revision 1.53 1999/01/07 09:25:21 mhaveman
236 * Forgot to initialize a variable.
238 * Revision 1.52 1999/01/05 10:34:33 mhaveman
239 * Fixed little error in RlmtChangeEstimate calculation.
241 * Revision 1.51 1999/01/05 09:59:07 mhaveman
242 * -Moved timer start to init level 2
243 * -Redesigned port switch average calculation to avoid 64bit
246 * Revision 1.50 1998/12/10 15:13:59 mhaveman
247 * -Fixed: PHYS_CUR_ADDR returned wrong addresses
248 * -Fixed: RLMT_PORT_PREFERED and RLMT_CHANGE_THRES preset returned
250 * -Fixed: TRAP buffer seemed to sometimes suddenly empty
252 * Revision 1.49 1998/12/09 16:17:07 mhaveman
253 * Fixed: Couldnot delete VPD keys on UNIX.
255 * Revision 1.48 1998/12/09 14:11:10 mhaveman
256 * -Add: Debugmessage for XMAC_RESET supressed to minimize output.
257 * -Fixed: RlmtChangeThreshold will now be initialized.
258 * -Fixed: VPD_ENTRIES_LIST extended value with unnecessary space char.
259 * -Fixed: On VPD key creation an invalid key name could be created
261 * -Some minor changes in comments and code.
263 * Revision 1.47 1998/12/08 16:00:31 mhaveman
264 * -Fixed: For RLMT_PORT_ACTIVE will now be returned a 0 if no port
266 * -Fixed: For the RLMT statistics group only the last value was
267 * returned and the rest of the buffer was filled with 0xff
268 * -Fixed: Mysteriously the preset on RLMT_MODE still returned
270 * Revision 1.46 1998/12/08 10:04:56 mhaveman
271 * -Fixed: Preset on RLMT_MODE returned always BAD_VALUE error.
272 * -Fixed: Alignment error in GetStruct
273 * -Fixed: If for Get/Preset/SetStruct the buffer size is equal or
274 * larger than SK_PNMI_MIN_STRUCT_SIZE the return value is stored
275 * to the buffer. In this case the caller should always return
276 * ok to its upper routines. Only if the buffer size is less
277 * than SK_PNMI_MIN_STRUCT_SIZE and the return value is unequal
278 * to 0, an error should be returned by the caller.
279 * -Fixed: Wrong number of instances with RLMT statistic.
280 * -Fixed: Return now SK_LMODE_STAT_UNKNOWN if the LinkModeStatus is 0.
282 * Revision 1.45 1998/12/03 17:17:24 mhaveman
283 * -Removed for VPD create action the buffer size limitation to 4 bytes.
284 * -Pass now physical/active physical port to ADDR for CUR_ADDR set
286 * Revision 1.44 1998/12/03 15:14:35 mhaveman
287 * Another change to Vpd instance evaluation.
289 * Revision 1.43 1998/12/03 14:18:10 mhaveman
290 * -Fixed problem in PnmiSetStruct. It was impossible to set any value.
291 * -Removed VPD key evaluation for VPD_FREE_BYTES and VPD_ACTION.
293 * Revision 1.42 1998/12/03 11:31:47 mhaveman
294 * Inserted cast to satisfy lint.
296 * Revision 1.41 1998/12/03 11:28:16 mhaveman
297 * Removed SK_PNMI_CHECKPTR
299 * Revision 1.40 1998/12/03 11:19:07 mhaveman
301 * -A set to virtual port will now be ignored. A set with broadcast
302 * address to any port will be ignored.
303 * -GetStruct function made VPD instance calculation wrong.
304 * -Prefered port returned -1 instead of 0.
306 * Revision 1.39 1998/11/26 15:30:29 mhaveman
307 * Added sense mode to link mode.
309 * Revision 1.38 1998/11/23 15:34:00 mhaveman
310 * -Fixed bug for RX counters. On an RX overflow interrupt the high
311 * words of all RX counters were incremented.
312 * -SET operations on FLOWCTRL_MODE and LINK_MODE accept now the
313 * value 0, which has no effect. It is usefull for multiple instance
316 * Revision 1.37 1998/11/20 08:02:04 mhaveman
317 * -Fixed: Ports were compared with MAX_SENSORS
318 * -Fixed: Crash in GetTrapEntry with MEMSET macro
319 * -Fixed: Conversions between physical, logical port index and instance
321 * Revision 1.36 1998/11/16 07:48:53 mhaveman
322 * Casted SK_DRIVER_SENDEVENT with (void) to eleminate compiler warnings
325 * Revision 1.35 1998/11/16 07:45:34 mhaveman
326 * SkAddrOverride now returns value and will be checked.
328 * Revision 1.34 1998/11/10 13:40:37 mhaveman
329 * Needed to change interface, because NT driver needs a return value
330 * of needed buffer space on TOO_SHORT errors. Therefore all
331 * SkPnmiGet/Preset/Set functions now have a pointer to the length
332 * parameter, where the needed space on error is returned.
334 * Revision 1.33 1998/11/03 13:52:46 mhaveman
335 * Made file lint conform.
337 * Revision 1.32 1998/11/03 13:19:07 mhaveman
338 * The events SK_HWEV_SET_LMODE and SK_HWEV_SET_FLOWMODE pass now in
339 * Para32[0] the physical MAC index and in Para32[1] the new mode.
341 * Revision 1.31 1998/11/03 12:30:40 gklug
342 * fix: compiler warning memset
344 * Revision 1.30 1998/11/03 12:04:46 mhaveman
345 * Fixed problem in SENSOR_VALUE, which wrote beyond the buffer end
346 * Fixed alignment problem with CHIPSET.
348 * Revision 1.29 1998/11/02 11:23:54 mhaveman
349 * Corrected SK_ERROR_LOG to SK_ERR_LOG. Sorry.
351 * Revision 1.28 1998/11/02 10:47:16 mhaveman
352 * Added syslog messages for internal errors.
354 * Revision 1.27 1998/10/30 15:48:06 mhaveman
355 * Fixed problems after simulation of SK_PNMI_EVT_CHG_EST_TIMER and
356 * RlmtChangeThreshold calculation.
358 * Revision 1.26 1998/10/29 15:36:55 mhaveman
359 * -Fixed bug in trap buffer handling.
360 * -OID_SKGE_DRIVER_DESCR, OID_SKGE_DRIVER_VERSION, OID_SKGE_HW_DESCR,
361 * OID_SKGE_HW_VERSION, OID_SKGE_VPD_ENTRIES_LIST, OID_SKGE_VPD_KEY,
362 * OID_SKGE_VPD_VALUE, and OID_SKGE_SENSOR_DESCR return values with
363 * a leading octet before each string storing the string length.
364 * -Perform a RlmtUpdate during SK_PNMI_EVT_XMAC_RESET to minimize
365 * RlmtUpdate calls in GetStatVal.
366 * -Inserted SK_PNMI_CHECKFLAGS macro increase readability.
368 * Revision 1.25 1998/10/29 08:50:36 mhaveman
369 * Fixed problems after second event simulation.
371 * Revision 1.24 1998/10/28 08:44:37 mhaveman
372 * -Fixed alignment problem
373 * -Fixed problems during event simulation
374 * -Fixed sequence of error return code (INSTANCE -> ACCESS -> SHORT)
375 * -Changed type of parameter Instance back to SK_U32 because of VPD
376 * -Updated new VPD function calls
378 * Revision 1.23 1998/10/23 10:16:37 mhaveman
379 * Fixed bugs after buffer test simulation.
381 * Revision 1.22 1998/10/21 13:23:52 mhaveman
382 * -Call syntax of SkOsGetTime() changed to SkOsGetTime(pAc).
383 * -Changed calculation of hundrets of seconds.
385 * Revision 1.20 1998/10/20 07:30:45 mhaveman
386 * Made type changes to unsigned integer where possible.
388 * Revision 1.19 1998/10/19 10:51:30 mhaveman
389 * -Made Bug fixes after simulation run
390 * -Renamed RlmtMAC... to RlmtPort...
391 * -Marked workarounds with Errata comments
393 * Revision 1.18 1998/10/14 07:50:08 mhaveman
394 * -For OID_SKGE_LINK_STATUS the link down detection has moved from RLMT
396 * -Provided all MEMCPY/MEMSET macros with (char *) pointers, because
397 * Solaris throwed warnings when mapping to bcopy/bset.
399 * Revision 1.17 1998/10/13 07:42:01 mhaveman
400 * -Added OIDs OID_SKGE_TRAP_NUMBER and OID_SKGE_ALL_DATA
401 * -Removed old cvs history entries
402 * -Renamed MacNumber to PortNumber
404 * Revision 1.16 1998/10/07 10:52:49 mhaveman
405 * -Inserted handling of some OID_GEN_ Ids for windows
406 * -Fixed problem with 803.2 statistic.
408 * Revision 1.15 1998/10/01 09:16:29 mhaveman
409 * Added Debug messages for function call and UpdateFlag tracing.
411 * Revision 1.14 1998/09/30 13:39:09 mhaveman
412 * -Reduced namings of 'MAC' by replacing them with 'PORT'.
413 * -Completed counting of OID_SKGE_RX_HW_ERROR_CTS,
414 * OID_SKGE_TX_HW_ERROR_CTS,
415 * OID_SKGE_IN_ERRORS_CTS, and OID_SKGE_OUT_ERROR_CTS.
416 * -SET check for RlmtMode
418 * Revision 1.13 1998/09/28 13:13:08 mhaveman
419 * Hide strcmp, strlen, and strncpy behind macros SK_STRCMP, SK_STRLEN,
420 * and SK_STRNCPY. (Same reasons as for mem.. and MEM..)
422 * Revision 1.12 1998/09/16 08:18:36 cgoos
423 * Fix: XM_INxx and XM_OUTxx called with different parameter order:
424 * sometimes IoC,Mac,... sometimes Mac,IoC,... Now always first variant.
425 * Fix: inserted "Pnmi." into some pAC->pDriverDescription / Version.
426 * Change: memset, memcpy to makros SK_MEMSET, SK_MEMCPY
428 * Revision 1.11 1998/09/04 17:01:45 mhaveman
429 * Added SyncCounter as macro and OID_SKGE_.._NO_DESCR_CTS to
430 * OID_SKGE_RX_NO_BUF_CTS.
432 * Revision 1.10 1998/09/04 14:35:35 mhaveman
433 * Added macro counters, that are counted by driver.
435 ****************************************************************************/
440 static const char SysKonnectFileId[] =
444 #include "h/skdrv1st.h"
445 #include "h/sktypes.h"
446 #include "h/xmac_ii.h"
447 #include "h/skdebug.h"
448 #include "h/skqueue.h"
449 #include "h/skgepnmi.h"
450 #include "h/skgesirq.h"
451 #include "h/skcsum.h"
453 #include "h/skgehw.h"
454 #include "h/skgeinit.h"
455 #include "h/skdrv2nd.h"
456 #include "h/skgepnm2.h"
458 #include "h/skgepmgt.h"
460 /* defines *******************************************************************/
463 #define PNMI_STATIC static
469 * Public Function prototypes
471 int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level);
472 int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
473 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
474 int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
475 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
476 int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
477 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
478 int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
479 unsigned int *pLen, SK_U32 NetIndex);
480 int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
481 unsigned int *pLen, SK_U32 NetIndex);
482 int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
483 unsigned int *pLen, SK_U32 NetIndex);
484 int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
488 * Private Function prototypes
491 PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
493 PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
495 PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac);
496 PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
497 PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
498 unsigned int PhysPortIndex, unsigned int StatIndex);
499 PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
500 unsigned int StatIndex, SK_U32 NetIndex);
501 PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
502 PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
503 unsigned int *pEntries);
504 PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr,
505 unsigned int KeyArrLen, unsigned int *pKeyNo);
506 PNMI_STATIC int LookupId(SK_U32 Id);
507 PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
508 unsigned int LastMac);
509 PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
510 unsigned int *pLen, SK_U32 NetIndex);
511 PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id,
512 char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
513 PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
514 PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
515 unsigned int PortIndex);
516 PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
517 unsigned int SensorIndex);
518 PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
519 PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
520 PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
521 PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
522 PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
523 PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
524 unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
525 PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
528 * Table to correlate OID with handler function and index to
529 * hardware register stored in StatAddress if applicable.
533 /* global variables **********************************************************/
536 * Overflow status register bit table and corresponding counter
537 * dependent on MAC type - the number relates to the size of overflow
538 * mask returned by the pFnMacOverflow function
540 PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = {
541 /* Bit0 */ { SK_PNMI_HTX, SK_PNMI_HTX_UNICAST},
542 /* Bit1 */ { SK_PNMI_HTX_OCTETHIGH, SK_PNMI_HTX_BROADCAST},
543 /* Bit2 */ { SK_PNMI_HTX_OCTETLOW, SK_PNMI_HTX_PMACC},
544 /* Bit3 */ { SK_PNMI_HTX_BROADCAST, SK_PNMI_HTX_MULTICAST},
545 /* Bit4 */ { SK_PNMI_HTX_MULTICAST, SK_PNMI_HTX_OCTETLOW},
546 /* Bit5 */ { SK_PNMI_HTX_UNICAST, SK_PNMI_HTX_OCTETHIGH},
547 /* Bit6 */ { SK_PNMI_HTX_LONGFRAMES, SK_PNMI_HTX_64},
548 /* Bit7 */ { SK_PNMI_HTX_BURST, SK_PNMI_HTX_127},
549 /* Bit8 */ { SK_PNMI_HTX_PMACC, SK_PNMI_HTX_255},
550 /* Bit9 */ { SK_PNMI_HTX_MACC, SK_PNMI_HTX_511},
551 /* Bit10 */ { SK_PNMI_HTX_SINGLE_COL, SK_PNMI_HTX_1023},
552 /* Bit11 */ { SK_PNMI_HTX_MULTI_COL, SK_PNMI_HTX_MAX},
553 /* Bit12 */ { SK_PNMI_HTX_EXCESS_COL, SK_PNMI_HTX_LONGFRAMES},
554 /* Bit13 */ { SK_PNMI_HTX_LATE_COL, SK_PNMI_HTX_RESERVED},
555 /* Bit14 */ { SK_PNMI_HTX_DEFFERAL, SK_PNMI_HTX_COL},
556 /* Bit15 */ { SK_PNMI_HTX_EXCESS_DEF, SK_PNMI_HTX_LATE_COL},
557 /* Bit16 */ { SK_PNMI_HTX_UNDERRUN, SK_PNMI_HTX_EXCESS_COL},
558 /* Bit17 */ { SK_PNMI_HTX_CARRIER, SK_PNMI_HTX_MULTI_COL},
559 /* Bit18 */ { SK_PNMI_HTX_UTILUNDER, SK_PNMI_HTX_SINGLE_COL},
560 /* Bit19 */ { SK_PNMI_HTX_UTILOVER, SK_PNMI_HTX_UNDERRUN},
561 /* Bit20 */ { SK_PNMI_HTX_64, SK_PNMI_HTX_RESERVED},
562 /* Bit21 */ { SK_PNMI_HTX_127, SK_PNMI_HTX_RESERVED},
563 /* Bit22 */ { SK_PNMI_HTX_255, SK_PNMI_HTX_RESERVED},
564 /* Bit23 */ { SK_PNMI_HTX_511, SK_PNMI_HTX_RESERVED},
565 /* Bit24 */ { SK_PNMI_HTX_1023, SK_PNMI_HTX_RESERVED},
566 /* Bit25 */ { SK_PNMI_HTX_MAX, SK_PNMI_HTX_RESERVED},
567 /* Bit26 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
568 /* Bit27 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
569 /* Bit28 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
570 /* Bit29 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
571 /* Bit30 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
572 /* Bit31 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
573 /* Bit32 */ { SK_PNMI_HRX, SK_PNMI_HRX_UNICAST},
574 /* Bit33 */ { SK_PNMI_HRX_OCTETHIGH, SK_PNMI_HRX_BROADCAST},
575 /* Bit34 */ { SK_PNMI_HRX_OCTETLOW, SK_PNMI_HRX_PMACC},
576 /* Bit35 */ { SK_PNMI_HRX_BROADCAST, SK_PNMI_HRX_MULTICAST},
577 /* Bit36 */ { SK_PNMI_HRX_MULTICAST, SK_PNMI_HRX_FCS},
578 /* Bit37 */ { SK_PNMI_HRX_UNICAST, SK_PNMI_HRX_RESERVED},
579 /* Bit38 */ { SK_PNMI_HRX_PMACC, SK_PNMI_HRX_OCTETLOW},
580 /* Bit39 */ { SK_PNMI_HRX_MACC, SK_PNMI_HRX_OCTETHIGH},
581 /* Bit40 */ { SK_PNMI_HRX_PMACC_ERR, SK_PNMI_HRX_BADOCTETLOW},
582 /* Bit41 */ { SK_PNMI_HRX_MACC_UNKWN, SK_PNMI_HRX_BADOCTETHIGH},
583 /* Bit42 */ { SK_PNMI_HRX_BURST, SK_PNMI_HRX_UNDERSIZE},
584 /* Bit43 */ { SK_PNMI_HRX_MISSED, SK_PNMI_HRX_RUNT},
585 /* Bit44 */ { SK_PNMI_HRX_FRAMING, SK_PNMI_HRX_64},
586 /* Bit45 */ { SK_PNMI_HRX_OVERFLOW, SK_PNMI_HRX_127},
587 /* Bit46 */ { SK_PNMI_HRX_JABBER, SK_PNMI_HRX_255},
588 /* Bit47 */ { SK_PNMI_HRX_CARRIER, SK_PNMI_HRX_511},
589 /* Bit48 */ { SK_PNMI_HRX_IRLENGTH, SK_PNMI_HRX_1023},
590 /* Bit49 */ { SK_PNMI_HRX_SYMBOL, SK_PNMI_HRX_MAX},
591 /* Bit50 */ { SK_PNMI_HRX_SHORTS, SK_PNMI_HRX_LONGFRAMES},
592 /* Bit51 */ { SK_PNMI_HRX_RUNT, SK_PNMI_HRX_TOO_LONG},
593 /* Bit52 */ { SK_PNMI_HRX_TOO_LONG, SK_PNMI_HRX_JABBER},
594 /* Bit53 */ { SK_PNMI_HRX_FCS, SK_PNMI_HRX_RESERVED},
595 /* Bit54 */ { SK_PNMI_HRX_RESERVED, SK_PNMI_HRX_OVERFLOW},
596 /* Bit55 */ { SK_PNMI_HRX_CEXT, SK_PNMI_HRX_RESERVED},
597 /* Bit56 */ { SK_PNMI_HRX_UTILUNDER, SK_PNMI_HRX_RESERVED},
598 /* Bit57 */ { SK_PNMI_HRX_UTILOVER, SK_PNMI_HRX_RESERVED},
599 /* Bit58 */ { SK_PNMI_HRX_64, SK_PNMI_HRX_RESERVED},
600 /* Bit59 */ { SK_PNMI_HRX_127, SK_PNMI_HRX_RESERVED},
601 /* Bit60 */ { SK_PNMI_HRX_255, SK_PNMI_HRX_RESERVED},
602 /* Bit61 */ { SK_PNMI_HRX_511, SK_PNMI_HRX_RESERVED},
603 /* Bit62 */ { SK_PNMI_HRX_1023, SK_PNMI_HRX_RESERVED},
604 /* Bit63 */ { SK_PNMI_HRX_MAX, SK_PNMI_HRX_RESERVED}
608 * Table for hardware register saving on resets and port switches
610 PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = {
612 {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}},
613 /* SK_PNMI_HTX_OCTETHIGH */
614 {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}},
615 /* SK_PNMI_HTX_OCTETLOW */
616 {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}},
617 /* SK_PNMI_HTX_BROADCAST */
618 {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}},
619 /* SK_PNMI_HTX_MULTICAST */
620 {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}},
621 /* SK_PNMI_HTX_UNICAST */
622 {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}},
623 /* SK_PNMI_HTX_BURST */
624 {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}},
625 /* SK_PNMI_HTX_PMACC */
626 {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}},
627 /* SK_PNMI_HTX_MACC */
628 {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
629 /* SK_PNMI_HTX_COL */
630 {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}},
631 /* SK_PNMI_HTX_SINGLE_COL */
632 {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}},
633 /* SK_PNMI_HTX_MULTI_COL */
634 {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}},
635 /* SK_PNMI_HTX_EXCESS_COL */
636 {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}},
637 /* SK_PNMI_HTX_LATE_COL */
638 {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}},
639 /* SK_PNMI_HTX_DEFFERAL */
640 {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}},
641 /* SK_PNMI_HTX_EXCESS_DEF */
642 {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}},
643 /* SK_PNMI_HTX_UNDERRUN */
644 {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}},
645 /* SK_PNMI_HTX_CARRIER */
646 {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}},
647 /* SK_PNMI_HTX_UTILUNDER */
648 {{0, SK_FALSE}, {0, SK_FALSE}},
649 /* SK_PNMI_HTX_UTILOVER */
650 {{0, SK_FALSE}, {0, SK_FALSE}},
652 {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}},
653 /* SK_PNMI_HTX_127 */
654 {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}},
655 /* SK_PNMI_HTX_255 */
656 {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}},
657 /* SK_PNMI_HTX_511 */
658 {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}},
659 /* SK_PNMI_HTX_1023 */
660 {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}},
661 /* SK_PNMI_HTX_MAX */
662 {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}},
663 /* SK_PNMI_HTX_LONGFRAMES */
664 {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}},
665 /* SK_PNMI_HTX_SYNC */
666 {{0, SK_FALSE}, {0, SK_FALSE}},
667 /* SK_PNMI_HTX_SYNC_OCTET */
668 {{0, SK_FALSE}, {0, SK_FALSE}},
669 /* SK_PNMI_HTX_RESERVED */
670 {{0, SK_FALSE}, {0, SK_FALSE}},
672 {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}},
673 /* SK_PNMI_HRX_OCTETHIGH */
674 {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}},
675 /* SK_PNMI_HRX_OCTETLOW */
676 {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}},
677 /* SK_PNMI_HRX_BADOCTETHIGH */
678 {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}},
679 /* SK_PNMI_HRX_BADOCTETLOW */
680 {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}},
681 /* SK_PNMI_HRX_BROADCAST */
682 {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}},
683 /* SK_PNMI_HRX_MULTICAST */
684 {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}},
685 /* SK_PNMI_HRX_UNICAST */
686 {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}},
687 /* SK_PNMI_HRX_PMACC */
688 {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}},
689 /* SK_PNMI_HRX_MACC */
690 {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
691 /* SK_PNMI_HRX_PMACC_ERR */
692 {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}},
693 /* SK_PNMI_HRX_MACC_UNKWN */
694 {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}},
695 /* SK_PNMI_HRX_BURST */
696 {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}},
697 /* SK_PNMI_HRX_MISSED */
698 {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}},
699 /* SK_PNMI_HRX_FRAMING */
700 {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}},
701 /* SK_PNMI_HRX_UNDERSIZE */
702 {{0, SK_FALSE},{GM_RXF_SHT, SK_TRUE}},
703 /* SK_PNMI_HRX_OVERFLOW */
704 {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}},
705 /* SK_PNMI_HRX_JABBER */
706 {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}},
707 /* SK_PNMI_HRX_CARRIER */
708 {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}},
709 /* SK_PNMI_HRX_IRLENGTH */
710 {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}},
711 /* SK_PNMI_HRX_SYMBOL */
712 {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}},
713 /* SK_PNMI_HRX_SHORTS */
714 {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}},
715 /* SK_PNMI_HRX_RUNT */
716 {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}},
717 /* SK_PNMI_HRX_TOO_LONG */
718 {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}},
719 /* SK_PNMI_HRX_FCS */
720 {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}},
721 /* SK_PNMI_HRX_CEXT */
722 {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}},
723 /* SK_PNMI_HRX_UTILUNDER */
724 {{0, SK_FALSE}, {0, SK_FALSE}},
725 /* SK_PNMI_HRX_UTILOVER */
726 {{0, SK_FALSE}, {0, SK_FALSE}},
728 {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}},
729 /* SK_PNMI_HRX_127 */
730 {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}},
731 /* SK_PNMI_HRX_255 */
732 {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}},
733 /* SK_PNMI_HRX_511 */
734 {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}},
735 /* SK_PNMI_HRX_1023 */
736 {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}},
737 /* SK_PNMI_HRX_MAX */
738 {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}},
739 /* SK_PNMI_HRX_LONGFRAMES */
740 {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}},
741 /* SK_PNMI_HRX_RESERVED */
742 {{0, SK_FALSE}, {0, SK_FALSE}}
746 /*****************************************************************************
752 /*****************************************************************************
754 * SkPnmiInit - Init function of PNMI
757 * SK_INIT_DATA: Initialises the data structures
758 * SK_INIT_IO: Resets the XMAC statistics, determines the device and
760 * SK_INIT_RUN: Starts a timer event for port switch per hour
767 SK_AC *pAC, /* Pointer to adapter context */
768 SK_IOC IoC, /* IO context handle */
769 int Level) /* Initialization level */
771 unsigned int PortMax; /* Number of ports */
772 unsigned int PortIndex; /* Current port index in loop */
773 SK_U16 Val16; /* Multiple purpose 16 bit variable */
774 SK_U8 Val8; /* Mulitple purpose 8 bit variable */
775 SK_EVPARA EventParam; /* Event struct for timer event */
777 SK_PNMI_VCT *pVctBackupData;
780 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
781 ("PNMI: SkPnmiInit: Called, level=%d\n", Level));
786 SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
787 pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
788 pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
789 pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
790 for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
792 pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
793 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
797 if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) {
799 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG);
801 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
802 ("CounterOffset struct size (%d) differs from"
803 "SK_PNMI_MAX_IDX (%d)\n",
804 SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
808 if (SK_PNMI_MAX_IDX !=
809 (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) {
811 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG);
813 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
814 ("StatAddr table size (%d) differs from "
815 "SK_PNMI_MAX_IDX (%d)\n",
817 (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)),
821 #endif /* SK_PNMI_CHECK */
828 PortMax = pAC->GIni.GIMacsFound;
830 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
832 pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
835 /* Initialize DSP variables for Vct() to 0xff => Never written! */
836 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
837 pPrt = &pAC->GIni.GP[PortIndex];
838 pPrt->PCableLen =0xff;
839 pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
840 pVctBackupData->PCableLen = 0xff;
846 SK_IN16(IoC, B0_CTST, &Val16);
847 if ((Val16 & CS_BUS_CLOCK) == 0) {
849 pAC->Pnmi.PciBusSpeed = 33;
852 pAC->Pnmi.PciBusSpeed = 66;
858 SK_IN16(IoC, B0_CTST, &Val16);
859 if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
861 pAC->Pnmi.PciBusWidth = 32;
864 pAC->Pnmi.PciBusWidth = 64;
870 switch (pAC->GIni.GIChipId) {
871 case CHIP_ID_GENESIS:
872 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
876 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
884 * Get PMD and DeviceType
886 SK_IN8(IoC, B2_PMD_TYP, &Val8);
890 if (pAC->GIni.GIMacsFound > 1) {
892 pAC->Pnmi.DeviceType = 0x00020002;
895 pAC->Pnmi.DeviceType = 0x00020001;
901 if (pAC->GIni.GIMacsFound > 1) {
903 pAC->Pnmi.DeviceType = 0x00020004;
906 pAC->Pnmi.DeviceType = 0x00020003;
912 if (pAC->GIni.GIMacsFound > 1) {
914 pAC->Pnmi.DeviceType = 0x00020006;
917 pAC->Pnmi.DeviceType = 0x00020005;
923 if (pAC->GIni.GIMacsFound > 1) {
925 pAC->Pnmi.DeviceType = 0x00020008;
928 pAC->Pnmi.DeviceType = 0x00020007;
934 pAC->Pnmi.DeviceType = 0;
941 SK_IN8(IoC, B2_CONN_TYP, &Val8);
944 pAC->Pnmi.Connector = 2;
948 pAC->Pnmi.Connector = 3;
952 pAC->Pnmi.Connector = 4;
956 pAC->Pnmi.Connector = 5;
960 pAC->Pnmi.Connector = 6;
964 pAC->Pnmi.Connector = 1;
971 * Start timer for RLMT change counter
973 SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
974 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
975 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
980 break; /* Nothing todo */
986 /*****************************************************************************
988 * SkPnmiGetVar - Retrieves the value of a single OID
991 * Calls a general sub-function for all this stuff. If the instance
992 * -1 is passed, the values of all instances are returned in an
996 * SK_PNMI_ERR_OK The request was successfully performed
997 * SK_PNMI_ERR_GENERAL A general severe internal error occured
998 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
1000 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
1001 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1002 * exist (e.g. port instance 3 on a two port
1006 SK_AC *pAC, /* Pointer to adapter context */
1007 SK_IOC IoC, /* IO context handle */
1008 SK_U32 Id, /* Object ID that is to be processed */
1009 void *pBuf, /* Buffer to which to mgmt data will be retrieved */
1010 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
1011 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
1012 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1014 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1015 ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
1016 Id, *pLen, Instance, NetIndex));
1018 return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
1019 Instance, NetIndex));
1022 /*****************************************************************************
1024 * SkPnmiPreSetVar - Presets the value of a single OID
1027 * Calls a general sub-function for all this stuff. The preset does
1028 * the same as a set, but returns just before finally setting the
1029 * new value. This is usefull to check if a set might be successfull.
1030 * If as instance a -1 is passed, an array of values is supposed and
1031 * all instance of the OID will be set.
1034 * SK_PNMI_ERR_OK The request was successfully performed.
1035 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1036 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1037 * the correct data (e.g. a 32bit value is
1038 * needed, but a 16 bit value was passed).
1039 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1041 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
1042 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
1043 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1044 * exist (e.g. port instance 3 on a two port
1047 int SkPnmiPreSetVar(
1048 SK_AC *pAC, /* Pointer to adapter context */
1049 SK_IOC IoC, /* IO context handle */
1050 SK_U32 Id, /* Object ID that is to be processed */
1051 void *pBuf, /* Buffer which stores the mgmt data to be set */
1052 unsigned int *pLen, /* Total length of mgmt data */
1053 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
1054 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1056 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1057 ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
1058 Id, *pLen, Instance, NetIndex));
1061 return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
1062 Instance, NetIndex));
1065 /*****************************************************************************
1067 * SkPnmiSetVar - Sets the value of a single OID
1070 * Calls a general sub-function for all this stuff. The preset does
1071 * the same as a set, but returns just before finally setting the
1072 * new value. This is usefull to check if a set might be successfull.
1073 * If as instance a -1 is passed, an array of values is supposed and
1074 * all instance of the OID will be set.
1077 * SK_PNMI_ERR_OK The request was successfully performed.
1078 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1079 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1080 * the correct data (e.g. a 32bit value is
1081 * needed, but a 16 bit value was passed).
1082 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1084 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
1085 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
1086 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1087 * exist (e.g. port instance 3 on a two port
1091 SK_AC *pAC, /* Pointer to adapter context */
1092 SK_IOC IoC, /* IO context handle */
1093 SK_U32 Id, /* Object ID that is to be processed */
1094 void *pBuf, /* Buffer which stores the mgmt data to be set */
1095 unsigned int *pLen, /* Total length of mgmt data */
1096 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
1097 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1099 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1100 ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
1101 Id, *pLen, Instance, NetIndex));
1103 return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
1104 Instance, NetIndex));
1107 /*****************************************************************************
1109 * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA
1112 * Runs through the IdTable, queries the single OIDs and stores the
1113 * returned data into the management database structure
1114 * SK_PNMI_STRUCT_DATA. The offset of the OID in the structure
1115 * is stored in the IdTable. The return value of the function will also
1116 * be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
1117 * minimum size of SK_PNMI_MIN_STRUCT_SIZE.
1120 * SK_PNMI_ERR_OK The request was successfully performed
1121 * SK_PNMI_ERR_GENERAL A general severe internal error occured
1122 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
1124 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
1126 int SkPnmiGetStruct(
1127 SK_AC *pAC, /* Pointer to adapter context */
1128 SK_IOC IoC, /* IO context handle */
1129 void *pBuf, /* Buffer which will store the retrieved data */
1130 unsigned int *pLen, /* Length of buffer */
1131 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1134 unsigned int TableIndex;
1135 unsigned int DstOffset;
1136 unsigned int InstanceNo;
1137 unsigned int InstanceCnt;
1139 unsigned int TmpLen;
1140 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
1143 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1144 ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
1147 if (*pLen < SK_PNMI_STRUCT_SIZE) {
1149 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
1151 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
1155 *pLen = SK_PNMI_STRUCT_SIZE;
1156 return (SK_PNMI_ERR_TOO_SHORT);
1162 if (NetIndex >= pAC->Rlmt.NumNets) {
1163 return (SK_PNMI_ERR_UNKNOWN_NET);
1166 /* Update statistic */
1167 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
1169 if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
1172 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1173 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1177 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
1179 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1180 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1184 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
1186 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1187 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1192 * Increment semaphores to indicate that an update was
1195 pAC->Pnmi.MacUpdatedFlag ++;
1196 pAC->Pnmi.RlmtUpdatedFlag ++;
1197 pAC->Pnmi.SirqUpdatedFlag ++;
1199 /* Get vpd keys for instance calculation */
1200 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
1201 if (Ret != SK_PNMI_ERR_OK) {
1203 pAC->Pnmi.MacUpdatedFlag --;
1204 pAC->Pnmi.RlmtUpdatedFlag --;
1205 pAC->Pnmi.SirqUpdatedFlag --;
1207 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
1208 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1209 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1210 return (SK_PNMI_ERR_GENERAL);
1213 /* Retrieve values */
1214 SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
1215 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
1217 InstanceNo = IdTable[TableIndex].InstanceNo;
1218 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
1221 DstOffset = IdTable[TableIndex].Offset +
1223 IdTable[TableIndex].StructSize;
1226 * For the VPD the instance is not an index number
1227 * but the key itself. Determin with the instance
1228 * counter the VPD key to be used.
1230 if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
1231 IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
1232 IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
1233 IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
1235 SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
1238 Instance = (SK_U32)InstanceCnt;
1241 TmpLen = *pLen - DstOffset;
1242 Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
1243 IdTable[TableIndex].Id, (char *)pBuf +
1244 DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
1247 * An unknown instance error means that we reached
1248 * the last instance of that variable. Proceed with
1249 * the next OID in the table and ignore the return
1252 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
1257 if (Ret != SK_PNMI_ERR_OK) {
1259 pAC->Pnmi.MacUpdatedFlag --;
1260 pAC->Pnmi.RlmtUpdatedFlag --;
1261 pAC->Pnmi.SirqUpdatedFlag --;
1263 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
1264 SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
1265 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1271 pAC->Pnmi.MacUpdatedFlag --;
1272 pAC->Pnmi.RlmtUpdatedFlag --;
1273 pAC->Pnmi.SirqUpdatedFlag --;
1275 *pLen = SK_PNMI_STRUCT_SIZE;
1276 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
1277 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
1278 return (SK_PNMI_ERR_OK);
1281 /*****************************************************************************
1283 * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
1286 * Calls a general sub-function for all this set stuff. The preset does
1287 * the same as a set, but returns just before finally setting the
1288 * new value. This is usefull to check if a set might be successfull.
1289 * The sub-function runs through the IdTable, checks which OIDs are able
1290 * to set, and calls the handler function of the OID to perform the
1291 * preset. The return value of the function will also be stored in
1292 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
1293 * SK_PNMI_MIN_STRUCT_SIZE.
1296 * SK_PNMI_ERR_OK The request was successfully performed.
1297 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1298 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1299 * the correct data (e.g. a 32bit value is
1300 * needed, but a 16 bit value was passed).
1301 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1304 int SkPnmiPreSetStruct(
1305 SK_AC *pAC, /* Pointer to adapter context */
1306 SK_IOC IoC, /* IO context handle */
1307 void *pBuf, /* Buffer which contains the data to be set */
1308 unsigned int *pLen, /* Length of buffer */
1309 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1311 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1312 ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
1315 return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf,
1319 /*****************************************************************************
1321 * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA
1324 * Calls a general sub-function for all this set stuff. The return value
1325 * of the function will also be stored in SK_PNMI_STRUCT_DATA if the
1326 * passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE.
1327 * The sub-function runs through the IdTable, checks which OIDs are able
1328 * to set, and calls the handler function of the OID to perform the
1329 * set. The return value of the function will also be stored in
1330 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
1331 * SK_PNMI_MIN_STRUCT_SIZE.
1334 * SK_PNMI_ERR_OK The request was successfully performed.
1335 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1336 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1337 * the correct data (e.g. a 32bit value is
1338 * needed, but a 16 bit value was passed).
1339 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1342 int SkPnmiSetStruct(
1343 SK_AC *pAC, /* Pointer to adapter context */
1344 SK_IOC IoC, /* IO context handle */
1345 void *pBuf, /* Buffer which contains the data to be set */
1346 unsigned int *pLen, /* Length of buffer */
1347 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1349 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1350 ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
1353 return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf,
1357 /*****************************************************************************
1359 * SkPnmiEvent - Event handler
1362 * Handles the following events:
1363 * SK_PNMI_EVT_SIRQ_OVERFLOW When a hardware counter overflows an
1364 * interrupt will be generated which is
1365 * first handled by SIRQ which generates a
1366 * this event. The event increments the
1367 * upper 32 bit of the 64 bit counter.
1368 * SK_PNMI_EVT_SEN_XXX The event is generated by the I2C module
1369 * when a sensor reports a warning or
1370 * error. The event will store a trap
1371 * message in the trap buffer.
1372 * SK_PNMI_EVT_CHG_EST_TIMER The timer event was initiated by this
1373 * module and is used to calculate the
1374 * port switches per hour.
1375 * SK_PNMI_EVT_CLEAR_COUNTER The event clears all counters and
1377 * SK_PNMI_EVT_XMAC_RESET The event is generated by the driver
1378 * before a hard reset of the XMAC is
1379 * performed. All counters will be saved
1380 * and added to the hardware counter
1381 * values after reset to grant continuous
1383 * SK_PNMI_EVT_RLMT_PORT_UP Generated by RLMT to notify that a port
1384 * went logically up. A trap message will
1385 * be stored to the trap buffer.
1386 * SK_PNMI_EVT_RLMT_PORT_DOWN Generated by RLMT to notify that a port
1387 * went logically down. A trap message will
1388 * be stored to the trap buffer.
1389 * SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
1390 * spanning tree root bridges were
1391 * detected. A trap message will be stored
1392 * to the trap buffer.
1393 * SK_PNMI_EVT_RLMT_ACTIVE_DOWN Notifies PNMI that an active port went
1394 * down. PNMI will not further add the
1395 * statistic values to the virtual port.
1396 * SK_PNMI_EVT_RLMT_ACTIVE_UP Notifies PNMI that a port went up and
1397 * is now an active port. PNMI will now
1398 * add the statistic data of this port to
1400 * SK_PNMI_EVT_RLMT_SET_NETS Notifies PNMI about the net mode. The first Parameter
1401 * contains the number of nets. 1 means single net, 2 means
1402 * dual net. The second Parameter is -1
1408 SK_AC *pAC, /* Pointer to adapter context */
1409 SK_IOC IoC, /* IO context handle */
1410 SK_U32 Event, /* Event-Id */
1411 SK_EVPARA Param) /* Event dependent parameter */
1413 unsigned int PhysPortIndex;
1414 unsigned int MaxNetNumber;
1418 SK_U64 OverflowStatus;
1424 SK_EVPARA EventParam;
1428 SK_PNMI_ESTIMATE *pEst;
1431 SK_PNMI_VCT *pVctBackupData;
1438 if (Event != SK_PNMI_EVT_XMAC_RESET) {
1440 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1441 ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n",
1442 (unsigned int)Event, (unsigned int)Param.Para64));
1445 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call");
1447 MacType = pAC->GIni.GIMacType;
1451 case SK_PNMI_EVT_SIRQ_OVERFLOW:
1452 PhysPortIndex = (int)Param.Para32[0];
1453 MacStatus = (SK_U16)Param.Para32[1];
1455 if (PhysPortIndex >= SK_MAX_MACS) {
1457 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1458 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter"
1459 " wrong, PhysPortIndex=0x%x\n",
1467 * Check which source caused an overflow interrupt.
1469 if ((pAC->GIni.GIFunc.pFnMacOverflow(
1470 pAC, IoC, PhysPortIndex, MacStatus, &OverflowStatus) != 0) ||
1471 (OverflowStatus == 0)) {
1473 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1478 * Check the overflow status register and increment
1479 * the upper dword of corresponding counter.
1481 for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8;
1484 Mask = (SK_U64)1 << CounterIndex;
1485 if ((OverflowStatus & Mask) == 0) {
1490 switch (StatOvrflwBit[CounterIndex][MacType]) {
1492 case SK_PNMI_HTX_UTILUNDER:
1493 case SK_PNMI_HTX_UTILOVER:
1494 XM_IN16(IoC, PhysPortIndex, XM_TX_CMD,
1496 Register |= XM_TX_SAM_LINE;
1497 XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD,
1501 case SK_PNMI_HRX_UTILUNDER:
1502 case SK_PNMI_HRX_UTILOVER:
1503 XM_IN16(IoC, PhysPortIndex, XM_RX_CMD,
1505 Register |= XM_RX_SAM_LINE;
1506 XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD,
1510 case SK_PNMI_HTX_OCTETHIGH:
1511 case SK_PNMI_HTX_OCTETLOW:
1512 case SK_PNMI_HTX_RESERVED:
1513 case SK_PNMI_HRX_OCTETHIGH:
1514 case SK_PNMI_HRX_OCTETLOW:
1515 case SK_PNMI_HRX_IRLENGTH:
1516 case SK_PNMI_HRX_RESERVED:
1519 * the following counters aren't be handled (id > 63)
1521 case SK_PNMI_HTX_SYNC:
1522 case SK_PNMI_HTX_SYNC_OCTET:
1525 case SK_PNMI_HRX_LONGFRAMES:
1526 if (MacType == SK_MAC_GMAC) {
1527 pAC->Pnmi.Port[PhysPortIndex].
1528 CounterHigh[CounterIndex] ++;
1533 pAC->Pnmi.Port[PhysPortIndex].
1534 CounterHigh[CounterIndex] ++;
1539 case SK_PNMI_EVT_SEN_WAR_LOW:
1541 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1543 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1544 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n",
1545 (unsigned int)Param.Para64));
1550 * Store a trap message in the trap buffer and generate
1551 * an event for user space applications with the
1552 * SK_DRIVER_SENDEVENT macro.
1554 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW,
1555 (unsigned int)Param.Para64);
1556 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1559 case SK_PNMI_EVT_SEN_WAR_UPP:
1561 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1563 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1564 ("PNMI: ERR:SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n",
1565 (unsigned int)Param.Para64));
1570 * Store a trap message in the trap buffer and generate
1571 * an event for user space applications with the
1572 * SK_DRIVER_SENDEVENT macro.
1574 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP,
1575 (unsigned int)Param.Para64);
1576 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1579 case SK_PNMI_EVT_SEN_ERR_LOW:
1581 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1583 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1584 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n",
1585 (unsigned int)Param.Para64));
1590 * Store a trap message in the trap buffer and generate
1591 * an event for user space applications with the
1592 * SK_DRIVER_SENDEVENT macro.
1594 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW,
1595 (unsigned int)Param.Para64);
1596 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1599 case SK_PNMI_EVT_SEN_ERR_UPP:
1601 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1603 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1604 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
1605 (unsigned int)Param.Para64));
1610 * Store a trap message in the trap buffer and generate
1611 * an event for user space applications with the
1612 * SK_DRIVER_SENDEVENT macro.
1614 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP,
1615 (unsigned int)Param.Para64);
1616 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1619 case SK_PNMI_EVT_CHG_EST_TIMER:
1621 * Calculate port switch average on a per hour basis
1622 * Time interval for check : 28125 ms
1623 * Number of values for average : 8
1625 * Be careful in changing these values, on change check
1626 * - typedef of SK_PNMI_ESTIMATE (Size of EstValue
1627 * array one less than value number)
1628 * - Timer initilization SkTimerStart() in SkPnmiInit
1629 * - Delta value below must be multiplicated with
1633 pEst = &pAC->Pnmi.RlmtChangeEstimate;
1634 CounterIndex = pEst->EstValueIndex + 1;
1635 if (CounterIndex == 7) {
1639 pEst->EstValueIndex = CounterIndex;
1641 NewestValue = pAC->Pnmi.RlmtChangeCts;
1642 OldestValue = pEst->EstValue[CounterIndex];
1643 pEst->EstValue[CounterIndex] = NewestValue;
1646 * Calculate average. Delta stores the number of
1647 * port switches per 28125 * 8 = 225000 ms
1649 if (NewestValue >= OldestValue) {
1651 Delta = NewestValue - OldestValue;
1654 /* Overflow situation */
1655 Delta = (SK_U64)(0 - OldestValue) + NewestValue;
1659 * Extrapolate delta to port switches per hour.
1660 * Estimate = Delta * (3600000 / 225000)
1664 pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4;
1667 * Check if threshold is exceeded. If the threshold is
1668 * permanently exceeded every 28125 ms an event will be
1669 * generated to remind the user of this condition.
1671 if ((pAC->Pnmi.RlmtChangeThreshold != 0) &&
1672 (pAC->Pnmi.RlmtChangeEstimate.Estimate >=
1673 pAC->Pnmi.RlmtChangeThreshold)) {
1675 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES);
1676 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1679 SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
1680 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
1681 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
1685 case SK_PNMI_EVT_CLEAR_COUNTER:
1687 * Param.Para32[0] contains the NetIndex (0 ..1).
1688 * Param.Para32[1] is reserved, contains -1.
1690 NetIndex = (SK_U32)Param.Para32[0];
1693 if (NetIndex >= pAC->Rlmt.NumNets) {
1695 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1696 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
1704 * Set all counters and timestamps to zero
1706 ResetCounter(pAC, IoC, NetIndex); /* the according NetIndex is required
1707 as a Parameter of the Event */
1710 case SK_PNMI_EVT_XMAC_RESET:
1712 * To grant continuous counter values store the current
1713 * XMAC statistic values to the entries 1..n of the
1714 * CounterOffset array. XMAC Errata #2
1717 if ((unsigned int)Param.Para64 >= SK_MAX_MACS) {
1719 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1720 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n",
1721 (unsigned int)Param.Para64));
1725 PhysPortIndex = (unsigned int)Param.Para64;
1728 * Update XMAC statistic to get fresh values
1730 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
1731 if (Ret != SK_PNMI_ERR_OK) {
1733 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1737 * Increment semaphore to indicate that an update was
1740 pAC->Pnmi.MacUpdatedFlag ++;
1742 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1745 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1750 pAC->Pnmi.Port[PhysPortIndex].
1751 CounterOffset[CounterIndex] = GetPhysStatVal(
1752 pAC, IoC, PhysPortIndex, CounterIndex);
1753 pAC->Pnmi.Port[PhysPortIndex].
1754 CounterHigh[CounterIndex] = 0;
1757 pAC->Pnmi.MacUpdatedFlag --;
1760 case SK_PNMI_EVT_RLMT_PORT_UP:
1761 PhysPortIndex = (unsigned int)Param.Para32[0];
1763 if (PhysPortIndex >= SK_MAX_MACS) {
1765 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1766 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter"
1767 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1773 * Store a trap message in the trap buffer and generate an event for
1774 * user space applications with the SK_DRIVER_SENDEVENT macro.
1776 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
1777 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1779 /* Bugfix for XMAC errata (#10620)*/
1780 if (pAC->GIni.GIMacType == SK_MAC_XMAC){
1782 /* Add incremental difference to offset (#10620)*/
1783 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1784 XM_RXE_SHT_ERR, &Val32);
1786 Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1787 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1788 pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
1789 Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
1792 /* Tell VctStatus() that a link was up meanwhile. */
1793 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK;
1796 case SK_PNMI_EVT_RLMT_PORT_DOWN:
1797 PhysPortIndex = (unsigned int)Param.Para32[0];
1800 if (PhysPortIndex >= SK_MAX_MACS) {
1802 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1803 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter"
1804 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1810 * Store a trap message in the trap buffer and generate an event for
1811 * user space applications with the SK_DRIVER_SENDEVENT macro.
1813 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
1814 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1816 /* Bugfix #10620 - get zero level for incremental difference */
1817 if ((pAC->GIni.GIMacType == SK_MAC_XMAC)) {
1819 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1820 XM_RXE_SHT_ERR, &Val32);
1821 pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark =
1822 (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1823 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1827 case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
1828 PhysPortIndex = (unsigned int)Param.Para32[0];
1829 NetIndex = (SK_U32)Param.Para32[1];
1832 if (PhysPortIndex >= SK_MAX_MACS) {
1834 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1835 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
1839 if (NetIndex >= pAC->Rlmt.NumNets) {
1841 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1842 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
1847 * For now, ignore event if NetIndex != 0.
1849 if (Param.Para32[1] != 0) {
1855 * Nothing to do if port is already inactive
1857 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1863 * Update statistic counters to calculate new offset for the virtual
1864 * port and increment semaphore to indicate that an update was already
1867 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1870 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1873 pAC->Pnmi.MacUpdatedFlag ++;
1876 * Calculate new counter offset for virtual port to grant continous
1877 * counting on port switches. The virtual port consists of all currently
1878 * active ports. The port down event indicates that a port is removed
1879 * from the virtual port. Therefore add the counter value of the removed
1880 * port to the CounterOffset for the virtual port to grant the same
1883 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1886 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1891 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1893 pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
1897 * Set port to inactive
1899 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
1901 pAC->Pnmi.MacUpdatedFlag --;
1904 case SK_PNMI_EVT_RLMT_ACTIVE_UP:
1905 PhysPortIndex = (unsigned int)Param.Para32[0];
1906 NetIndex = (SK_U32)Param.Para32[1];
1909 if (PhysPortIndex >= SK_MAX_MACS) {
1911 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1912 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
1916 if (NetIndex >= pAC->Rlmt.NumNets) {
1918 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1919 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
1924 * For now, ignore event if NetIndex != 0.
1926 if (Param.Para32[1] != 0) {
1932 * Nothing to do if port is already active
1934 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1940 * Statistic maintenance
1942 pAC->Pnmi.RlmtChangeCts ++;
1943 pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
1946 * Store a trap message in the trap buffer and generate an event for
1947 * user space applications with the SK_DRIVER_SENDEVENT macro.
1949 QueueRlmtNewMacTrap(pAC, PhysPortIndex);
1950 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1953 * Update statistic counters to calculate new offset for the virtual
1954 * port and increment semaphore to indicate that an update was
1957 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1960 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1963 pAC->Pnmi.MacUpdatedFlag ++;
1966 * Calculate new counter offset for virtual port to grant continous
1967 * counting on port switches. A new port is added to the virtual port.
1968 * Therefore substract the counter value of the new port from the
1969 * CounterOffset for the virtual port to grant the same value.
1971 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1974 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1979 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1981 pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
1985 * Set port to active
1987 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
1989 pAC->Pnmi.MacUpdatedFlag --;
1992 case SK_PNMI_EVT_RLMT_SEGMENTATION:
1994 * Para.Para32[0] contains the NetIndex.
1998 * Store a trap message in the trap buffer and generate an event for
1999 * user space applications with the SK_DRIVER_SENDEVENT macro.
2001 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
2002 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
2005 case SK_PNMI_EVT_RLMT_SET_NETS:
2007 * Param.Para32[0] contains the number of Nets.
2008 * Param.Para32[1] is reserved, contains -1.
2011 * Check number of nets
2013 MaxNetNumber = pAC->GIni.GIMacsFound;
2014 if (((unsigned int)Param.Para32[0] < 1)
2015 || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
2016 return (SK_PNMI_ERR_UNKNOWN_NET);
2019 if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
2020 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
2022 else { /* dual net mode */
2023 pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
2027 case SK_PNMI_EVT_VCT_RESET:
2028 PhysPortIndex = Param.Para32[0];
2029 pPrt = &pAC->GIni.GP[PhysPortIndex];
2030 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
2032 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
2033 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
2036 * VCT test is still running.
2037 * Start VCT timer counter again.
2039 SK_MEMSET((char *) &Param, 0, sizeof(Param));
2040 Param.Para32[0] = PhysPortIndex;
2041 Param.Para32[1] = -1;
2042 SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
2043 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
2046 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
2047 pAC->Pnmi.VctStatus[PhysPortIndex] |=
2048 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
2050 /* Copy results for later use to PNMI struct. */
2051 for (i = 0; i < 4; i++) {
2052 if (pPrt->PMdiPairLen[i] > 35) {
2053 CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
2058 pVctBackupData->PMdiPairLen[i] = CableLength;
2059 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
2062 Param.Para32[0] = PhysPortIndex;
2063 Param.Para32[1] = -1;
2064 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
2065 SkEventDispatcher(pAC, IoC);
2074 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
2079 /******************************************************************************
2085 /*****************************************************************************
2087 * PnmiVar - Gets, presets, and sets single OIDs
2090 * Looks up the requested OID, calls the corresponding handler
2091 * function, and passes the parameters with the get, preset, or
2092 * set command. The function is called by SkGePnmiGetVar,
2093 * SkGePnmiPreSetVar, or SkGePnmiSetVar.
2096 * SK_PNMI_ERR_XXX. For details have a look to the description of the
2097 * calling functions.
2098 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
2100 PNMI_STATIC int PnmiVar(
2101 SK_AC *pAC, /* Pointer to adapter context */
2102 SK_IOC IoC, /* IO context handle */
2103 int Action, /* Get/PreSet/Set action */
2104 SK_U32 Id, /* Object ID that is to be processed */
2105 char *pBuf, /* Buffer which stores the mgmt data to be set */
2106 unsigned int *pLen, /* Total length of mgmt data */
2107 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
2108 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2110 unsigned int TableIndex;
2114 if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
2117 return (SK_PNMI_ERR_UNKNOWN_OID);
2123 if (NetIndex >= pAC->Rlmt.NumNets) {
2124 return (SK_PNMI_ERR_UNKNOWN_NET);
2127 SK_PNMI_CHECKFLAGS("PnmiVar: On call");
2129 Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
2130 Instance, TableIndex, NetIndex);
2132 SK_PNMI_CHECKFLAGS("PnmiVar: On return");
2137 /*****************************************************************************
2139 * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA
2142 * The return value of the function will also be stored in
2143 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
2144 * SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable,
2145 * checks which OIDs are able to set, and calls the handler function of
2146 * the OID to perform the set. The return value of the function will
2147 * also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
2148 * minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called
2149 * by SkGePnmiPreSetStruct and SkGePnmiSetStruct.
2152 * SK_PNMI_ERR_XXX. The codes are described in the calling functions.
2153 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
2155 PNMI_STATIC int PnmiStruct(
2156 SK_AC *pAC, /* Pointer to adapter context */
2157 SK_IOC IoC, /* IO context handle */
2158 int Action, /* Set action to be performed */
2159 char *pBuf, /* Buffer which contains the data to be set */
2160 unsigned int *pLen, /* Length of buffer */
2161 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2164 unsigned int TableIndex;
2165 unsigned int DstOffset;
2167 unsigned int InstanceNo;
2168 unsigned int InstanceCnt;
2173 /* Check if the passed buffer has the right size */
2174 if (*pLen < SK_PNMI_STRUCT_SIZE) {
2176 /* Check if we can return the error within the buffer */
2177 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
2179 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
2183 *pLen = SK_PNMI_STRUCT_SIZE;
2184 return (SK_PNMI_ERR_TOO_SHORT);
2190 if (NetIndex >= pAC->Rlmt.NumNets) {
2191 return (SK_PNMI_ERR_UNKNOWN_NET);
2194 SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
2197 * Update the values of RLMT and SIRQ and increment semaphores to
2198 * indicate that an update was already done.
2200 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
2202 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
2203 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2207 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
2209 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
2210 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2214 pAC->Pnmi.RlmtUpdatedFlag ++;
2215 pAC->Pnmi.SirqUpdatedFlag ++;
2217 /* Preset/Set values */
2218 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
2220 if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
2221 (IdTable[TableIndex].Access != SK_PNMI_WO)) {
2226 InstanceNo = IdTable[TableIndex].InstanceNo;
2227 Id = IdTable[TableIndex].Id;
2229 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
2232 DstOffset = IdTable[TableIndex].Offset +
2234 IdTable[TableIndex].StructSize;
2237 * Because VPD multiple instance variables are
2238 * not setable we do not need to evaluate VPD
2239 * instances. Have a look to VPD instance
2240 * calculation in SkPnmiGetStruct().
2242 Instance = (SK_U32)InstanceCnt;
2245 * Evaluate needed buffer length
2248 Ret = IdTable[TableIndex].Func(pAC, IoC,
2249 SK_PNMI_GET, IdTable[TableIndex].Id,
2250 NULL, &Len, Instance, TableIndex, NetIndex);
2252 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
2256 if (Ret != SK_PNMI_ERR_TOO_SHORT) {
2258 pAC->Pnmi.RlmtUpdatedFlag --;
2259 pAC->Pnmi.SirqUpdatedFlag --;
2261 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
2262 SK_PNMI_SET_STAT(pBuf,
2263 SK_PNMI_ERR_GENERAL, DstOffset);
2264 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2265 return (SK_PNMI_ERR_GENERAL);
2267 if (Id == OID_SKGE_VPD_ACTION) {
2269 switch (*(pBuf + DstOffset)) {
2271 case SK_PNMI_VPD_CREATE:
2272 Len = 3 + *(pBuf + DstOffset + 3);
2275 case SK_PNMI_VPD_DELETE:
2285 /* Call the OID handler function */
2286 Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
2287 IdTable[TableIndex].Id, pBuf + DstOffset,
2288 &Len, Instance, TableIndex, NetIndex);
2290 if (Ret != SK_PNMI_ERR_OK) {
2292 pAC->Pnmi.RlmtUpdatedFlag --;
2293 pAC->Pnmi.SirqUpdatedFlag --;
2295 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
2296 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
2298 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2299 return (SK_PNMI_ERR_BAD_VALUE);
2304 pAC->Pnmi.RlmtUpdatedFlag --;
2305 pAC->Pnmi.SirqUpdatedFlag --;
2307 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
2308 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
2309 return (SK_PNMI_ERR_OK);
2312 /*****************************************************************************
2314 * LookupId - Lookup an OID in the IdTable
2317 * Scans the IdTable to find the table entry of an OID.
2320 * The table index or -1 if not found.
2322 PNMI_STATIC int LookupId(
2323 SK_U32 Id) /* Object identifier to be searched */
2327 for (i = 0; i < ID_TABLE_SIZE; i++) {
2329 if (IdTable[i].Id == Id) {
2338 /*****************************************************************************
2340 * OidStruct - Handler of OID_SKGE_ALL_DATA
2343 * This OID performs a Get/Preset/SetStruct call and returns all data
2344 * in a SK_PNMI_STRUCT_DATA structure.
2347 * SK_PNMI_ERR_OK The request was successfully performed.
2348 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2349 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2350 * the correct data (e.g. a 32bit value is
2351 * needed, but a 16 bit value was passed).
2352 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2354 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2355 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2356 * exist (e.g. port instance 3 on a two port
2359 PNMI_STATIC int OidStruct(
2360 SK_AC *pAC, /* Pointer to adapter context */
2361 SK_IOC IoC, /* IO context handle */
2362 int Action, /* Get/PreSet/Set action */
2363 SK_U32 Id, /* Object ID that is to be processed */
2364 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2365 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2366 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2367 unsigned int TableIndex, /* Index to the Id table */
2368 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2370 if (Id != OID_SKGE_ALL_DATA) {
2372 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
2376 return (SK_PNMI_ERR_GENERAL);
2380 * Check instance. We only handle single instance variables
2382 if (Instance != (SK_U32)(-1) && Instance != 1) {
2385 return (SK_PNMI_ERR_UNKNOWN_INST);
2391 return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
2393 case SK_PNMI_PRESET:
2394 return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
2397 return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
2400 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
2403 return (SK_PNMI_ERR_GENERAL);
2406 /*****************************************************************************
2408 * Perform - OID handler of OID_SKGE_ACTION
2414 * SK_PNMI_ERR_OK The request was successfully performed.
2415 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2416 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2417 * the correct data (e.g. a 32bit value is
2418 * needed, but a 16 bit value was passed).
2419 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2421 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2422 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2423 * exist (e.g. port instance 3 on a two port
2426 PNMI_STATIC int Perform(
2427 SK_AC *pAC, /* Pointer to adapter context */
2428 SK_IOC IoC, /* IO context handle */
2429 int Action, /* Get/PreSet/Set action */
2430 SK_U32 Id, /* Object ID that is to be processed */
2431 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2432 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2433 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2434 unsigned int TableIndex, /* Index to the Id table */
2435 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2442 * Check instance. We only handle single instance variables
2444 if (Instance != (SK_U32)(-1) && Instance != 1) {
2447 return (SK_PNMI_ERR_UNKNOWN_INST);
2450 if (*pLen < sizeof(SK_U32)) {
2452 *pLen = sizeof(SK_U32);
2453 return (SK_PNMI_ERR_TOO_SHORT);
2456 /* Check if a get should be performed */
2457 if (Action == SK_PNMI_GET) {
2459 /* A get is easy. We always return the same value */
2460 ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
2461 SK_PNMI_STORE_U32(pBuf, ActionOp);
2462 *pLen = sizeof(SK_U32);
2464 return (SK_PNMI_ERR_OK);
2467 /* Continue with PRESET/SET action */
2468 if (*pLen > sizeof(SK_U32)) {
2470 return (SK_PNMI_ERR_BAD_VALUE);
2473 /* Check if the command is a known one */
2474 SK_PNMI_READ_U32(pBuf, ActionOp);
2475 if (*pLen > sizeof(SK_U32) ||
2476 (ActionOp != SK_PNMI_ACT_IDLE &&
2477 ActionOp != SK_PNMI_ACT_RESET &&
2478 ActionOp != SK_PNMI_ACT_SELFTEST &&
2479 ActionOp != SK_PNMI_ACT_RESETCNT)) {
2482 return (SK_PNMI_ERR_BAD_VALUE);
2485 /* A preset ends here */
2486 if (Action == SK_PNMI_PRESET) {
2488 return (SK_PNMI_ERR_OK);
2493 case SK_PNMI_ACT_IDLE:
2497 case SK_PNMI_ACT_RESET:
2499 * Perform a driver reset or something that comes near
2502 Ret = SK_DRIVER_RESET(pAC, IoC);
2505 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
2508 return (SK_PNMI_ERR_GENERAL);
2512 case SK_PNMI_ACT_SELFTEST:
2514 * Perform a driver selftest or something similar to this.
2515 * Currently this feature is not used and will probably
2516 * implemented in another way.
2518 Ret = SK_DRIVER_SELFTEST(pAC, IoC);
2519 pAC->Pnmi.TestResult = Ret;
2522 case SK_PNMI_ACT_RESETCNT:
2523 /* Set all counters and timestamps to zero */
2524 ResetCounter(pAC, IoC, NetIndex);
2528 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
2531 return (SK_PNMI_ERR_GENERAL);
2534 return (SK_PNMI_ERR_OK);
2537 /*****************************************************************************
2539 * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX
2542 * Retrieves the statistic values of the virtual port (logical
2543 * index 0). Only special OIDs of NDIS are handled which consist
2544 * of a 32 bit instead of a 64 bit value. The OIDs are public
2545 * because perhaps some other platform can use them too.
2548 * SK_PNMI_ERR_OK The request was successfully performed.
2549 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2550 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2551 * the correct data (e.g. a 32bit value is
2552 * needed, but a 16 bit value was passed).
2553 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2554 * exist (e.g. port instance 3 on a two port
2557 PNMI_STATIC int Mac8023Stat(
2558 SK_AC *pAC, /* Pointer to adapter context */
2559 SK_IOC IoC, /* IO context handle */
2560 int Action, /* Get/PreSet/Set action */
2561 SK_U32 Id, /* Object ID that is to be processed */
2562 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2563 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2564 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2565 unsigned int TableIndex, /* Index to the Id table */
2566 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2571 SK_BOOL Is64BitReq = SK_FALSE;
2574 * Only the active Mac is returned
2576 if (Instance != (SK_U32)(-1) && Instance != 1) {
2579 return (SK_PNMI_ERR_UNKNOWN_INST);
2585 if (Action != SK_PNMI_GET) {
2588 return (SK_PNMI_ERR_READ_ONLY);
2596 case OID_802_3_PERMANENT_ADDRESS:
2597 case OID_802_3_CURRENT_ADDRESS:
2598 if (*pLen < sizeof(SK_MAC_ADDR)) {
2600 *pLen = sizeof(SK_MAC_ADDR);
2601 return (SK_PNMI_ERR_TOO_SHORT);
2606 #ifndef SK_NDIS_64BIT_CTR
2607 if (*pLen < sizeof(SK_U32)) {
2608 *pLen = sizeof(SK_U32);
2609 return (SK_PNMI_ERR_TOO_SHORT);
2612 #else /* SK_NDIS_64BIT_CTR */
2615 * for compatibility, at least 32bit are required for oid
2617 if (*pLen < sizeof(SK_U32)) {
2619 * but indicate handling for 64bit values,
2620 * if insufficient space is provided
2622 *pLen = sizeof(SK_U64);
2623 return (SK_PNMI_ERR_TOO_SHORT);
2626 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
2627 #endif /* SK_NDIS_64BIT_CTR */
2632 * Update all statistics, because we retrieve virtual MAC, which
2633 * consists of multiple physical statistics and increment semaphore
2634 * to indicate that an update was already done.
2636 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2637 if ( Ret != SK_PNMI_ERR_OK) {
2642 pAC->Pnmi.MacUpdatedFlag ++;
2645 * Get value (MAC Index 0 identifies the virtual MAC)
2649 case OID_802_3_PERMANENT_ADDRESS:
2650 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2651 *pLen = sizeof(SK_MAC_ADDR);
2654 case OID_802_3_CURRENT_ADDRESS:
2655 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2656 *pLen = sizeof(SK_MAC_ADDR);
2660 StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
2663 * by default 32bit values are evaluated
2666 StatVal32 = (SK_U32)StatVal;
2667 SK_PNMI_STORE_U32(pBuf, StatVal32);
2668 *pLen = sizeof(SK_U32);
2671 SK_PNMI_STORE_U64(pBuf, StatVal);
2672 *pLen = sizeof(SK_U64);
2677 pAC->Pnmi.MacUpdatedFlag --;
2679 return (SK_PNMI_ERR_OK);
2682 /*****************************************************************************
2684 * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX
2687 * Retrieves the XMAC statistic data.
2690 * SK_PNMI_ERR_OK The request was successfully performed.
2691 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2692 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2693 * the correct data (e.g. a 32bit value is
2694 * needed, but a 16 bit value was passed).
2695 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2696 * exist (e.g. port instance 3 on a two port
2699 PNMI_STATIC int MacPrivateStat(
2700 SK_AC *pAC, /* Pointer to adapter context */
2701 SK_IOC IoC, /* IO context handle */
2702 int Action, /* Get/PreSet/Set action */
2703 SK_U32 Id, /* Object ID that is to be processed */
2704 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2705 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2706 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2707 unsigned int TableIndex, /* Index to the Id table */
2708 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2710 unsigned int LogPortMax;
2711 unsigned int LogPortIndex;
2712 unsigned int PhysPortMax;
2714 unsigned int Offset;
2720 * Calculate instance if wished. MAC index 0 is the virtual
2723 PhysPortMax = pAC->GIni.GIMacsFound;
2724 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2726 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2730 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2731 /* Check instance range */
2732 if ((Instance < 1) || (Instance > LogPortMax)) {
2735 return (SK_PNMI_ERR_UNKNOWN_INST);
2737 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2738 Limit = LogPortIndex + 1;
2741 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2751 if (Action != SK_PNMI_GET) {
2754 return (SK_PNMI_ERR_READ_ONLY);
2760 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
2762 *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
2763 return (SK_PNMI_ERR_TOO_SHORT);
2767 * Update XMAC statistic and increment semaphore to indicate that
2768 * an update was already done.
2770 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2771 if (Ret != SK_PNMI_ERR_OK) {
2776 pAC->Pnmi.MacUpdatedFlag ++;
2782 for (; LogPortIndex < Limit; LogPortIndex ++) {
2786 /* XXX not yet implemented due to XMAC problems
2787 case OID_SKGE_STAT_TX_UTIL:
2788 return (SK_PNMI_ERR_GENERAL);
2790 /* XXX not yet implemented due to XMAC problems
2791 case OID_SKGE_STAT_RX_UTIL:
2792 return (SK_PNMI_ERR_GENERAL);
2794 case OID_SKGE_STAT_RX:
2795 case OID_SKGE_STAT_TX:
2796 switch (pAC->GIni.GIMacType) {
2798 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2799 IdTable[TableIndex].Param, NetIndex);
2803 if (Id == OID_SKGE_STAT_TX) {
2806 GetStatVal(pAC, IoC, LogPortIndex,
2807 SK_PNMI_HTX_BROADCAST, NetIndex) +
2808 GetStatVal(pAC, IoC, LogPortIndex,
2809 SK_PNMI_HTX_MULTICAST, NetIndex) +
2810 GetStatVal(pAC, IoC, LogPortIndex,
2811 SK_PNMI_HTX_UNICAST, NetIndex);
2815 GetStatVal(pAC, IoC, LogPortIndex,
2816 SK_PNMI_HRX_BROADCAST, NetIndex) +
2817 GetStatVal(pAC, IoC, LogPortIndex,
2818 SK_PNMI_HRX_MULTICAST, NetIndex) +
2819 GetStatVal(pAC, IoC, LogPortIndex,
2820 SK_PNMI_HRX_UNICAST, NetIndex) +
2821 GetStatVal(pAC, IoC, LogPortIndex,
2822 SK_PNMI_HRX_UNDERSIZE, NetIndex);
2831 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2835 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2836 IdTable[TableIndex].Param, NetIndex);
2837 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2841 Offset += sizeof(SK_U64);
2845 pAC->Pnmi.MacUpdatedFlag --;
2847 return (SK_PNMI_ERR_OK);
2850 /*****************************************************************************
2852 * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR
2855 * Get/Presets/Sets the current and factory MAC address. The MAC
2856 * address of the virtual port, which is reported to the OS, may
2857 * not be changed, but the physical ones. A set to the virtual port
2858 * will be ignored. No error should be reported because otherwise
2859 * a multiple instance set (-1) would always fail.
2862 * SK_PNMI_ERR_OK The request was successfully performed.
2863 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2864 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2865 * the correct data (e.g. a 32bit value is
2866 * needed, but a 16 bit value was passed).
2867 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2869 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2870 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2871 * exist (e.g. port instance 3 on a two port
2874 PNMI_STATIC int Addr(
2875 SK_AC *pAC, /* Pointer to adapter context */
2876 SK_IOC IoC, /* IO context handle */
2877 int Action, /* Get/PreSet/Set action */
2878 SK_U32 Id, /* Object ID that is to be processed */
2879 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2880 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2881 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2882 unsigned int TableIndex, /* Index to the Id table */
2883 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2886 unsigned int LogPortMax;
2887 unsigned int PhysPortMax;
2888 unsigned int LogPortIndex;
2889 unsigned int PhysPortIndex;
2891 unsigned int Offset = 0;
2894 * Calculate instance if wished. MAC index 0 is the virtual
2897 PhysPortMax = pAC->GIni.GIMacsFound;
2898 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2900 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2904 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2905 /* Check instance range */
2906 if ((Instance < 1) || (Instance > LogPortMax)) {
2909 return (SK_PNMI_ERR_UNKNOWN_INST);
2911 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2912 Limit = LogPortIndex + 1;
2915 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2924 if (Action == SK_PNMI_GET) {
2929 if (*pLen < (Limit - LogPortIndex) * 6) {
2931 *pLen = (Limit - LogPortIndex) * 6;
2932 return (SK_PNMI_ERR_TOO_SHORT);
2938 for (; LogPortIndex < Limit; LogPortIndex ++) {
2942 case OID_SKGE_PHYS_CUR_ADDR:
2943 if (LogPortIndex == 0) {
2944 CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2947 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
2949 CopyMac(pBuf + Offset,
2950 &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
2955 case OID_SKGE_PHYS_FAC_ADDR:
2956 if (LogPortIndex == 0) {
2957 CopyMac(pBuf + Offset,
2958 &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2961 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
2964 CopyMac(pBuf + Offset,
2965 &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
2971 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
2975 return (SK_PNMI_ERR_GENERAL);
2983 * The logical MAC address may not be changed only
2986 if (Id == OID_SKGE_PHYS_FAC_ADDR) {
2989 return (SK_PNMI_ERR_READ_ONLY);
2993 * Only the current address may be changed
2995 if (Id != OID_SKGE_PHYS_CUR_ADDR) {
2997 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
3001 return (SK_PNMI_ERR_GENERAL);
3007 if (*pLen < (Limit - LogPortIndex) * 6) {
3009 *pLen = (Limit - LogPortIndex) * 6;
3010 return (SK_PNMI_ERR_TOO_SHORT);
3012 if (*pLen > (Limit - LogPortIndex) * 6) {
3015 return (SK_PNMI_ERR_BAD_VALUE);
3021 if (Action == SK_PNMI_PRESET) {
3024 return (SK_PNMI_ERR_OK);
3028 * Set OID_SKGE_MAC_CUR_ADDR
3030 for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
3033 * A set to virtual port and set of broadcast
3034 * address will be ignored
3036 if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
3037 "\xff\xff\xff\xff\xff\xff", 6) == 0) {
3042 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
3045 Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
3046 (SK_MAC_ADDR *)(pBuf + Offset),
3047 (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
3048 SK_ADDR_PHYSICAL_ADDRESS));
3049 if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {
3051 return (SK_PNMI_ERR_GENERAL);
3057 return (SK_PNMI_ERR_OK);
3060 /*****************************************************************************
3062 * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
3065 * Retrieves the statistic values of the CSUM module. The CSUM data
3066 * structure must be available in the SK_AC even if the CSUM module
3067 * is not included, because PNMI reads the statistic data from the
3068 * CSUM part of SK_AC directly.
3071 * SK_PNMI_ERR_OK The request was successfully performed.
3072 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3073 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3074 * the correct data (e.g. a 32bit value is
3075 * needed, but a 16 bit value was passed).
3076 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3077 * exist (e.g. port instance 3 on a two port
3080 PNMI_STATIC int CsumStat(
3081 SK_AC *pAC, /* Pointer to adapter context */
3082 SK_IOC IoC, /* IO context handle */
3083 int Action, /* Get/PreSet/Set action */
3084 SK_U32 Id, /* Object ID that is to be processed */
3085 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
3086 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3087 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3088 unsigned int TableIndex, /* Index to the Id table */
3089 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
3093 unsigned int Offset = 0;
3098 * Calculate instance if wished
3100 if (Instance != (SK_U32)(-1)) {
3102 if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
3105 return (SK_PNMI_ERR_UNKNOWN_INST);
3107 Index = (unsigned int)Instance - 1;
3112 Limit = SKCS_NUM_PROTOCOLS;
3118 if (Action != SK_PNMI_GET) {
3121 return (SK_PNMI_ERR_READ_ONLY);
3127 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
3129 *pLen = (Limit - Index) * sizeof(SK_U64);
3130 return (SK_PNMI_ERR_TOO_SHORT);
3136 for (; Index < Limit; Index ++) {
3140 case OID_SKGE_CHKSM_RX_OK_CTS:
3141 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
3144 case OID_SKGE_CHKSM_RX_UNABLE_CTS:
3145 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
3148 case OID_SKGE_CHKSM_RX_ERR_CTS:
3149 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
3152 case OID_SKGE_CHKSM_TX_OK_CTS:
3153 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
3156 case OID_SKGE_CHKSM_TX_UNABLE_CTS:
3157 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
3161 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
3165 return (SK_PNMI_ERR_GENERAL);
3168 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
3169 Offset += sizeof(SK_U64);
3173 * Store used buffer space
3177 return (SK_PNMI_ERR_OK);
3180 /*****************************************************************************
3182 * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
3185 * Retrieves the statistic values of the I2C module, which handles
3186 * the temperature and voltage sensors.
3189 * SK_PNMI_ERR_OK The request was successfully performed.
3190 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3191 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3192 * the correct data (e.g. a 32bit value is
3193 * needed, but a 16 bit value was passed).
3194 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3195 * exist (e.g. port instance 3 on a two port
3198 PNMI_STATIC int SensorStat(
3199 SK_AC *pAC, /* Pointer to adapter context */
3200 SK_IOC IoC, /* IO context handle */
3201 int Action, /* Get/PreSet/Set action */
3202 SK_U32 Id, /* Object ID that is to be processed */
3203 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
3204 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3205 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3206 unsigned int TableIndex, /* Index to the Id table */
3207 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
3212 unsigned int Offset;
3219 * Calculate instance if wished
3221 if ((Instance != (SK_U32)(-1))) {
3223 if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
3226 return (SK_PNMI_ERR_UNKNOWN_INST);
3229 Index = (unsigned int)Instance -1;
3230 Limit = (unsigned int)Instance;
3234 Limit = (unsigned int) pAC->I2c.MaxSens;
3240 if (Action != SK_PNMI_GET) {
3243 return (SK_PNMI_ERR_READ_ONLY);
3251 case OID_SKGE_SENSOR_VALUE:
3252 case OID_SKGE_SENSOR_WAR_THRES_LOW:
3253 case OID_SKGE_SENSOR_WAR_THRES_UPP:
3254 case OID_SKGE_SENSOR_ERR_THRES_LOW:
3255 case OID_SKGE_SENSOR_ERR_THRES_UPP:
3256 if (*pLen < (Limit - Index) * sizeof(SK_U32)) {
3258 *pLen = (Limit - Index) * sizeof(SK_U32);
3259 return (SK_PNMI_ERR_TOO_SHORT);
3263 case OID_SKGE_SENSOR_DESCR:
3264 for (Offset = 0, i = Index; i < Limit; i ++) {
3266 Len = (unsigned int)
3267 SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1;
3268 if (Len >= SK_PNMI_STRINGLEN2) {
3270 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011,
3274 return (SK_PNMI_ERR_GENERAL);
3278 if (*pLen < Offset) {
3281 return (SK_PNMI_ERR_TOO_SHORT);
3285 case OID_SKGE_SENSOR_INDEX:
3286 case OID_SKGE_SENSOR_TYPE:
3287 case OID_SKGE_SENSOR_STATUS:
3288 if (*pLen < Limit - Index) {
3290 *pLen = Limit - Index;
3291 return (SK_PNMI_ERR_TOO_SHORT);
3295 case OID_SKGE_SENSOR_WAR_CTS:
3296 case OID_SKGE_SENSOR_WAR_TIME:
3297 case OID_SKGE_SENSOR_ERR_CTS:
3298 case OID_SKGE_SENSOR_ERR_TIME:
3299 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
3301 *pLen = (Limit - Index) * sizeof(SK_U64);
3302 return (SK_PNMI_ERR_TOO_SHORT);
3307 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
3311 return (SK_PNMI_ERR_GENERAL);
3318 for (Offset = 0; Index < Limit; Index ++) {
3322 case OID_SKGE_SENSOR_INDEX:
3323 *(pBuf + Offset) = (char)Index;
3324 Offset += sizeof(char);
3327 case OID_SKGE_SENSOR_DESCR:
3328 Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
3329 SK_MEMCPY(pBuf + Offset + 1,
3330 pAC->I2c.SenTable[Index].SenDesc, Len);
3331 *(pBuf + Offset) = (char)Len;
3335 case OID_SKGE_SENSOR_TYPE:
3337 (char)pAC->I2c.SenTable[Index].SenType;
3338 Offset += sizeof(char);
3341 case OID_SKGE_SENSOR_VALUE:
3342 Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
3343 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3344 Offset += sizeof(SK_U32);
3347 case OID_SKGE_SENSOR_WAR_THRES_LOW:
3348 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
3350 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3351 Offset += sizeof(SK_U32);
3354 case OID_SKGE_SENSOR_WAR_THRES_UPP:
3355 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
3357 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3358 Offset += sizeof(SK_U32);
3361 case OID_SKGE_SENSOR_ERR_THRES_LOW:
3362 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
3364 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3365 Offset += sizeof(SK_U32);
3368 case OID_SKGE_SENSOR_ERR_THRES_UPP:
3369 Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
3370 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3371 Offset += sizeof(SK_U32);
3374 case OID_SKGE_SENSOR_STATUS:
3376 (char)pAC->I2c.SenTable[Index].SenErrFlag;
3377 Offset += sizeof(char);
3380 case OID_SKGE_SENSOR_WAR_CTS:
3381 Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
3382 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3383 Offset += sizeof(SK_U64);
3386 case OID_SKGE_SENSOR_ERR_CTS:
3387 Val64 = pAC->I2c.SenTable[Index].SenErrCts;
3388 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3389 Offset += sizeof(SK_U64);
3392 case OID_SKGE_SENSOR_WAR_TIME:
3393 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
3395 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3396 Offset += sizeof(SK_U64);
3399 case OID_SKGE_SENSOR_ERR_TIME:
3400 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
3402 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3403 Offset += sizeof(SK_U64);
3407 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
3408 ("SensorStat: Unknown OID should be handled before"));
3410 return (SK_PNMI_ERR_GENERAL);
3415 * Store used buffer space
3419 return (SK_PNMI_ERR_OK);
3422 /*****************************************************************************
3424 * Vpd - OID handler function of OID_SKGE_VPD_XXX
3427 * Get/preset/set of VPD data. As instance the name of a VPD key
3428 * can be passed. The Instance parameter is a SK_U32 and can be
3429 * used as a string buffer for the VPD key, because their maximum
3433 * SK_PNMI_ERR_OK The request was successfully performed.
3434 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3435 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3436 * the correct data (e.g. a 32bit value is
3437 * needed, but a 16 bit value was passed).
3438 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
3440 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
3441 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3442 * exist (e.g. port instance 3 on a two port
3445 PNMI_STATIC int Vpd(
3446 SK_AC *pAC, /* Pointer to adapter context */
3447 SK_IOC IoC, /* IO context handle */
3448 int Action, /* Get/PreSet/Set action */
3449 SK_U32 Id, /* Object ID that is to be processed */
3450 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
3451 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3452 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3453 unsigned int TableIndex, /* Index to the Id table */
3454 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
3456 SK_VPD_STATUS *pVpdStatus;
3457 unsigned int BufLen;
3459 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
3460 char KeyStr[SK_PNMI_VPD_KEY_SIZE];
3462 unsigned int Offset;
3464 unsigned int FirstIndex;
3465 unsigned int LastIndex;
3471 * Get array of all currently stored VPD keys
3473 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr),
3475 if (Ret != SK_PNMI_ERR_OK) {
3481 * If instance is not -1, try to find the requested VPD key for
3482 * the multiple instance variables. The other OIDs as for example
3483 * OID VPD_ACTION are single instance variables and must be
3484 * handled separatly.
3489 if ((Instance != (SK_U32)(-1))) {
3491 if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
3492 Id == OID_SKGE_VPD_ACCESS) {
3494 SK_STRNCPY(KeyStr, (char *)&Instance, 4);
3497 for (Index = 0; Index < KeyNo; Index ++) {
3499 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3501 LastIndex = Index+1;
3505 if (Index == KeyNo) {
3508 return (SK_PNMI_ERR_UNKNOWN_INST);
3511 else if (Instance != 1) {
3514 return (SK_PNMI_ERR_UNKNOWN_INST);
3519 * Get value, if a query should be performed
3521 if (Action == SK_PNMI_GET) {
3525 case OID_SKGE_VPD_FREE_BYTES:
3526 /* Check length of buffer */
3527 if (*pLen < sizeof(SK_U32)) {
3529 *pLen = sizeof(SK_U32);
3530 return (SK_PNMI_ERR_TOO_SHORT);
3532 /* Get number of free bytes */
3533 pVpdStatus = VpdStat(pAC, IoC);
3534 if (pVpdStatus == NULL) {
3536 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
3540 return (SK_PNMI_ERR_GENERAL);
3542 if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
3544 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
3548 return (SK_PNMI_ERR_GENERAL);
3551 Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
3552 SK_PNMI_STORE_U32(pBuf, Val32);
3553 *pLen = sizeof(SK_U32);
3556 case OID_SKGE_VPD_ENTRIES_LIST:
3558 for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
3560 Len += SK_STRLEN(KeyArr[Index]) + 1;
3565 return (SK_PNMI_ERR_TOO_SHORT);
3569 *(pBuf) = (char)Len - 1;
3570 for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
3572 Len = SK_STRLEN(KeyArr[Index]);
3573 SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
3577 if (Index < KeyNo - 1) {
3579 *(pBuf + Offset) = ' ';
3586 case OID_SKGE_VPD_ENTRIES_NUMBER:
3588 if (*pLen < sizeof(SK_U32)) {
3590 *pLen = sizeof(SK_U32);
3591 return (SK_PNMI_ERR_TOO_SHORT);
3594 Val32 = (SK_U32)KeyNo;
3595 SK_PNMI_STORE_U32(pBuf, Val32);
3596 *pLen = sizeof(SK_U32);
3599 case OID_SKGE_VPD_KEY:
3600 /* Check buffer length, if it is large enough */
3601 for (Len = 0, Index = FirstIndex;
3602 Index < LastIndex; Index ++) {
3604 Len += SK_STRLEN(KeyArr[Index]) + 1;
3609 return (SK_PNMI_ERR_TOO_SHORT);
3613 * Get the key to an intermediate buffer, because
3614 * we have to prepend a length byte.
3616 for (Offset = 0, Index = FirstIndex;
3617 Index < LastIndex; Index ++) {
3619 Len = SK_STRLEN(KeyArr[Index]);
3621 *(pBuf + Offset) = (char)Len;
3622 SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
3629 case OID_SKGE_VPD_VALUE:
3630 /* Check the buffer length if it is large enough */
3631 for (Offset = 0, Index = FirstIndex;
3632 Index < LastIndex; Index ++) {
3635 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3636 (int *)&BufLen) > 0 ||
3637 BufLen >= SK_PNMI_VPD_DATALEN) {
3639 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3643 return (SK_PNMI_ERR_GENERAL);
3645 Offset += BufLen + 1;
3647 if (*pLen < Offset) {
3650 return (SK_PNMI_ERR_TOO_SHORT);
3654 * Get the value to an intermediate buffer, because
3655 * we have to prepend a length byte.
3657 for (Offset = 0, Index = FirstIndex;
3658 Index < LastIndex; Index ++) {
3661 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3662 (int *)&BufLen) > 0 ||
3663 BufLen >= SK_PNMI_VPD_DATALEN) {
3665 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3670 return (SK_PNMI_ERR_GENERAL);
3673 *(pBuf + Offset) = (char)BufLen;
3674 SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
3675 Offset += BufLen + 1;
3680 case OID_SKGE_VPD_ACCESS:
3681 if (*pLen < LastIndex - FirstIndex) {
3683 *pLen = LastIndex - FirstIndex;
3684 return (SK_PNMI_ERR_TOO_SHORT);
3687 for (Offset = 0, Index = FirstIndex;
3688 Index < LastIndex; Index ++) {
3690 if (VpdMayWrite(KeyArr[Index])) {
3692 *(pBuf + Offset) = SK_PNMI_VPD_RW;
3695 *(pBuf + Offset) = SK_PNMI_VPD_RO;
3702 case OID_SKGE_VPD_ACTION:
3703 Offset = LastIndex - FirstIndex;
3704 if (*pLen < Offset) {
3707 return (SK_PNMI_ERR_TOO_SHORT);
3709 SK_MEMSET(pBuf, 0, Offset);
3714 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
3718 return (SK_PNMI_ERR_GENERAL);
3722 /* The only OID which can be set is VPD_ACTION */
3723 if (Id != OID_SKGE_VPD_ACTION) {
3725 if (Id == OID_SKGE_VPD_FREE_BYTES ||
3726 Id == OID_SKGE_VPD_ENTRIES_LIST ||
3727 Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
3728 Id == OID_SKGE_VPD_KEY ||
3729 Id == OID_SKGE_VPD_VALUE ||
3730 Id == OID_SKGE_VPD_ACCESS) {
3733 return (SK_PNMI_ERR_READ_ONLY);
3736 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
3740 return (SK_PNMI_ERR_GENERAL);
3744 * From this point we handle VPD_ACTION. Check the buffer
3745 * length. It should at least have the size of one byte.
3750 return (SK_PNMI_ERR_TOO_SHORT);
3754 * The first byte contains the VPD action type we should
3759 case SK_PNMI_VPD_IGNORE:
3763 case SK_PNMI_VPD_CREATE:
3765 * We have to create a new VPD entry or we modify
3766 * an existing one. Check first the buffer length.
3771 return (SK_PNMI_ERR_TOO_SHORT);
3773 KeyStr[0] = pBuf[1];
3774 KeyStr[1] = pBuf[2];
3778 * Is the entry writable or does it belong to the
3781 if (!VpdMayWrite(KeyStr)) {
3784 return (SK_PNMI_ERR_BAD_VALUE);
3787 Offset = (int)pBuf[3] & 0xFF;
3789 SK_MEMCPY(Buf, pBuf + 4, Offset);
3792 /* A preset ends here */
3793 if (Action == SK_PNMI_PRESET) {
3795 return (SK_PNMI_ERR_OK);
3798 /* Write the new entry or modify an existing one */
3799 Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
3800 if (Ret == SK_PNMI_VPD_NOWRITE ) {
3803 return (SK_PNMI_ERR_BAD_VALUE);
3805 else if (Ret != SK_PNMI_VPD_OK) {
3807 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
3811 return (SK_PNMI_ERR_GENERAL);
3815 * Perform an update of the VPD data. This is
3816 * not mandantory, but just to be sure.
3818 Ret = VpdUpdate(pAC, IoC);
3819 if (Ret != SK_PNMI_VPD_OK) {
3821 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
3825 return (SK_PNMI_ERR_GENERAL);
3829 case SK_PNMI_VPD_DELETE:
3830 /* Check if the buffer size is plausible */
3834 return (SK_PNMI_ERR_TOO_SHORT);
3839 return (SK_PNMI_ERR_BAD_VALUE);
3841 KeyStr[0] = pBuf[1];
3842 KeyStr[1] = pBuf[2];
3845 /* Find the passed key in the array */
3846 for (Index = 0; Index < KeyNo; Index ++) {
3848 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3854 * If we cannot find the key it is wrong, so we
3855 * return an appropriate error value.
3857 if (Index == KeyNo) {
3860 return (SK_PNMI_ERR_BAD_VALUE);
3863 if (Action == SK_PNMI_PRESET) {
3865 return (SK_PNMI_ERR_OK);
3868 /* Ok, you wanted it and you will get it */
3869 Ret = VpdDelete(pAC, IoC, KeyStr);
3870 if (Ret != SK_PNMI_VPD_OK) {
3872 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
3876 return (SK_PNMI_ERR_GENERAL);
3880 * Perform an update of the VPD data. This is
3881 * not mandantory, but just to be sure.
3883 Ret = VpdUpdate(pAC, IoC);
3884 if (Ret != SK_PNMI_VPD_OK) {
3886 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
3890 return (SK_PNMI_ERR_GENERAL);
3896 return (SK_PNMI_ERR_BAD_VALUE);
3900 return (SK_PNMI_ERR_OK);
3903 /*****************************************************************************
3905 * General - OID handler function of various single instance OIDs
3908 * The code is simple. No description necessary.
3911 * SK_PNMI_ERR_OK The request was successfully performed.
3912 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3913 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3914 * the correct data (e.g. a 32bit value is
3915 * needed, but a 16 bit value was passed).
3916 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3917 * exist (e.g. port instance 3 on a two port
3920 PNMI_STATIC int General(
3921 SK_AC *pAC, /* Pointer to adapter context */
3922 SK_IOC IoC, /* IO context handle */
3923 int Action, /* Get/PreSet/Set action */
3924 SK_U32 Id, /* Object ID that is to be processed */
3925 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
3926 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3927 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3928 unsigned int TableIndex, /* Index to the Id table */
3929 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
3934 unsigned int Offset;
3940 SK_U64 Val64RxHwErrs = 0;
3941 SK_U64 Val64TxHwErrs = 0;
3942 SK_BOOL Is64BitReq = SK_FALSE;
3947 * Check instance. We only handle single instance variables
3949 if (Instance != (SK_U32)(-1) && Instance != 1) {
3952 return (SK_PNMI_ERR_UNKNOWN_INST);
3956 * Check action. We only allow get requests.
3958 if (Action != SK_PNMI_GET) {
3961 return (SK_PNMI_ERR_READ_ONLY);
3964 MacType = pAC->GIni.GIMacType;
3967 * Check length for the various supported OIDs
3971 case OID_GEN_XMIT_ERROR:
3972 case OID_GEN_RCV_ERROR:
3973 case OID_GEN_RCV_NO_BUFFER:
3974 #ifndef SK_NDIS_64BIT_CTR
3975 if (*pLen < sizeof(SK_U32)) {
3976 *pLen = sizeof(SK_U32);
3977 return (SK_PNMI_ERR_TOO_SHORT);
3980 #else /* SK_NDIS_64BIT_CTR */
3983 * for compatibility, at least 32bit are required for oid
3985 if (*pLen < sizeof(SK_U32)) {
3987 * but indicate handling for 64bit values,
3988 * if insufficient space is provided
3990 *pLen = sizeof(SK_U64);
3991 return (SK_PNMI_ERR_TOO_SHORT);
3994 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
3995 #endif /* SK_NDIS_64BIT_CTR */
3998 case OID_SKGE_PORT_NUMBER:
3999 case OID_SKGE_DEVICE_TYPE:
4000 case OID_SKGE_RESULT:
4001 case OID_SKGE_RLMT_MONITOR_NUMBER:
4002 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
4003 case OID_SKGE_TRAP_NUMBER:
4004 case OID_SKGE_MDB_VERSION:
4005 if (*pLen < sizeof(SK_U32)) {
4007 *pLen = sizeof(SK_U32);
4008 return (SK_PNMI_ERR_TOO_SHORT);
4012 case OID_SKGE_CHIPSET:
4013 if (*pLen < sizeof(SK_U16)) {
4015 *pLen = sizeof(SK_U16);
4016 return (SK_PNMI_ERR_TOO_SHORT);
4020 case OID_SKGE_BUS_TYPE:
4021 case OID_SKGE_BUS_SPEED:
4022 case OID_SKGE_BUS_WIDTH:
4023 case OID_SKGE_SENSOR_NUMBER:
4024 case OID_SKGE_CHKSM_NUMBER:
4025 if (*pLen < sizeof(SK_U8)) {
4027 *pLen = sizeof(SK_U8);
4028 return (SK_PNMI_ERR_TOO_SHORT);
4032 case OID_SKGE_TX_SW_QUEUE_LEN:
4033 case OID_SKGE_TX_SW_QUEUE_MAX:
4034 case OID_SKGE_TX_RETRY:
4035 case OID_SKGE_RX_INTR_CTS:
4036 case OID_SKGE_TX_INTR_CTS:
4037 case OID_SKGE_RX_NO_BUF_CTS:
4038 case OID_SKGE_TX_NO_BUF_CTS:
4039 case OID_SKGE_TX_USED_DESCR_NO:
4040 case OID_SKGE_RX_DELIVERED_CTS:
4041 case OID_SKGE_RX_OCTETS_DELIV_CTS:
4042 case OID_SKGE_RX_HW_ERROR_CTS:
4043 case OID_SKGE_TX_HW_ERROR_CTS:
4044 case OID_SKGE_IN_ERRORS_CTS:
4045 case OID_SKGE_OUT_ERROR_CTS:
4046 case OID_SKGE_ERR_RECOVERY_CTS:
4047 case OID_SKGE_SYSUPTIME:
4048 if (*pLen < sizeof(SK_U64)) {
4050 *pLen = sizeof(SK_U64);
4051 return (SK_PNMI_ERR_TOO_SHORT);
4060 /* Update statistic */
4061 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
4062 Id == OID_SKGE_TX_HW_ERROR_CTS ||
4063 Id == OID_SKGE_IN_ERRORS_CTS ||
4064 Id == OID_SKGE_OUT_ERROR_CTS ||
4065 Id == OID_GEN_XMIT_ERROR ||
4066 Id == OID_GEN_RCV_ERROR) {
4068 /* Force the XMAC to update its statistic counters and
4069 * Increment semaphore to indicate that an update was
4072 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
4073 if (Ret != SK_PNMI_ERR_OK) {
4078 pAC->Pnmi.MacUpdatedFlag ++;
4081 * Some OIDs consist of multiple hardware counters. Those
4082 * values which are contained in all of them will be added
4087 case OID_SKGE_RX_HW_ERROR_CTS:
4088 case OID_SKGE_IN_ERRORS_CTS:
4089 case OID_GEN_RCV_ERROR:
4091 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
4092 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
4093 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex)+
4094 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
4095 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
4096 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex)+
4097 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
4098 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
4099 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
4100 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
4101 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
4102 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
4105 case OID_SKGE_TX_HW_ERROR_CTS:
4106 case OID_SKGE_OUT_ERROR_CTS:
4107 case OID_GEN_XMIT_ERROR:
4109 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
4110 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex)+
4111 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex)+
4112 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex);
4122 case OID_SKGE_SUPPORTED_LIST:
4123 Len = ID_TABLE_SIZE * sizeof(SK_U32);
4127 return (SK_PNMI_ERR_TOO_SHORT);
4129 for (Offset = 0, Index = 0; Offset < Len;
4130 Offset += sizeof(SK_U32), Index ++) {
4132 Val32 = (SK_U32)IdTable[Index].Id;
4133 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4138 case OID_SKGE_PORT_NUMBER:
4139 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
4140 SK_PNMI_STORE_U32(pBuf, Val32);
4141 *pLen = sizeof(SK_U32);
4144 case OID_SKGE_DEVICE_TYPE:
4145 Val32 = (SK_U32)pAC->Pnmi.DeviceType;
4146 SK_PNMI_STORE_U32(pBuf, Val32);
4147 *pLen = sizeof(SK_U32);
4150 case OID_SKGE_DRIVER_DESCR:
4151 if (pAC->Pnmi.pDriverDescription == NULL) {
4153 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
4157 return (SK_PNMI_ERR_GENERAL);
4160 Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
4161 if (Len > SK_PNMI_STRINGLEN1) {
4163 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
4167 return (SK_PNMI_ERR_GENERAL);
4173 return (SK_PNMI_ERR_TOO_SHORT);
4175 *pBuf = (char)(Len - 1);
4176 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
4180 case OID_SKGE_DRIVER_VERSION:
4181 if (pAC->Pnmi.pDriverVersion == NULL) {
4183 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
4187 return (SK_PNMI_ERR_GENERAL);
4190 Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
4191 if (Len > SK_PNMI_STRINGLEN1) {
4193 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
4197 return (SK_PNMI_ERR_GENERAL);
4203 return (SK_PNMI_ERR_TOO_SHORT);
4205 *pBuf = (char)(Len - 1);
4206 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
4210 case OID_SKGE_HW_DESCR:
4212 * The hardware description is located in the VPD. This
4213 * query may move to the initialisation routine. But
4214 * the VPD data is cached and therefore a call here
4215 * will not make much difference.
4218 if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
4220 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
4224 return (SK_PNMI_ERR_GENERAL);
4227 if (Len > SK_PNMI_STRINGLEN1) {
4229 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
4233 return (SK_PNMI_ERR_GENERAL);
4238 return (SK_PNMI_ERR_TOO_SHORT);
4240 *pBuf = (char)(Len - 1);
4241 SK_MEMCPY(pBuf + 1, Buf, Len - 1);
4245 case OID_SKGE_HW_VERSION:
4246 /* Oh, I love to do some string manipulation */
4250 return (SK_PNMI_ERR_TOO_SHORT);
4252 Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
4255 pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
4257 pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
4261 case OID_SKGE_CHIPSET:
4262 Val16 = pAC->Pnmi.Chipset;
4263 SK_PNMI_STORE_U16(pBuf, Val16);
4264 *pLen = sizeof(SK_U16);
4267 case OID_SKGE_BUS_TYPE:
4268 *pBuf = (char)SK_PNMI_BUS_PCI;
4269 *pLen = sizeof(char);
4272 case OID_SKGE_BUS_SPEED:
4273 *pBuf = pAC->Pnmi.PciBusSpeed;
4274 *pLen = sizeof(char);
4277 case OID_SKGE_BUS_WIDTH:
4278 *pBuf = pAC->Pnmi.PciBusWidth;
4279 *pLen = sizeof(char);
4282 case OID_SKGE_RESULT:
4283 Val32 = pAC->Pnmi.TestResult;
4284 SK_PNMI_STORE_U32(pBuf, Val32);
4285 *pLen = sizeof(SK_U32);
4288 case OID_SKGE_SENSOR_NUMBER:
4289 *pBuf = (char)pAC->I2c.MaxSens;
4290 *pLen = sizeof(char);
4293 case OID_SKGE_CHKSM_NUMBER:
4294 *pBuf = SKCS_NUM_PROTOCOLS;
4295 *pLen = sizeof(char);
4298 case OID_SKGE_TRAP_NUMBER:
4299 GetTrapQueueLen(pAC, &Len, &Val);
4300 Val32 = (SK_U32)Val;
4301 SK_PNMI_STORE_U32(pBuf, Val32);
4302 *pLen = sizeof(SK_U32);
4306 GetTrapQueueLen(pAC, &Len, &Val);
4310 return (SK_PNMI_ERR_TOO_SHORT);
4312 CopyTrapQueue(pAC, pBuf);
4316 case OID_SKGE_RLMT_MONITOR_NUMBER:
4317 /* XXX Not yet implemented by RLMT therefore we return zero elements */
4319 SK_PNMI_STORE_U32(pBuf, Val32);
4320 *pLen = sizeof(SK_U32);
4323 case OID_SKGE_TX_SW_QUEUE_LEN:
4324 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4325 if (MacType == SK_MAC_XMAC) {
4327 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4328 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
4330 /* Single net mode */
4332 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
4333 pAC->Pnmi.BufPort[1].TxSwQueueLen;
4338 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4339 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
4341 /* Single net mode */
4343 Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
4344 pAC->Pnmi.Port[1].TxSwQueueLen;
4347 SK_PNMI_STORE_U64(pBuf, Val64);
4348 *pLen = sizeof(SK_U64);
4352 case OID_SKGE_TX_SW_QUEUE_MAX:
4353 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4354 if (MacType == SK_MAC_XMAC) {
4356 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4357 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
4359 /* Single net mode */
4361 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
4362 pAC->Pnmi.BufPort[1].TxSwQueueMax;
4367 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4368 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
4370 /* Single net mode */
4372 Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
4373 pAC->Pnmi.Port[1].TxSwQueueMax;
4376 SK_PNMI_STORE_U64(pBuf, Val64);
4377 *pLen = sizeof(SK_U64);
4380 case OID_SKGE_TX_RETRY:
4381 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4382 if (MacType == SK_MAC_XMAC) {
4384 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4385 Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
4387 /* Single net mode */
4389 Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
4390 pAC->Pnmi.BufPort[1].TxRetryCts;
4395 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4396 Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
4398 /* Single net mode */
4400 Val64 = pAC->Pnmi.Port[0].TxRetryCts +
4401 pAC->Pnmi.Port[1].TxRetryCts;
4404 SK_PNMI_STORE_U64(pBuf, Val64);
4405 *pLen = sizeof(SK_U64);
4408 case OID_SKGE_RX_INTR_CTS:
4409 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4410 if (MacType == SK_MAC_XMAC) {
4412 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4413 Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
4415 /* Single net mode */
4417 Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
4418 pAC->Pnmi.BufPort[1].RxIntrCts;
4423 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4424 Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
4426 /* Single net mode */
4428 Val64 = pAC->Pnmi.Port[0].RxIntrCts +
4429 pAC->Pnmi.Port[1].RxIntrCts;
4432 SK_PNMI_STORE_U64(pBuf, Val64);
4433 *pLen = sizeof(SK_U64);
4436 case OID_SKGE_TX_INTR_CTS:
4437 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4438 if (MacType == SK_MAC_XMAC) {
4440 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4441 Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
4443 /* Single net mode */
4445 Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
4446 pAC->Pnmi.BufPort[1].TxIntrCts;
4451 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4452 Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
4454 /* Single net mode */
4456 Val64 = pAC->Pnmi.Port[0].TxIntrCts +
4457 pAC->Pnmi.Port[1].TxIntrCts;
4460 SK_PNMI_STORE_U64(pBuf, Val64);
4461 *pLen = sizeof(SK_U64);
4464 case OID_SKGE_RX_NO_BUF_CTS:
4465 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4466 if (MacType == SK_MAC_XMAC) {
4468 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4469 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4471 /* Single net mode */
4473 Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
4474 pAC->Pnmi.BufPort[1].RxNoBufCts;
4479 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4480 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4482 /* Single net mode */
4484 Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
4485 pAC->Pnmi.Port[1].RxNoBufCts;
4488 SK_PNMI_STORE_U64(pBuf, Val64);
4489 *pLen = sizeof(SK_U64);
4492 case OID_SKGE_TX_NO_BUF_CTS:
4493 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4494 if (MacType == SK_MAC_XMAC) {
4496 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4497 Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4499 /* Single net mode */
4501 Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
4502 pAC->Pnmi.BufPort[1].TxNoBufCts;
4507 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4508 Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4510 /* Single net mode */
4512 Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
4513 pAC->Pnmi.Port[1].TxNoBufCts;
4516 SK_PNMI_STORE_U64(pBuf, Val64);
4517 *pLen = sizeof(SK_U64);
4520 case OID_SKGE_TX_USED_DESCR_NO:
4521 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4522 if (MacType == SK_MAC_XMAC) {
4524 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4525 Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
4527 /* Single net mode */
4529 Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
4530 pAC->Pnmi.BufPort[1].TxUsedDescrNo;
4535 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4536 Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
4538 /* Single net mode */
4540 Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
4541 pAC->Pnmi.Port[1].TxUsedDescrNo;
4544 SK_PNMI_STORE_U64(pBuf, Val64);
4545 *pLen = sizeof(SK_U64);
4548 case OID_SKGE_RX_DELIVERED_CTS:
4549 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4550 if (MacType == SK_MAC_XMAC) {
4552 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4553 Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
4555 /* Single net mode */
4557 Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
4558 pAC->Pnmi.BufPort[1].RxDeliveredCts;
4563 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4564 Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
4566 /* Single net mode */
4568 Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
4569 pAC->Pnmi.Port[1].RxDeliveredCts;
4572 SK_PNMI_STORE_U64(pBuf, Val64);
4573 *pLen = sizeof(SK_U64);
4576 case OID_SKGE_RX_OCTETS_DELIV_CTS:
4577 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4578 if (MacType == SK_MAC_XMAC) {
4580 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4581 Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
4583 /* Single net mode */
4585 Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
4586 pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
4591 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4592 Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
4594 /* Single net mode */
4596 Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
4597 pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
4600 SK_PNMI_STORE_U64(pBuf, Val64);
4601 *pLen = sizeof(SK_U64);
4604 case OID_SKGE_RX_HW_ERROR_CTS:
4605 SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
4606 *pLen = sizeof(SK_U64);
4609 case OID_SKGE_TX_HW_ERROR_CTS:
4610 SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
4611 *pLen = sizeof(SK_U64);
4614 case OID_SKGE_IN_ERRORS_CTS:
4615 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4616 if (MacType == SK_MAC_XMAC) {
4618 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4619 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4621 /* Single net mode */
4623 Val64 = Val64RxHwErrs +
4624 pAC->Pnmi.BufPort[0].RxNoBufCts +
4625 pAC->Pnmi.BufPort[1].RxNoBufCts;
4630 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4631 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4633 /* Single net mode */
4635 Val64 = Val64RxHwErrs +
4636 pAC->Pnmi.Port[0].RxNoBufCts +
4637 pAC->Pnmi.Port[1].RxNoBufCts;
4640 SK_PNMI_STORE_U64(pBuf, Val64);
4641 *pLen = sizeof(SK_U64);
4644 case OID_SKGE_OUT_ERROR_CTS:
4645 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4646 if (MacType == SK_MAC_XMAC) {
4648 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4649 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4651 /* Single net mode */
4653 Val64 = Val64TxHwErrs +
4654 pAC->Pnmi.BufPort[0].TxNoBufCts +
4655 pAC->Pnmi.BufPort[1].TxNoBufCts;
4660 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4661 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4663 /* Single net mode */
4665 Val64 = Val64TxHwErrs +
4666 pAC->Pnmi.Port[0].TxNoBufCts +
4667 pAC->Pnmi.Port[1].TxNoBufCts;
4670 SK_PNMI_STORE_U64(pBuf, Val64);
4671 *pLen = sizeof(SK_U64);
4674 case OID_SKGE_ERR_RECOVERY_CTS:
4675 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4676 if (MacType == SK_MAC_XMAC) {
4678 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4679 Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
4681 /* Single net mode */
4683 Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
4684 pAC->Pnmi.BufPort[1].ErrRecoveryCts;
4689 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4690 Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
4692 /* Single net mode */
4694 Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
4695 pAC->Pnmi.Port[1].ErrRecoveryCts;
4698 SK_PNMI_STORE_U64(pBuf, Val64);
4699 *pLen = sizeof(SK_U64);
4702 case OID_SKGE_SYSUPTIME:
4703 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
4704 Val64 -= pAC->Pnmi.StartUpTime;
4705 SK_PNMI_STORE_U64(pBuf, Val64);
4706 *pLen = sizeof(SK_U64);
4709 case OID_SKGE_MDB_VERSION:
4710 Val32 = SK_PNMI_MDB_VERSION;
4711 SK_PNMI_STORE_U32(pBuf, Val32);
4712 *pLen = sizeof(SK_U32);
4715 case OID_GEN_RCV_ERROR:
4716 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4717 if (MacType == SK_MAC_XMAC) {
4718 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4721 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4725 * by default 32bit values are evaluated
4728 Val32 = (SK_U32)Val64;
4729 SK_PNMI_STORE_U32(pBuf, Val32);
4730 *pLen = sizeof(SK_U32);
4733 SK_PNMI_STORE_U64(pBuf, Val64);
4734 *pLen = sizeof(SK_U64);
4738 case OID_GEN_XMIT_ERROR:
4739 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4740 if (MacType == SK_MAC_XMAC) {
4741 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4744 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4748 * by default 32bit values are evaluated
4751 Val32 = (SK_U32)Val64;
4752 SK_PNMI_STORE_U32(pBuf, Val32);
4753 *pLen = sizeof(SK_U32);
4756 SK_PNMI_STORE_U64(pBuf, Val64);
4757 *pLen = sizeof(SK_U64);
4761 case OID_GEN_RCV_NO_BUFFER:
4762 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4763 if (MacType == SK_MAC_XMAC) {
4764 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4767 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4771 * by default 32bit values are evaluated
4774 Val32 = (SK_U32)Val64;
4775 SK_PNMI_STORE_U32(pBuf, Val32);
4776 *pLen = sizeof(SK_U32);
4779 SK_PNMI_STORE_U64(pBuf, Val64);
4780 *pLen = sizeof(SK_U64);
4784 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
4785 Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
4786 SK_PNMI_STORE_U32(pBuf, Val32);
4787 *pLen = sizeof(SK_U32);
4791 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
4795 return (SK_PNMI_ERR_GENERAL);
4798 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
4799 Id == OID_SKGE_TX_HW_ERROR_CTS ||
4800 Id == OID_SKGE_IN_ERRORS_CTS ||
4801 Id == OID_SKGE_OUT_ERROR_CTS ||
4802 Id == OID_GEN_XMIT_ERROR ||
4803 Id == OID_GEN_RCV_ERROR) {
4805 pAC->Pnmi.MacUpdatedFlag --;
4808 return (SK_PNMI_ERR_OK);
4811 /*****************************************************************************
4813 * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
4816 * Get/Presets/Sets the RLMT OIDs.
4819 * SK_PNMI_ERR_OK The request was successfully performed.
4820 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4821 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4822 * the correct data (e.g. a 32bit value is
4823 * needed, but a 16 bit value was passed).
4824 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
4826 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
4827 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4828 * exist (e.g. port instance 3 on a two port
4831 PNMI_STATIC int Rlmt(
4832 SK_AC *pAC, /* Pointer to adapter context */
4833 SK_IOC IoC, /* IO context handle */
4834 int Action, /* Get/PreSet/Set action */
4835 SK_U32 Id, /* Object ID that is to be processed */
4836 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
4837 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
4838 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4839 unsigned int TableIndex, /* Index to the Id table */
4840 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
4843 unsigned int PhysPortIndex;
4844 unsigned int PhysPortMax;
4845 SK_EVPARA EventParam;
4851 * Check instance. Only single instance OIDs are allowed here.
4853 if (Instance != (SK_U32)(-1) && Instance != 1) {
4856 return (SK_PNMI_ERR_UNKNOWN_INST);
4860 * Perform the requested action
4862 if (Action == SK_PNMI_GET) {
4865 * Check if the buffer length is large enough.
4870 case OID_SKGE_RLMT_MODE:
4871 case OID_SKGE_RLMT_PORT_ACTIVE:
4872 case OID_SKGE_RLMT_PORT_PREFERRED:
4873 if (*pLen < sizeof(SK_U8)) {
4875 *pLen = sizeof(SK_U8);
4876 return (SK_PNMI_ERR_TOO_SHORT);
4880 case OID_SKGE_RLMT_PORT_NUMBER:
4881 if (*pLen < sizeof(SK_U32)) {
4883 *pLen = sizeof(SK_U32);
4884 return (SK_PNMI_ERR_TOO_SHORT);
4888 case OID_SKGE_RLMT_CHANGE_CTS:
4889 case OID_SKGE_RLMT_CHANGE_TIME:
4890 case OID_SKGE_RLMT_CHANGE_ESTIM:
4891 case OID_SKGE_RLMT_CHANGE_THRES:
4892 if (*pLen < sizeof(SK_U64)) {
4894 *pLen = sizeof(SK_U64);
4895 return (SK_PNMI_ERR_TOO_SHORT);
4900 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
4904 return (SK_PNMI_ERR_GENERAL);
4908 * Update RLMT statistic and increment semaphores to indicate
4909 * that an update was already done. Maybe RLMT will hold its
4910 * statistic always up to date some time. Then we can
4911 * remove this type of call.
4913 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4918 pAC->Pnmi.RlmtUpdatedFlag ++;
4925 case OID_SKGE_RLMT_MODE:
4926 *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
4927 *pLen = sizeof(char);
4930 case OID_SKGE_RLMT_PORT_NUMBER:
4931 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
4932 SK_PNMI_STORE_U32(pBuf, Val32);
4933 *pLen = sizeof(SK_U32);
4936 case OID_SKGE_RLMT_PORT_ACTIVE:
4939 * If multiple ports may become active this OID
4940 * doesn't make sense any more. A new variable in
4941 * the port structure should be created. However,
4942 * for this variable the first active port is
4945 PhysPortMax = pAC->GIni.GIMacsFound;
4947 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
4950 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4952 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
4956 *pLen = sizeof(char);
4959 case OID_SKGE_RLMT_PORT_PREFERRED:
4960 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
4961 *pLen = sizeof(char);
4964 case OID_SKGE_RLMT_CHANGE_CTS:
4965 Val64 = pAC->Pnmi.RlmtChangeCts;
4966 SK_PNMI_STORE_U64(pBuf, Val64);
4967 *pLen = sizeof(SK_U64);
4970 case OID_SKGE_RLMT_CHANGE_TIME:
4971 Val64 = pAC->Pnmi.RlmtChangeTime;
4972 SK_PNMI_STORE_U64(pBuf, Val64);
4973 *pLen = sizeof(SK_U64);
4976 case OID_SKGE_RLMT_CHANGE_ESTIM:
4977 Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
4978 SK_PNMI_STORE_U64(pBuf, Val64);
4979 *pLen = sizeof(SK_U64);
4982 case OID_SKGE_RLMT_CHANGE_THRES:
4983 Val64 = pAC->Pnmi.RlmtChangeThreshold;
4984 SK_PNMI_STORE_U64(pBuf, Val64);
4985 *pLen = sizeof(SK_U64);
4989 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
4990 ("Rlmt: Unknown OID should be handled before"));
4992 pAC->Pnmi.RlmtUpdatedFlag --;
4994 return (SK_PNMI_ERR_GENERAL);
4997 pAC->Pnmi.RlmtUpdatedFlag --;
5000 /* Perform a preset or set */
5003 case OID_SKGE_RLMT_MODE:
5004 /* Check if the buffer length is plausible */
5005 if (*pLen < sizeof(char)) {
5007 *pLen = sizeof(char);
5008 return (SK_PNMI_ERR_TOO_SHORT);
5010 /* Check if the value range is correct */
5011 if (*pLen != sizeof(char) ||
5012 (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
5013 *(SK_U8 *)pBuf > 15) {
5016 return (SK_PNMI_ERR_BAD_VALUE);
5018 /* The preset ends here */
5019 if (Action == SK_PNMI_PRESET) {
5022 return (SK_PNMI_ERR_OK);
5024 /* Send an event to RLMT to change the mode */
5025 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
5026 EventParam.Para32[0] |= (SK_U32)(*pBuf);
5027 EventParam.Para32[1] = 0;
5028 if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
5031 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
5035 return (SK_PNMI_ERR_GENERAL);
5039 case OID_SKGE_RLMT_PORT_PREFERRED:
5040 /* Check if the buffer length is plausible */
5041 if (*pLen < sizeof(char)) {
5043 *pLen = sizeof(char);
5044 return (SK_PNMI_ERR_TOO_SHORT);
5046 /* Check if the value range is correct */
5047 if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
5048 (SK_U8)pAC->GIni.GIMacsFound) {
5051 return (SK_PNMI_ERR_BAD_VALUE);
5053 /* The preset ends here */
5054 if (Action == SK_PNMI_PRESET) {
5057 return (SK_PNMI_ERR_OK);
5061 * Send an event to RLMT change the preferred port.
5062 * A param of -1 means automatic mode. RLMT will
5063 * make the decision which is the preferred port.
5065 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
5066 EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
5067 EventParam.Para32[1] = NetIndex;
5068 if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
5071 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
5075 return (SK_PNMI_ERR_GENERAL);
5079 case OID_SKGE_RLMT_CHANGE_THRES:
5080 /* Check if the buffer length is plausible */
5081 if (*pLen < sizeof(SK_U64)) {
5083 *pLen = sizeof(SK_U64);
5084 return (SK_PNMI_ERR_TOO_SHORT);
5087 * There are not many restrictions to the
5090 if (*pLen != sizeof(SK_U64)) {
5093 return (SK_PNMI_ERR_BAD_VALUE);
5095 /* A preset ends here */
5096 if (Action == SK_PNMI_PRESET) {
5099 return (SK_PNMI_ERR_OK);
5102 * Store the new threshold, which will be taken
5103 * on the next timer event.
5105 SK_PNMI_READ_U64(pBuf, Val64);
5106 pAC->Pnmi.RlmtChangeThreshold = Val64;
5110 /* The other OIDs are not be able for set */
5112 return (SK_PNMI_ERR_READ_ONLY);
5116 return (SK_PNMI_ERR_OK);
5119 /*****************************************************************************
5121 * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
5124 * Performs get requests on multiple instance variables.
5127 * SK_PNMI_ERR_OK The request was successfully performed.
5128 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
5129 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
5130 * the correct data (e.g. a 32bit value is
5131 * needed, but a 16 bit value was passed).
5132 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
5133 * exist (e.g. port instance 3 on a two port
5136 PNMI_STATIC int RlmtStat(
5137 SK_AC *pAC, /* Pointer to adapter context */
5138 SK_IOC IoC, /* IO context handle */
5139 int Action, /* Get/PreSet/Set action */
5140 SK_U32 Id, /* Object ID that is to be processed */
5141 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
5142 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
5143 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5144 unsigned int TableIndex, /* Index to the Id table */
5145 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
5147 unsigned int PhysPortMax;
5148 unsigned int PhysPortIndex;
5150 unsigned int Offset;
5156 * Calculate the port indexes from the instance
5158 PhysPortMax = pAC->GIni.GIMacsFound;
5160 if ((Instance != (SK_U32)(-1))) {
5161 /* Check instance range */
5162 if ((Instance < 1) || (Instance > PhysPortMax)) {
5165 return (SK_PNMI_ERR_UNKNOWN_INST);
5168 /* Single net mode */
5169 PhysPortIndex = Instance - 1;
5172 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
5173 PhysPortIndex = NetIndex;
5176 /* Both net modes */
5177 Limit = PhysPortIndex + 1;
5180 /* Single net mode */
5182 Limit = PhysPortMax;
5185 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
5186 PhysPortIndex = NetIndex;
5187 Limit = PhysPortIndex + 1;
5192 * Currently only get requests are allowed.
5194 if (Action != SK_PNMI_GET) {
5197 return (SK_PNMI_ERR_READ_ONLY);
5201 * Check if the buffer length is large enough.
5205 case OID_SKGE_RLMT_PORT_INDEX:
5206 case OID_SKGE_RLMT_STATUS:
5207 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
5209 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
5210 return (SK_PNMI_ERR_TOO_SHORT);
5214 case OID_SKGE_RLMT_TX_HELLO_CTS:
5215 case OID_SKGE_RLMT_RX_HELLO_CTS:
5216 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
5217 case OID_SKGE_RLMT_RX_SP_CTS:
5218 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
5220 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
5221 return (SK_PNMI_ERR_TOO_SHORT);
5226 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
5230 return (SK_PNMI_ERR_GENERAL);
5235 * Update statistic and increment semaphores to indicate that
5236 * an update was already done.
5238 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
5243 pAC->Pnmi.RlmtUpdatedFlag ++;
5249 for (; PhysPortIndex < Limit; PhysPortIndex ++) {
5253 case OID_SKGE_RLMT_PORT_INDEX:
5254 Val32 = PhysPortIndex;
5255 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
5256 Offset += sizeof(SK_U32);
5259 case OID_SKGE_RLMT_STATUS:
5260 if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
5262 pAC->Rlmt.Port[PhysPortIndex].PortState ==
5265 Val32 = SK_PNMI_RLMT_STATUS_ERROR;
5267 else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
5269 Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
5272 Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
5274 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
5275 Offset += sizeof(SK_U32);
5278 case OID_SKGE_RLMT_TX_HELLO_CTS:
5279 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
5280 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5281 Offset += sizeof(SK_U64);
5284 case OID_SKGE_RLMT_RX_HELLO_CTS:
5285 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
5286 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5287 Offset += sizeof(SK_U64);
5290 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
5291 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
5292 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5293 Offset += sizeof(SK_U64);
5296 case OID_SKGE_RLMT_RX_SP_CTS:
5297 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
5298 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5299 Offset += sizeof(SK_U64);
5303 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5304 ("RlmtStat: Unknown OID should be errored before"));
5306 pAC->Pnmi.RlmtUpdatedFlag --;
5308 return (SK_PNMI_ERR_GENERAL);
5313 pAC->Pnmi.RlmtUpdatedFlag --;
5315 return (SK_PNMI_ERR_OK);
5318 /*****************************************************************************
5320 * MacPrivateConf - OID handler function of OIDs concerning the configuration
5323 * Get/Presets/Sets the OIDs concerning the configuration.
5326 * SK_PNMI_ERR_OK The request was successfully performed.
5327 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
5328 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
5329 * the correct data (e.g. a 32bit value is
5330 * needed, but a 16 bit value was passed).
5331 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
5333 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
5334 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
5335 * exist (e.g. port instance 3 on a two port
5338 PNMI_STATIC int MacPrivateConf(
5339 SK_AC *pAC, /* Pointer to adapter context */
5340 SK_IOC IoC, /* IO context handle */
5341 int Action, /* Get/PreSet/Set action */
5342 SK_U32 Id, /* Object ID that is to be processed */
5343 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
5344 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
5345 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5346 unsigned int TableIndex, /* Index to the Id table */
5347 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
5349 unsigned int PhysPortMax;
5350 unsigned int PhysPortIndex;
5351 unsigned int LogPortMax;
5352 unsigned int LogPortIndex;
5354 unsigned int Offset;
5357 SK_EVPARA EventParam;
5362 * Calculate instance if wished. MAC index 0 is the virtual
5365 PhysPortMax = pAC->GIni.GIMacsFound;
5366 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
5368 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
5372 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
5373 /* Check instance range */
5374 if ((Instance < 1) || (Instance > LogPortMax)) {
5377 return (SK_PNMI_ERR_UNKNOWN_INST);
5379 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
5380 Limit = LogPortIndex + 1;
5383 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
5392 if (Action == SK_PNMI_GET) {
5400 case OID_SKGE_CONNECTOR:
5401 case OID_SKGE_LINK_CAP:
5402 case OID_SKGE_LINK_MODE:
5403 case OID_SKGE_LINK_MODE_STATUS:
5404 case OID_SKGE_LINK_STATUS:
5405 case OID_SKGE_FLOWCTRL_CAP:
5406 case OID_SKGE_FLOWCTRL_MODE:
5407 case OID_SKGE_FLOWCTRL_STATUS:
5408 case OID_SKGE_PHY_OPERATION_CAP:
5409 case OID_SKGE_PHY_OPERATION_MODE:
5410 case OID_SKGE_PHY_OPERATION_STATUS:
5411 case OID_SKGE_SPEED_CAP:
5412 case OID_SKGE_SPEED_MODE:
5413 case OID_SKGE_SPEED_STATUS:
5414 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
5416 *pLen = (Limit - LogPortIndex) *
5418 return (SK_PNMI_ERR_TOO_SHORT);
5423 if (*pLen < sizeof(SK_U32)) {
5425 *pLen = sizeof(SK_U32);
5426 return (SK_PNMI_ERR_TOO_SHORT);
5431 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
5434 return (SK_PNMI_ERR_GENERAL);
5438 * Update statistic and increment semaphore to indicate
5439 * that an update was already done.
5441 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
5446 pAC->Pnmi.SirqUpdatedFlag ++;
5452 for (; LogPortIndex < Limit; LogPortIndex ++) {
5457 *(pBuf + Offset) = pAC->Pnmi.PMD;
5458 Offset += sizeof(char);
5461 case OID_SKGE_CONNECTOR:
5462 *(pBuf + Offset) = pAC->Pnmi.Connector;
5463 Offset += sizeof(char);
5466 case OID_SKGE_LINK_CAP:
5467 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5468 if (LogPortIndex == 0) {
5470 /* Get value for virtual port */
5471 VirtualConf(pAC, IoC, Id, pBuf +
5475 /* Get value for physical ports */
5476 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5479 *(pBuf + Offset) = pAC->GIni.GP[
5480 PhysPortIndex].PLinkCap;
5482 Offset += sizeof(char);
5484 else { /* DualNetMode */
5486 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkCap;
5487 Offset += sizeof(char);
5491 case OID_SKGE_LINK_MODE:
5492 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5493 if (LogPortIndex == 0) {
5495 /* Get value for virtual port */
5496 VirtualConf(pAC, IoC, Id, pBuf +
5500 /* Get value for physical ports */
5501 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5504 *(pBuf + Offset) = pAC->GIni.GP[
5505 PhysPortIndex].PLinkModeConf;
5507 Offset += sizeof(char);
5509 else { /* DualNetMode */
5511 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkModeConf;
5512 Offset += sizeof(char);
5516 case OID_SKGE_LINK_MODE_STATUS:
5517 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5518 if (LogPortIndex == 0) {
5520 /* Get value for virtual port */
5521 VirtualConf(pAC, IoC, Id, pBuf +
5525 /* Get value for physical port */
5526 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5530 CalculateLinkModeStatus(pAC,
5531 IoC, PhysPortIndex);
5533 Offset += sizeof(char);
5535 else { /* DualNetMode */
5536 *(pBuf + Offset) = CalculateLinkModeStatus(pAC, IoC, NetIndex);
5537 Offset += sizeof(char);
5541 case OID_SKGE_LINK_STATUS:
5542 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5543 if (LogPortIndex == 0) {
5545 /* Get value for virtual port */
5546 VirtualConf(pAC, IoC, Id, pBuf +
5550 /* Get value for physical ports */
5551 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5555 CalculateLinkStatus(pAC,
5556 IoC, PhysPortIndex);
5558 Offset += sizeof(char);
5560 else { /* DualNetMode */
5562 *(pBuf + Offset) = CalculateLinkStatus(pAC, IoC, NetIndex);
5563 Offset += sizeof(char);
5567 case OID_SKGE_FLOWCTRL_CAP:
5568 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5569 if (LogPortIndex == 0) {
5571 /* Get value for virtual port */
5572 VirtualConf(pAC, IoC, Id, pBuf +
5576 /* Get value for physical ports */
5577 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5580 *(pBuf + Offset) = pAC->GIni.GP[
5581 PhysPortIndex].PFlowCtrlCap;
5583 Offset += sizeof(char);
5585 else { /* DualNetMode */
5587 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
5588 Offset += sizeof(char);
5592 case OID_SKGE_FLOWCTRL_MODE:
5593 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5594 if (LogPortIndex == 0) {
5596 /* Get value for virtual port */
5597 VirtualConf(pAC, IoC, Id, pBuf +
5601 /* Get value for physical port */
5602 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5605 *(pBuf + Offset) = pAC->GIni.GP[
5606 PhysPortIndex].PFlowCtrlMode;
5608 Offset += sizeof(char);
5610 else { /* DualNetMode */
5612 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
5613 Offset += sizeof(char);
5617 case OID_SKGE_FLOWCTRL_STATUS:
5618 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5619 if (LogPortIndex == 0) {
5621 /* Get value for virtual port */
5622 VirtualConf(pAC, IoC, Id, pBuf +
5626 /* Get value for physical port */
5627 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5630 *(pBuf + Offset) = pAC->GIni.GP[
5631 PhysPortIndex].PFlowCtrlStatus;
5633 Offset += sizeof(char);
5635 else { /* DualNetMode */
5637 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
5638 Offset += sizeof(char);
5642 case OID_SKGE_PHY_OPERATION_CAP:
5643 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5644 if (LogPortIndex == 0) {
5646 /* Get value for virtual port */
5647 VirtualConf(pAC, IoC, Id, pBuf +
5651 /* Get value for physical ports */
5652 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5655 *(pBuf + Offset) = pAC->GIni.GP[
5656 PhysPortIndex].PMSCap;
5658 Offset += sizeof(char);
5660 else { /* DualNetMode */
5662 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSCap;
5663 Offset += sizeof(char);
5667 case OID_SKGE_PHY_OPERATION_MODE:
5668 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5669 if (LogPortIndex == 0) {
5671 /* Get value for virtual port */
5672 VirtualConf(pAC, IoC, Id, pBuf + Offset);
5675 /* Get value for physical port */
5676 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5679 *(pBuf + Offset) = pAC->GIni.GP[
5680 PhysPortIndex].PMSMode;
5682 Offset += sizeof(char);
5684 else { /* DualNetMode */
5686 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSMode;
5687 Offset += sizeof(char);
5691 case OID_SKGE_PHY_OPERATION_STATUS:
5692 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5693 if (LogPortIndex == 0) {
5695 /* Get value for virtual port */
5696 VirtualConf(pAC, IoC, Id, pBuf + Offset);
5699 /* Get value for physical port */
5700 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5703 *(pBuf + Offset) = pAC->GIni.GP[
5704 PhysPortIndex].PMSStatus;
5706 Offset += sizeof(char);
5710 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSStatus;
5711 Offset += sizeof(char);
5715 case OID_SKGE_SPEED_CAP:
5716 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5717 if (LogPortIndex == 0) {
5719 /* Get value for virtual port */
5720 VirtualConf(pAC, IoC, Id, pBuf +
5724 /* Get value for physical ports */
5725 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5728 *(pBuf + Offset) = pAC->GIni.GP[
5729 PhysPortIndex].PLinkSpeedCap;
5731 Offset += sizeof(char);
5733 else { /* DualNetMode */
5735 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
5736 Offset += sizeof(char);
5740 case OID_SKGE_SPEED_MODE:
5741 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5742 if (LogPortIndex == 0) {
5744 /* Get value for virtual port */
5745 VirtualConf(pAC, IoC, Id, pBuf + Offset);
5748 /* Get value for physical port */
5749 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5752 *(pBuf + Offset) = pAC->GIni.GP[
5753 PhysPortIndex].PLinkSpeed;
5755 Offset += sizeof(char);
5757 else { /* DualNetMode */
5759 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeed;
5760 Offset += sizeof(char);
5764 case OID_SKGE_SPEED_STATUS:
5765 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5766 if (LogPortIndex == 0) {
5768 /* Get value for virtual port */
5769 VirtualConf(pAC, IoC, Id, pBuf + Offset);
5772 /* Get value for physical port */
5773 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5776 *(pBuf + Offset) = pAC->GIni.GP[
5777 PhysPortIndex].PLinkSpeedUsed;
5779 Offset += sizeof(char);
5781 else { /* DualNetMode */
5783 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
5784 Offset += sizeof(char);
5789 Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
5790 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
5791 Offset += sizeof(SK_U32);
5795 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5796 ("MacPrivateConf: Unknown OID should be handled before"));
5798 pAC->Pnmi.SirqUpdatedFlag --;
5799 return (SK_PNMI_ERR_GENERAL);
5803 pAC->Pnmi.SirqUpdatedFlag --;
5805 return (SK_PNMI_ERR_OK);
5809 * From here SET or PRESET action. Check if the passed
5810 * buffer length is plausible.
5814 case OID_SKGE_LINK_MODE:
5815 case OID_SKGE_FLOWCTRL_MODE:
5816 case OID_SKGE_PHY_OPERATION_MODE:
5817 case OID_SKGE_SPEED_MODE:
5818 if (*pLen < Limit - LogPortIndex) {
5820 *pLen = Limit - LogPortIndex;
5821 return (SK_PNMI_ERR_TOO_SHORT);
5823 if (*pLen != Limit - LogPortIndex) {
5826 return (SK_PNMI_ERR_BAD_VALUE);
5831 if (*pLen < sizeof(SK_U32)) {
5833 *pLen = sizeof(SK_U32);
5834 return (SK_PNMI_ERR_TOO_SHORT);
5836 if (*pLen != sizeof(SK_U32)) {
5839 return (SK_PNMI_ERR_BAD_VALUE);
5845 return (SK_PNMI_ERR_READ_ONLY);
5849 * Perform preset or set
5852 for (; LogPortIndex < Limit; LogPortIndex ++) {
5856 case OID_SKGE_LINK_MODE:
5857 /* Check the value range */
5858 Val8 = *(pBuf + Offset);
5861 Offset += sizeof(char);
5864 if (Val8 < SK_LMODE_HALF ||
5865 (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
5866 (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
5869 return (SK_PNMI_ERR_BAD_VALUE);
5872 /* The preset ends here */
5873 if (Action == SK_PNMI_PRESET) {
5875 return (SK_PNMI_ERR_OK);
5878 if (LogPortIndex == 0) {
5881 * The virtual port consists of all currently
5882 * active ports. Find them and send an event
5883 * with the new link mode to SIRQ.
5885 for (PhysPortIndex = 0;
5886 PhysPortIndex < PhysPortMax;
5889 if (!pAC->Pnmi.Port[PhysPortIndex].
5895 EventParam.Para32[0] = PhysPortIndex;
5896 EventParam.Para32[1] = (SK_U32)Val8;
5897 if (SkGeSirqEvent(pAC, IoC,
5901 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5906 return (SK_PNMI_ERR_GENERAL);
5912 * Send an event with the new link mode to
5915 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5917 EventParam.Para32[1] = (SK_U32)Val8;
5918 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
5921 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5926 return (SK_PNMI_ERR_GENERAL);
5929 Offset += sizeof(char);
5932 case OID_SKGE_FLOWCTRL_MODE:
5933 /* Check the value range */
5934 Val8 = *(pBuf + Offset);
5937 Offset += sizeof(char);
5940 if (Val8 < SK_FLOW_MODE_NONE ||
5941 (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
5942 (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
5945 return (SK_PNMI_ERR_BAD_VALUE);
5948 /* The preset ends here */
5949 if (Action == SK_PNMI_PRESET) {
5951 return (SK_PNMI_ERR_OK);
5954 if (LogPortIndex == 0) {
5957 * The virtual port consists of all currently
5958 * active ports. Find them and send an event
5959 * with the new flow control mode to SIRQ.
5961 for (PhysPortIndex = 0;
5962 PhysPortIndex < PhysPortMax;
5965 if (!pAC->Pnmi.Port[PhysPortIndex].
5971 EventParam.Para32[0] = PhysPortIndex;
5972 EventParam.Para32[1] = (SK_U32)Val8;
5973 if (SkGeSirqEvent(pAC, IoC,
5974 SK_HWEV_SET_FLOWMODE,
5977 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5982 return (SK_PNMI_ERR_GENERAL);
5988 * Send an event with the new flow control
5989 * mode to the SIRQ module.
5991 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5993 EventParam.Para32[1] = (SK_U32)Val8;
5994 if (SkGeSirqEvent(pAC, IoC,
5995 SK_HWEV_SET_FLOWMODE, EventParam)
5998 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6003 return (SK_PNMI_ERR_GENERAL);
6006 Offset += sizeof(char);
6009 case OID_SKGE_PHY_OPERATION_MODE :
6010 /* Check the value range */
6011 Val8 = *(pBuf + Offset);
6013 /* mode of this port remains unchanged */
6014 Offset += sizeof(char);
6017 if (Val8 < SK_MS_MODE_AUTO ||
6018 (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
6019 (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
6022 return (SK_PNMI_ERR_BAD_VALUE);
6025 /* The preset ends here */
6026 if (Action == SK_PNMI_PRESET) {
6028 return (SK_PNMI_ERR_OK);
6031 if (LogPortIndex == 0) {
6034 * The virtual port consists of all currently
6035 * active ports. Find them and send an event
6036 * with new master/slave (role) mode to SIRQ.
6038 for (PhysPortIndex = 0;
6039 PhysPortIndex < PhysPortMax;
6042 if (!pAC->Pnmi.Port[PhysPortIndex].
6048 EventParam.Para32[0] = PhysPortIndex;
6049 EventParam.Para32[1] = (SK_U32)Val8;
6050 if (SkGeSirqEvent(pAC, IoC,
6054 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6059 return (SK_PNMI_ERR_GENERAL);
6065 * Send an event with the new master/slave
6066 * (role) mode to the SIRQ module.
6068 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
6070 EventParam.Para32[1] = (SK_U32)Val8;
6071 if (SkGeSirqEvent(pAC, IoC,
6072 SK_HWEV_SET_ROLE, EventParam) > 0) {
6074 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6079 return (SK_PNMI_ERR_GENERAL);
6083 Offset += sizeof(char);
6086 case OID_SKGE_SPEED_MODE:
6087 /* Check the value range */
6088 Val8 = *(pBuf + Offset);
6091 Offset += sizeof(char);
6094 if (Val8 < (SK_LSPEED_AUTO) ||
6095 (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) ||
6096 (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) {
6099 return (SK_PNMI_ERR_BAD_VALUE);
6102 /* The preset ends here */
6103 if (Action == SK_PNMI_PRESET) {
6105 return (SK_PNMI_ERR_OK);
6108 if (LogPortIndex == 0) {
6111 * The virtual port consists of all currently
6112 * active ports. Find them and send an event
6113 * with the new flow control mode to SIRQ.
6115 for (PhysPortIndex = 0;
6116 PhysPortIndex < PhysPortMax;
6119 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6124 EventParam.Para32[0] = PhysPortIndex;
6125 EventParam.Para32[1] = (SK_U32)Val8;
6126 if (SkGeSirqEvent(pAC, IoC,
6130 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6135 return (SK_PNMI_ERR_GENERAL);
6141 * Send an event with the new flow control
6142 * mode to the SIRQ module.
6144 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
6146 EventParam.Para32[1] = (SK_U32)Val8;
6147 if (SkGeSirqEvent(pAC, IoC,
6151 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6156 return (SK_PNMI_ERR_GENERAL);
6159 Offset += sizeof(char);
6163 /* Check the value range */
6164 Val32 = *(SK_U32*)(pBuf + Offset);
6166 /* mtu of this port remains unchanged */
6167 Offset += sizeof(SK_U32);
6170 if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
6172 return (SK_PNMI_ERR_BAD_VALUE);
6175 /* The preset ends here */
6176 if (Action == SK_PNMI_PRESET) {
6177 return (SK_PNMI_ERR_OK);
6180 if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
6181 return (SK_PNMI_ERR_GENERAL);
6184 Offset += sizeof(SK_U32);
6188 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
6189 ("MacPrivateConf: Unknown OID should be handled before set"));
6192 return (SK_PNMI_ERR_GENERAL);
6196 return (SK_PNMI_ERR_OK);
6199 /*****************************************************************************
6201 * Monitor - OID handler function for RLMT_MONITOR_XXX
6204 * Because RLMT currently does not support the monitoring of
6205 * remote adapter cards, we return always an empty table.
6208 * SK_PNMI_ERR_OK The request was successfully performed.
6209 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
6210 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
6211 * the correct data (e.g. a 32bit value is
6212 * needed, but a 16 bit value was passed).
6213 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
6215 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
6216 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
6217 * exist (e.g. port instance 3 on a two port
6220 PNMI_STATIC int Monitor(
6221 SK_AC *pAC, /* Pointer to adapter context */
6222 SK_IOC IoC, /* IO context handle */
6223 int Action, /* Get/PreSet/Set action */
6224 SK_U32 Id, /* Object ID that is to be processed */
6225 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
6226 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
6227 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
6228 unsigned int TableIndex, /* Index to the Id table */
6229 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6233 unsigned int Offset;
6234 unsigned int Entries;
6238 * Calculate instance if wished.
6240 /* XXX Not yet implemented. Return always an empty table. */
6243 if ((Instance != (SK_U32)(-1))) {
6245 if ((Instance < 1) || (Instance > Entries)) {
6248 return (SK_PNMI_ERR_UNKNOWN_INST);
6251 Index = (unsigned int)Instance - 1;
6252 Limit = (unsigned int)Instance;
6262 if (Action == SK_PNMI_GET) {
6264 for (Offset=0; Index < Limit; Index ++) {
6268 case OID_SKGE_RLMT_MONITOR_INDEX:
6269 case OID_SKGE_RLMT_MONITOR_ADDR:
6270 case OID_SKGE_RLMT_MONITOR_ERRS:
6271 case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
6272 case OID_SKGE_RLMT_MONITOR_ADMIN:
6276 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
6280 return (SK_PNMI_ERR_GENERAL);
6286 /* Only MONITOR_ADMIN can be set */
6287 if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
6290 return (SK_PNMI_ERR_READ_ONLY);
6293 /* Check if the length is plausible */
6294 if (*pLen < (Limit - Index)) {
6296 return (SK_PNMI_ERR_TOO_SHORT);
6298 /* Okay, we have a wide value range */
6299 if (*pLen != (Limit - Index)) {
6302 return (SK_PNMI_ERR_BAD_VALUE);
6305 for (Offset=0; Index < Limit; Index ++) {
6309 * XXX Not yet implemented. Return always BAD_VALUE, because the table
6313 return (SK_PNMI_ERR_BAD_VALUE);
6316 return (SK_PNMI_ERR_OK);
6319 /*****************************************************************************
6321 * VirtualConf - Calculates the values of configuration OIDs for virtual port
6324 * We handle here the get of the configuration group OIDs, which are
6325 * a little bit complicated. The virtual port consists of all currently
6326 * active physical ports. If multiple ports are active and configured
6327 * differently we get in some trouble to return a single value. So we
6328 * get the value of the first active port and compare it with that of
6329 * the other active ports. If they are not the same, we return a value
6330 * that indicates that the state is indeterminated.
6335 PNMI_STATIC void VirtualConf(
6336 SK_AC *pAC, /* Pointer to adapter context */
6337 SK_IOC IoC, /* IO context handle */
6338 SK_U32 Id, /* Object ID that is to be processed */
6339 char *pBuf) /* Buffer to which to mgmt data will be retrieved */
6341 unsigned int PhysPortMax;
6342 unsigned int PhysPortIndex;
6344 SK_BOOL PortActiveFlag;
6348 PortActiveFlag = SK_FALSE;
6349 PhysPortMax = pAC->GIni.GIMacsFound;
6351 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
6354 /* Check if the physical port is active */
6355 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6360 PortActiveFlag = SK_TRUE;
6364 case OID_SKGE_LINK_CAP:
6367 * Different capabilities should not happen, but
6368 * in the case of the cases OR them all together.
6369 * From a curious point of view the virtual port
6370 * is capable of all found capabilities.
6372 *pBuf |= pAC->GIni.GP[PhysPortIndex].PLinkCap;
6375 case OID_SKGE_LINK_MODE:
6376 /* Check if it is the first active port */
6379 *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
6384 * If we find an active port with a different link
6385 * mode than the first one we return a value that
6386 * indicates that the link mode is indeterminated.
6388 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkModeConf
6391 *pBuf = SK_LMODE_INDETERMINATED;
6395 case OID_SKGE_LINK_MODE_STATUS:
6396 /* Get the link mode of the physical port */
6397 Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
6399 /* Check if it is the first active port */
6407 * If we find an active port with a different link
6408 * mode status than the first one we return a value
6409 * that indicates that the link mode status is
6412 if (*pBuf != Val8) {
6414 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6418 case OID_SKGE_LINK_STATUS:
6419 /* Get the link status of the physical port */
6420 Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
6422 /* Check if it is the first active port */
6430 * If we find an active port with a different link
6431 * status than the first one, we return a value
6432 * that indicates that the link status is
6435 if (*pBuf != Val8) {
6437 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6441 case OID_SKGE_FLOWCTRL_CAP:
6442 /* Check if it is the first active port */
6445 *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
6450 * From a curious point of view the virtual port
6451 * is capable of all found capabilities.
6453 *pBuf |= pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
6456 case OID_SKGE_FLOWCTRL_MODE:
6457 /* Check if it is the first active port */
6460 *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
6465 * If we find an active port with a different flow
6466 * control mode than the first one, we return a value
6467 * that indicates that the mode is indeterminated.
6469 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode) {
6471 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6475 case OID_SKGE_FLOWCTRL_STATUS:
6476 /* Check if it is the first active port */
6479 *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
6484 * If we find an active port with a different flow
6485 * control status than the first one, we return a
6486 * value that indicates that the status is
6489 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus) {
6491 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6495 case OID_SKGE_PHY_OPERATION_CAP:
6496 /* Check if it is the first active port */
6499 *pBuf = pAC->GIni.GP[PhysPortIndex].PMSCap;
6504 * From a curious point of view the virtual port
6505 * is capable of all found capabilities.
6507 *pBuf |= pAC->GIni.GP[PhysPortIndex].PMSCap;
6510 case OID_SKGE_PHY_OPERATION_MODE:
6511 /* Check if it is the first active port */
6514 *pBuf = pAC->GIni.GP[PhysPortIndex].PMSMode;
6519 * If we find an active port with a different master/
6520 * slave mode than the first one, we return a value
6521 * that indicates that the mode is indeterminated.
6523 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PMSMode) {
6525 *pBuf = SK_MS_MODE_INDETERMINATED;
6529 case OID_SKGE_PHY_OPERATION_STATUS:
6530 /* Check if it is the first active port */
6533 *pBuf = pAC->GIni.GP[PhysPortIndex].PMSStatus;
6538 * If we find an active port with a different master/
6539 * slave status than the first one, we return a
6540 * value that indicates that the status is
6543 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PMSStatus) {
6545 *pBuf = SK_MS_STAT_INDETERMINATED;
6549 case OID_SKGE_SPEED_MODE:
6550 /* Check if it is the first active port */
6553 *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
6558 * If we find an active port with a different flow
6559 * control mode than the first one, we return a value
6560 * that indicates that the mode is indeterminated.
6562 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkSpeed) {
6564 *pBuf = SK_LSPEED_INDETERMINATED;
6568 case OID_SKGE_SPEED_STATUS:
6569 /* Check if it is the first active port */
6572 *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
6577 * If we find an active port with a different flow
6578 * control status than the first one, we return a
6579 * value that indicates that the status is
6582 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed) {
6584 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6591 * If no port is active return an indeterminated answer
6593 if (!PortActiveFlag) {
6597 case OID_SKGE_LINK_CAP:
6598 *pBuf = SK_LMODE_CAP_INDETERMINATED;
6601 case OID_SKGE_LINK_MODE:
6602 *pBuf = SK_LMODE_INDETERMINATED;
6605 case OID_SKGE_LINK_MODE_STATUS:
6606 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6609 case OID_SKGE_LINK_STATUS:
6610 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6613 case OID_SKGE_FLOWCTRL_CAP:
6614 case OID_SKGE_FLOWCTRL_MODE:
6615 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6618 case OID_SKGE_FLOWCTRL_STATUS:
6619 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6622 case OID_SKGE_PHY_OPERATION_CAP:
6623 *pBuf = SK_MS_CAP_INDETERMINATED;
6626 case OID_SKGE_PHY_OPERATION_MODE:
6627 *pBuf = SK_MS_MODE_INDETERMINATED;
6630 case OID_SKGE_PHY_OPERATION_STATUS:
6631 *pBuf = SK_MS_STAT_INDETERMINATED;
6633 case OID_SKGE_SPEED_CAP:
6634 *pBuf = SK_LSPEED_CAP_INDETERMINATED;
6637 case OID_SKGE_SPEED_MODE:
6638 *pBuf = SK_LSPEED_INDETERMINATED;
6641 case OID_SKGE_SPEED_STATUS:
6642 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6648 /*****************************************************************************
6650 * CalculateLinkStatus - Determins the link status of a physical port
6653 * Determins the link status the following way:
6654 * LSTAT_PHY_DOWN: Link is down
6655 * LSTAT_AUTONEG: Auto-negotiation failed
6656 * LSTAT_LOG_DOWN: Link is up but RLMT did not yet put the port
6658 * LSTAT_LOG_UP: RLMT marked the port as up
6661 * Link status of physical port
6663 PNMI_STATIC SK_U8 CalculateLinkStatus(
6664 SK_AC *pAC, /* Pointer to adapter context */
6665 SK_IOC IoC, /* IO context handle */
6666 unsigned int PhysPortIndex) /* Physical port index */
6671 if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
6673 Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
6675 else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
6677 Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
6679 else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
6681 Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
6684 Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
6690 /*****************************************************************************
6692 * CalculateLinkModeStatus - Determins the link mode status of a phys. port
6695 * The COMMON module only tells us if the mode is half or full duplex.
6696 * But in the decade of auto sensing it is usefull for the user to
6697 * know if the mode was negotiated or forced. Therefore we have a
6698 * look to the mode, which was last used by the negotiation process.
6701 * The link mode status
6703 PNMI_STATIC SK_U8 CalculateLinkModeStatus(
6704 SK_AC *pAC, /* Pointer to adapter context */
6705 SK_IOC IoC, /* IO context handle */
6706 unsigned int PhysPortIndex) /* Physical port index */
6711 /* Get the current mode, which can be full or half duplex */
6712 Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
6714 /* Check if no valid mode could be found (link is down) */
6715 if (Result < SK_LMODE_STAT_HALF) {
6717 Result = SK_LMODE_STAT_UNKNOWN;
6719 else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
6722 * Auto-negotiation was used to bring up the link. Change
6723 * the already found duplex status that it indicates
6724 * auto-negotiation was involved.
6726 if (Result == SK_LMODE_STAT_HALF) {
6728 Result = SK_LMODE_STAT_AUTOHALF;
6730 else if (Result == SK_LMODE_STAT_FULL) {
6732 Result = SK_LMODE_STAT_AUTOFULL;
6739 /*****************************************************************************
6741 * GetVpdKeyArr - Obtain an array of VPD keys
6744 * Read the VPD keys and build an array of VPD keys, which are
6748 * SK_PNMI_ERR_OK Task successfully performed.
6749 * SK_PNMI_ERR_GENERAL Something went wrong.
6751 PNMI_STATIC int GetVpdKeyArr(
6752 SK_AC *pAC, /* Pointer to adapter context */
6753 SK_IOC IoC, /* IO context handle */
6754 char *pKeyArr, /* Ptr KeyArray */
6755 unsigned int KeyArrLen, /* Length of array in bytes */
6756 unsigned int *pKeyNo) /* Number of keys */
6758 unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE;
6759 char BufKeys[SK_PNMI_VPD_BUFSIZE];
6760 unsigned int StartOffset;
6761 unsigned int Offset;
6766 SK_MEMSET(pKeyArr, 0, KeyArrLen);
6771 Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
6775 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
6778 return (SK_PNMI_ERR_GENERAL);
6780 /* If no keys are available return now */
6781 if (*pKeyNo == 0 || BufKeysLen == 0) {
6783 return (SK_PNMI_ERR_OK);
6786 * If the key list is too long for us trunc it and give a
6787 * errorlog notification. This case should not happen because
6788 * the maximum number of keys is limited due to RAM limitations
6790 if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
6792 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
6795 *pKeyNo = SK_PNMI_VPD_ENTRIES;
6799 * Now build an array of fixed string length size and copy
6800 * the keys together.
6802 for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
6805 if (BufKeys[Offset] != 0) {
6810 if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
6812 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
6814 return (SK_PNMI_ERR_GENERAL);
6817 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6818 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6821 StartOffset = Offset + 1;
6824 /* Last key not zero terminated? Get it anyway */
6825 if (StartOffset < Offset) {
6827 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6828 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6831 return (SK_PNMI_ERR_OK);
6834 /*****************************************************************************
6836 * SirqUpdate - Let the SIRQ update its internal values
6839 * Just to be sure that the SIRQ module holds its internal data
6840 * structures up to date, we send an update event before we make
6844 * SK_PNMI_ERR_OK Task successfully performed.
6845 * SK_PNMI_ERR_GENERAL Something went wrong.
6847 PNMI_STATIC int SirqUpdate(
6848 SK_AC *pAC, /* Pointer to adapter context */
6849 SK_IOC IoC) /* IO context handle */
6851 SK_EVPARA EventParam;
6854 /* Was the module already updated during the current PNMI call? */
6855 if (pAC->Pnmi.SirqUpdatedFlag > 0) {
6857 return (SK_PNMI_ERR_OK);
6860 /* Send an synchronuous update event to the module */
6861 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6862 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
6864 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
6867 return (SK_PNMI_ERR_GENERAL);
6870 return (SK_PNMI_ERR_OK);
6873 /*****************************************************************************
6875 * RlmtUpdate - Let the RLMT update its internal values
6878 * Just to be sure that the RLMT module holds its internal data
6879 * structures up to date, we send an update event before we make
6883 * SK_PNMI_ERR_OK Task successfully performed.
6884 * SK_PNMI_ERR_GENERAL Something went wrong.
6886 PNMI_STATIC int RlmtUpdate(
6887 SK_AC *pAC, /* Pointer to adapter context */
6888 SK_IOC IoC, /* IO context handle */
6889 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6891 SK_EVPARA EventParam;
6894 /* Was the module already updated during the current PNMI call? */
6895 if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
6897 return (SK_PNMI_ERR_OK);
6900 /* Send an synchronuous update event to the module */
6901 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6902 EventParam.Para32[0] = NetIndex;
6903 EventParam.Para32[1] = (SK_U32)-1;
6904 if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
6906 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
6909 return (SK_PNMI_ERR_GENERAL);
6912 return (SK_PNMI_ERR_OK);
6915 /*****************************************************************************
6917 * MacUpdate - Force the XMAC to output the current statistic
6920 * The XMAC holds its statistic internally. To obtain the current
6921 * values we send a command so that the statistic data will
6922 * be written to apredefined memory area on the adapter.
6925 * SK_PNMI_ERR_OK Task successfully performed.
6926 * SK_PNMI_ERR_GENERAL Something went wrong.
6928 PNMI_STATIC int MacUpdate(
6929 SK_AC *pAC, /* Pointer to adapter context */
6930 SK_IOC IoC, /* IO context handle */
6931 unsigned int FirstMac, /* Index of the first Mac to be updated */
6932 unsigned int LastMac) /* Index of the last Mac to be updated */
6934 unsigned int MacIndex;
6937 * Were the statistics already updated during the
6938 * current PNMI call?
6940 if (pAC->Pnmi.MacUpdatedFlag > 0) {
6942 return (SK_PNMI_ERR_OK);
6945 /* Send an update command to all MACs specified */
6946 for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
6949 * 2002-09-13 pweber: Freeze the current sw counters.
6950 * (That should be done as close as
6951 * possible to the update of the
6954 if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
6955 pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
6958 /* 2002-09-13 pweber: Update the hw counter */
6959 if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
6961 return (SK_PNMI_ERR_GENERAL);
6965 return (SK_PNMI_ERR_OK);
6968 /*****************************************************************************
6970 * GetStatVal - Retrieve an XMAC statistic counter
6973 * Retrieves the statistic counter of a virtual or physical port. The
6974 * virtual port is identified by the index 0. It consists of all
6975 * currently active ports. To obtain the counter value for this port
6976 * we must add the statistic counter of all active ports. To grant
6977 * continuous counter values for the virtual port even when port
6978 * switches occur we must additionally add a delta value, which was
6979 * calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
6982 * Requested statistic value
6984 PNMI_STATIC SK_U64 GetStatVal(
6985 SK_AC *pAC, /* Pointer to adapter context */
6986 SK_IOC IoC, /* IO context handle */
6987 unsigned int LogPortIndex, /* Index of the logical Port to be processed */
6988 unsigned int StatIndex, /* Index to statistic value */
6989 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6991 unsigned int PhysPortIndex;
6992 unsigned int PhysPortMax;
6996 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
6998 PhysPortIndex = NetIndex;
6999 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
7001 else { /* Single Net mode */
7003 if (LogPortIndex == 0) {
7005 PhysPortMax = pAC->GIni.GIMacsFound;
7007 /* Add counter of all active ports */
7008 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
7011 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
7013 Val += GetPhysStatVal(pAC, IoC, PhysPortIndex,
7018 /* Correct value because of port switches */
7019 Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
7022 /* Get counter value of physical port */
7023 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
7024 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
7030 /*****************************************************************************
7032 * GetPhysStatVal - Get counter value for physical port
7035 * Builds a 64bit counter value. Except for the octet counters
7036 * the lower 32bit are counted in hardware and the upper 32bit
7037 * in software by monitoring counter overflow interrupts in the
7038 * event handler. To grant continous counter values during XMAC
7039 * resets (caused by a workaround) we must add a delta value.
7040 * The delta was calculated in the event handler when a
7041 * SK_PNMI_EVT_XMAC_RESET was received.
7046 PNMI_STATIC SK_U64 GetPhysStatVal(
7047 SK_AC *pAC, /* Pointer to adapter context */
7048 SK_IOC IoC, /* IO context handle */
7049 unsigned int PhysPortIndex, /* Index of the logical Port to be processed */
7050 unsigned int StatIndex) /* Index to statistic value */
7058 SK_PNMI_PORT *pPnmiPrt;
7059 SK_GEMACFUNC *pFnMac;
7061 MacType = pAC->GIni.GIMacType;
7063 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
7064 if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
7065 pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
7068 pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex];
7071 pFnMac = &pAC->GIni.GIFunc;
7073 switch (StatIndex) {
7076 /* Not supported by GMAC */
7077 if (MacType == SK_MAC_GMAC) {
7081 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7082 StatAddr[StatIndex][MacType].Reg,
7084 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7087 case SK_PNMI_HTX_OCTET:
7088 case SK_PNMI_HRX_OCTET:
7089 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7090 StatAddr[StatIndex][MacType].Reg,
7092 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7093 StatAddr[StatIndex + 1][MacType].Reg,
7097 case SK_PNMI_HTX_BURST:
7098 case SK_PNMI_HTX_EXCESS_DEF:
7099 case SK_PNMI_HTX_CARRIER:
7100 /* Not supported by GMAC */
7101 if (MacType == SK_MAC_GMAC) {
7105 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7106 StatAddr[StatIndex][MacType].Reg,
7108 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7111 case SK_PNMI_HTX_MACC:
7112 /* GMAC only supports PAUSE MAC control frames */
7113 if (MacType == SK_MAC_GMAC) {
7114 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, SK_PNMI_HTX_PMACC);
7119 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7120 StatAddr[StatIndex][MacType].Reg,
7122 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7125 case SK_PNMI_HTX_COL:
7126 case SK_PNMI_HRX_UNDERSIZE:
7127 /* Not supported by XMAC */
7128 if (MacType == SK_MAC_XMAC) {
7132 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7133 StatAddr[StatIndex][MacType].Reg,
7135 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7139 case SK_PNMI_HTX_DEFFERAL:
7140 /* Not supported by GMAC */
7141 if (MacType == SK_MAC_GMAC) {
7146 * XMAC counts frames with deferred transmission
7147 * even in full-duplex mode.
7149 * In full-duplex mode the counter remains constant!
7151 if ((pAC->GIni.GP[PhysPortIndex].PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) ||
7152 (pAC->GIni.GP[PhysPortIndex].PLinkModeStatus == SK_LMODE_STAT_FULL)) {
7158 /* Otherwise get contents of hardware register. */
7159 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7160 StatAddr[SK_PNMI_HTX_DEFFERAL][MacType].Reg,
7162 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7166 case SK_PNMI_HRX_BADOCTET:
7167 /* Not supported by XMAC */
7168 if (MacType == SK_MAC_XMAC) {
7172 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7173 StatAddr[StatIndex][MacType].Reg,
7175 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7176 StatAddr[StatIndex + 1][MacType].Reg,
7180 case SK_PNMI_HTX_OCTETLOW:
7181 case SK_PNMI_HRX_OCTETLOW:
7182 case SK_PNMI_HRX_BADOCTETLOW:
7185 case SK_PNMI_HRX_LONGFRAMES:
7186 /* For XMAC the SW counter is managed by PNMI */
7187 if (MacType == SK_MAC_XMAC) {
7188 return (pPnmiPrt->StatRxLongFrameCts);
7191 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7192 StatAddr[StatIndex][MacType].Reg,
7194 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7197 case SK_PNMI_HRX_TOO_LONG:
7198 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7199 StatAddr[StatIndex][MacType].Reg,
7201 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7203 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7207 /* For GMAC the SW counter is additionally managed by PNMI */
7208 Val += pPnmiPrt->StatRxFrameTooLongCts;
7213 * Frames longer than IEEE 802.3 frame max size are counted
7214 * by XMAC in frame_too_long counter even reception of long
7215 * frames was enabled and the frame was correct.
7216 * So correct the value by subtracting RxLongFrame counter.
7218 Val -= pPnmiPrt->StatRxLongFrameCts;
7225 LowVal = (SK_U32)Val;
7226 HighVal = (SK_U32)(Val >> 32);
7229 case SK_PNMI_HRX_SHORTS:
7230 /* Not supported by GMAC */
7231 if (MacType == SK_MAC_GMAC) {
7237 * XMAC counts short frame errors even if link down (#10620)
7239 * If link-down the counter remains constant
7241 if (pAC->GIni.GP[PhysPortIndex].PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
7243 /* Otherwise get incremental difference */
7244 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7245 StatAddr[StatIndex][MacType].Reg,
7247 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7249 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7250 Val -= pPnmiPrt->RxShortZeroMark;
7252 LowVal = (SK_U32)Val;
7253 HighVal = (SK_U32)(Val >> 32);
7257 case SK_PNMI_HRX_MACC:
7258 case SK_PNMI_HRX_MACC_UNKWN:
7259 case SK_PNMI_HRX_BURST:
7260 case SK_PNMI_HRX_MISSED:
7261 case SK_PNMI_HRX_FRAMING:
7262 case SK_PNMI_HRX_CARRIER:
7263 case SK_PNMI_HRX_IRLENGTH:
7264 case SK_PNMI_HRX_SYMBOL:
7265 case SK_PNMI_HRX_CEXT:
7266 /* Not supported by GMAC */
7267 if (MacType == SK_MAC_GMAC) {
7272 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7273 StatAddr[StatIndex][MacType].Reg,
7275 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7278 case SK_PNMI_HRX_PMACC_ERR:
7279 /* For GMAC the SW counter is managed by PNMI */
7280 if (MacType == SK_MAC_GMAC) {
7281 return (pPnmiPrt->StatRxPMaccErr);
7284 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7285 StatAddr[StatIndex][MacType].Reg,
7287 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7290 /* SW counter managed by PNMI */
7291 case SK_PNMI_HTX_SYNC:
7292 LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
7293 HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
7296 /* SW counter managed by PNMI */
7297 case SK_PNMI_HTX_SYNC_OCTET:
7298 LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
7299 HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
7302 case SK_PNMI_HRX_FCS:
7304 * Broadcom filters fcs errors and counts it in
7305 * Receive Error Counter register
7307 if (pAC->GIni.GP[PhysPortIndex].PhyType == SK_PHY_BCOM) {
7308 /* do not read while not initialized (PHY_READ hangs!)*/
7309 if (pAC->GIni.GP[PhysPortIndex].PState) {
7310 PHY_READ(IoC, &pAC->GIni.GP[PhysPortIndex],
7311 PhysPortIndex, PHY_BCOM_RE_CTR,
7316 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7319 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7320 StatAddr[StatIndex][MacType].Reg,
7322 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7327 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7328 StatAddr[StatIndex][MacType].Reg,
7330 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7334 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7336 /* Correct value because of possible XMAC reset. XMAC Errata #2 */
7337 Val += pPnmiPrt->CounterOffset[StatIndex];
7342 /*****************************************************************************
7344 * ResetCounter - Set all counters and timestamps to zero
7347 * Notifies other common modules which store statistic data to
7348 * reset their counters and finally reset our own counters.
7353 PNMI_STATIC void ResetCounter(
7354 SK_AC *pAC, /* Pointer to adapter context */
7355 SK_IOC IoC, /* IO context handle */
7358 unsigned int PhysPortIndex;
7359 SK_EVPARA EventParam;
7362 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
7364 /* Notify sensor module */
7365 SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
7367 /* Notify RLMT module */
7368 EventParam.Para32[0] = NetIndex;
7369 EventParam.Para32[1] = (SK_U32)-1;
7370 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
7371 EventParam.Para32[1] = 0;
7373 /* Notify SIRQ module */
7374 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
7376 /* Notify CSUM module */
7378 EventParam.Para32[0] = NetIndex;
7379 EventParam.Para32[1] = (SK_U32)-1;
7380 SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
7384 /* Clear XMAC statistic */
7385 for (PhysPortIndex = 0; PhysPortIndex <
7386 (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
7388 (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex);
7390 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
7391 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
7392 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7393 CounterOffset, 0, sizeof(pAC->Pnmi.Port[
7394 PhysPortIndex].CounterOffset));
7395 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
7396 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
7397 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7398 StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
7399 PhysPortIndex].StatSyncOctetsCts));
7400 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7401 StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
7402 PhysPortIndex].StatRxLongFrameCts));
7403 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7404 StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[
7405 PhysPortIndex].StatRxFrameTooLongCts));
7406 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7407 StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[
7408 PhysPortIndex].StatRxPMaccErr));
7412 * Clear local statistics
7414 SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
7415 sizeof(pAC->Pnmi.VirtualCounterOffset));
7416 pAC->Pnmi.RlmtChangeCts = 0;
7417 pAC->Pnmi.RlmtChangeTime = 0;
7418 SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
7419 sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
7420 pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
7421 pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
7422 pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
7423 pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
7424 pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
7425 pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
7426 pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
7427 pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
7428 pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
7429 pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
7430 pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
7431 pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
7434 /*****************************************************************************
7436 * GetTrapEntry - Get an entry in the trap buffer
7439 * The trap buffer stores various events. A user application somehow
7440 * gets notified that an event occured and retrieves the trap buffer
7441 * contens (or simply polls the buffer). The buffer is organized as
7442 * a ring which stores the newest traps at the beginning. The oldest
7443 * traps are overwritten by the newest ones. Each trap entry has a
7444 * unique number, so that applications may detect new trap entries.
7447 * A pointer to the trap entry
7449 PNMI_STATIC char* GetTrapEntry(
7450 SK_AC *pAC, /* Pointer to adapter context */
7451 SK_U32 TrapId, /* SNMP ID of the trap */
7452 unsigned int Size) /* Space needed for trap entry */
7454 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7455 unsigned int BufFree = pAC->Pnmi.TrapBufFree;
7456 unsigned int Beg = pAC->Pnmi.TrapQueueBeg;
7457 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7458 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7460 unsigned int NeededSpace;
7461 unsigned int EntrySize;
7466 /* Last byte of entry will get a copy of the entry length */
7470 * Calculate needed buffer space */
7477 NeededSpace = Beg + Size;
7482 * Check if enough buffer space is provided. Otherwise
7483 * free some entries. Leave one byte space between begin
7484 * and end of buffer to make it possible to detect whether
7485 * the buffer is full or empty
7487 while (BufFree < NeededSpace + 1) {
7491 End = SK_PNMI_TRAP_QUEUE_LEN;
7494 EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
7495 BufFree += EntrySize;
7498 SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
7500 if (End == BufPad) {
7502 SK_MEMSET(pBuf, (char)(-1), End);
7511 * Insert new entry as first entry. Newest entries are
7512 * stored at the beginning of the queue.
7517 Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
7522 BufFree -= NeededSpace;
7524 /* Save the current offsets */
7525 pAC->Pnmi.TrapQueueBeg = Beg;
7526 pAC->Pnmi.TrapQueueEnd = End;
7527 pAC->Pnmi.TrapBufPad = BufPad;
7528 pAC->Pnmi.TrapBufFree = BufFree;
7530 /* Initialize the trap entry */
7531 *(pBuf + Beg + Size - 1) = (char)Size;
7532 *(pBuf + Beg) = (char)Size;
7533 Val32 = (pAC->Pnmi.TrapUnique) ++;
7534 SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
7535 SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
7536 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
7537 SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
7539 return (pBuf + Beg);
7542 /*****************************************************************************
7544 * CopyTrapQueue - Copies the trap buffer for the TRAP OID
7547 * On a query of the TRAP OID the trap buffer contents will be
7548 * copied continuously to the request buffer, which must be large
7549 * enough. No length check is performed.
7554 PNMI_STATIC void CopyTrapQueue(
7555 SK_AC *pAC, /* Pointer to adapter context */
7556 char *pDstBuf) /* Buffer to which the queued traps will be copied */
7558 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7559 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7560 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7561 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7563 unsigned int DstOff = 0;
7566 while (Trap != End) {
7568 Len = (unsigned int)*(pBuf + Trap);
7571 * Last byte containing a copy of the length will
7574 *(pDstBuf + DstOff) = (char)(Len - 1);
7575 SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
7579 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7586 /*****************************************************************************
7588 * GetTrapQueueLen - Get the length of the trap buffer
7591 * Evaluates the number of currently stored traps and the needed
7592 * buffer size to retrieve them.
7597 PNMI_STATIC void GetTrapQueueLen(
7598 SK_AC *pAC, /* Pointer to adapter context */
7599 unsigned int *pLen, /* Length in Bytes of all queued traps */
7600 unsigned int *pEntries) /* Returns number of trapes stored in queue */
7602 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7603 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7604 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7605 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7607 unsigned int Entries = 0;
7608 unsigned int TotalLen = 0;
7611 while (Trap != End) {
7613 Len = (unsigned int)*(pBuf + Trap);
7614 TotalLen += Len - 1;
7618 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7624 *pEntries = Entries;
7628 /*****************************************************************************
7630 * QueueSimpleTrap - Store a simple trap to the trap buffer
7633 * A simple trap is a trap with now additional data. It consists
7634 * simply of a trap code.
7639 PNMI_STATIC void QueueSimpleTrap(
7640 SK_AC *pAC, /* Pointer to adapter context */
7641 SK_U32 TrapId) /* Type of sensor trap */
7643 GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
7646 /*****************************************************************************
7648 * QueueSensorTrap - Stores a sensor trap in the trap buffer
7651 * Gets an entry in the trap buffer and fills it with sensor related
7657 PNMI_STATIC void QueueSensorTrap(
7658 SK_AC *pAC, /* Pointer to adapter context */
7659 SK_U32 TrapId, /* Type of sensor trap */
7660 unsigned int SensorIndex) /* Index of sensor which caused the trap */
7663 unsigned int Offset;
7664 unsigned int DescrLen;
7668 /* Get trap buffer entry */
7669 DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
7670 pBuf = GetTrapEntry(pAC, TrapId,
7671 SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
7672 Offset = SK_PNMI_TRAP_SIMPLE_LEN;
7674 /* Store additionally sensor trap related data */
7675 Val32 = OID_SKGE_SENSOR_INDEX;
7676 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7677 *(pBuf + Offset + 4) = 4;
7678 Val32 = (SK_U32)SensorIndex;
7679 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7682 Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
7683 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7684 *(pBuf + Offset + 4) = (char)DescrLen;
7685 SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
7687 Offset += DescrLen + 5;
7689 Val32 = OID_SKGE_SENSOR_TYPE;
7690 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7691 *(pBuf + Offset + 4) = 1;
7692 *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
7695 Val32 = OID_SKGE_SENSOR_VALUE;
7696 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7697 *(pBuf + Offset + 4) = 4;
7698 Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
7699 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7702 /*****************************************************************************
7704 * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
7707 * Nothing further to explain.
7712 PNMI_STATIC void QueueRlmtNewMacTrap(
7713 SK_AC *pAC, /* Pointer to adapter context */
7714 unsigned int ActiveMac) /* Index (0..n) of the currently active port */
7720 pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
7721 SK_PNMI_TRAP_RLMT_CHANGE_LEN);
7723 Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
7724 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7725 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7726 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
7729 /*****************************************************************************
7731 * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
7734 * Nothing further to explain.
7739 PNMI_STATIC void QueueRlmtPortTrap(
7740 SK_AC *pAC, /* Pointer to adapter context */
7741 SK_U32 TrapId, /* Type of RLMT port trap */
7742 unsigned int PortIndex) /* Index of the port, which changed its state */
7748 pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
7750 Val32 = OID_SKGE_RLMT_PORT_INDEX;
7751 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7752 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7753 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
7756 /*****************************************************************************
7758 * CopyMac - Copies a MAC address
7761 * Nothing further to explain.
7766 PNMI_STATIC void CopyMac(
7767 char *pDst, /* Pointer to destination buffer */
7768 SK_MAC_ADDR *pMac) /* Pointer of Source */
7773 for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
7775 *(pDst + i) = pMac->a[i];
7780 #ifdef SK_POWER_MGMT
7781 /*****************************************************************************
7783 * PowerManagement - OID handler function of PowerManagement OIDs
7786 * The code is simple. No description necessary.
7789 * SK_PNMI_ERR_OK The request was successfully performed.
7790 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7791 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7792 * the correct data (e.g. a 32bit value is
7793 * needed, but a 16 bit value was passed).
7794 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7795 * exist (e.g. port instance 3 on a two port
7799 PNMI_STATIC int PowerManagement(
7800 SK_AC *pAC, /* Pointer to adapter context */
7801 SK_IOC IoC, /* IO context handle */
7802 int Action, /* Get/PreSet/Set action */
7803 SK_U32 Id, /* Object ID that is to be processed */
7804 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
7805 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
7806 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7807 unsigned int TableIndex, /* Index to the Id table */
7808 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
7811 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7814 * Check instance. We only handle single instance variables
7816 if (Instance != (SK_U32)(-1) && Instance != 1) {
7819 return (SK_PNMI_ERR_UNKNOWN_INST);
7825 if (Action == SK_PNMI_GET) {
7832 case OID_PNP_CAPABILITIES:
7833 if (*pLen < sizeof(SK_PNP_CAPABILITIES)) {
7835 *pLen = sizeof(SK_PNP_CAPABILITIES);
7836 return (SK_PNMI_ERR_TOO_SHORT);
7840 case OID_PNP_QUERY_POWER:
7841 case OID_PNP_ENABLE_WAKE_UP:
7842 if (*pLen < sizeof(SK_U32)) {
7844 *pLen = sizeof(SK_U32);
7845 return (SK_PNMI_ERR_TOO_SHORT);
7849 case OID_PNP_SET_POWER:
7850 case OID_PNP_ADD_WAKE_UP_PATTERN:
7851 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7855 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040,
7858 return (SK_PNMI_ERR_GENERAL);
7866 case OID_PNP_CAPABILITIES:
7867 RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen);
7870 case OID_PNP_QUERY_POWER:
7871 /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
7872 the miniport to indicate whether it can transition its NIC
7873 to the low-power state.
7874 A miniport driver must always return NDIS_STATUS_SUCCESS
7875 to a query of OID_PNP_QUERY_POWER. */
7876 RetCode = SK_PNMI_ERR_OK;
7879 /* NDIS handles these OIDs as write-only.
7880 * So in case of get action the buffer with written length = 0
7883 case OID_PNP_SET_POWER:
7884 case OID_PNP_ADD_WAKE_UP_PATTERN:
7885 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7887 RetCode = SK_PNMI_ERR_OK;
7890 case OID_PNP_ENABLE_WAKE_UP:
7891 RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen);
7895 RetCode = SK_PNMI_ERR_GENERAL;
7903 * From here SET or PRESET action. Check if the passed
7904 * buffer length is plausible.
7907 case OID_PNP_SET_POWER:
7908 case OID_PNP_ENABLE_WAKE_UP:
7909 if (*pLen < sizeof(SK_U32)) {
7911 *pLen = sizeof(SK_U32);
7912 return (SK_PNMI_ERR_TOO_SHORT);
7914 if (*pLen != sizeof(SK_U32)) {
7917 return (SK_PNMI_ERR_BAD_VALUE);
7921 case OID_PNP_ADD_WAKE_UP_PATTERN:
7922 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7923 if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) {
7926 return (SK_PNMI_ERR_BAD_VALUE);
7932 return (SK_PNMI_ERR_READ_ONLY);
7936 * Perform preset or set
7939 /* POWER module does not support PRESET action */
7940 if (Action == SK_PNMI_PRESET) {
7941 return (SK_PNMI_ERR_OK);
7945 case OID_PNP_SET_POWER:
7946 RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen);
7949 case OID_PNP_ADD_WAKE_UP_PATTERN:
7950 RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen);
7953 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7954 RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen);
7957 case OID_PNP_ENABLE_WAKE_UP:
7958 RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen);
7962 RetCode = SK_PNMI_ERR_GENERAL;
7967 #endif /* SK_POWER_MGMT */
7970 /*****************************************************************************
7972 * Vct - OID handler function of OIDs
7975 * The code is simple. No description necessary.
7978 * SK_PNMI_ERR_OK The request was performed successfully.
7979 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7980 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7981 * the correct data (e.g. a 32bit value is
7982 * needed, but a 16 bit value was passed).
7983 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7984 * exist (e.g. port instance 3 on a two port
7986 * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed.
7990 PNMI_STATIC int Vct(
7991 SK_AC *pAC, /* Pointer to adapter context */
7992 SK_IOC IoC, /* IO context handle */
7993 int Action, /* Get/PreSet/Set action */
7994 SK_U32 Id, /* Object ID that is to be processed */
7995 char *pBuf, /* Buffer to which the mgmt data will be copied */
7996 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
7997 SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */
7998 unsigned int TableIndex, /* Index to the Id table */
7999 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
8002 SK_PNMI_VCT *pVctBackupData;
8005 SK_U32 PhysPortIndex;
8009 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
8015 * Calculate the port indexes from the instance.
8017 PhysPortMax = pAC->GIni.GIMacsFound;
8018 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
8020 /* Dual net mode? */
8021 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
8025 if ((Instance != (SK_U32) (-1))) {
8026 /* Check instance range. */
8027 if ((Instance < 2) || (Instance > LogPortMax)) {
8029 return (SK_PNMI_ERR_UNKNOWN_INST);
8032 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
8033 PhysPortIndex = NetIndex;
8036 PhysPortIndex = Instance - 2;
8038 Limit = PhysPortIndex + 1;
8041 * Instance == (SK_U32) (-1), get all Instances of that OID.
8043 * Not implemented yet. May be used in future releases.
8046 Limit = PhysPortMax;
8049 pPrt = &pAC->GIni.GP[PhysPortIndex];
8050 if (pPrt->PHWLinkUp) {
8060 if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
8062 return (SK_PNMI_ERR_GENERAL);
8065 /* Initialize backup data pointer. */
8066 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
8069 * Check action type.
8071 if (Action == SK_PNMI_GET) {
8077 case OID_SKGE_VCT_GET:
8078 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
8079 *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
8080 return (SK_PNMI_ERR_TOO_SHORT);
8084 case OID_SKGE_VCT_STATUS:
8085 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
8086 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
8087 return (SK_PNMI_ERR_TOO_SHORT);
8093 return (SK_PNMI_ERR_GENERAL);
8100 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8103 case OID_SKGE_VCT_GET:
8104 if ((Link == SK_FALSE) &&
8105 (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
8106 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
8108 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
8109 pAC->Pnmi.VctStatus[PhysPortIndex] |=
8110 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
8112 /* Copy results for later use to PNMI struct. */
8113 for (i = 0; i < 4; i++) {
8114 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
8115 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
8116 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
8119 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
8120 CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
8125 pVctBackupData->PMdiPairLen[i] = CableLength;
8126 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
8129 Para.Para32[0] = PhysPortIndex;
8130 Para.Para32[1] = -1;
8131 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
8132 SkEventDispatcher(pAC, IoC);
8135 ; /* VCT test is running. */
8139 /* Get all results. */
8140 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
8141 Offset += sizeof(SK_U8);
8142 *(pBuf + Offset) = pPrt->PCableLen;
8143 Offset += sizeof(SK_U8);
8144 for (i = 0; i < 4; i++) {
8145 SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
8146 Offset += sizeof(SK_U32);
8148 for (i = 0; i < 4; i++) {
8149 *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
8150 Offset += sizeof(SK_U8);
8153 RetCode = SK_PNMI_ERR_OK;
8156 case OID_SKGE_VCT_STATUS:
8157 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
8158 Offset += sizeof(SK_U8);
8159 RetCode = SK_PNMI_ERR_OK;
8164 return (SK_PNMI_ERR_GENERAL);
8170 } /* if SK_PNMI_GET */
8173 * From here SET or PRESET action. Check if the passed
8174 * buffer length is plausible.
8181 case OID_SKGE_VCT_SET:
8182 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
8183 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
8184 return (SK_PNMI_ERR_TOO_SHORT);
8190 return (SK_PNMI_ERR_GENERAL);
8194 * Perform preset or set.
8197 /* VCT does not support PRESET action. */
8198 if (Action == SK_PNMI_PRESET) {
8199 return (SK_PNMI_ERR_OK);
8203 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8205 case OID_SKGE_VCT_SET: /* Start VCT test. */
8206 if (Link == SK_FALSE) {
8207 SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
8209 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
8210 if (RetCode == 0) { /* RetCode: 0 => Start! */
8211 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
8212 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8213 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
8216 * Start VCT timer counter.
8218 SK_MEMSET((char *) &Para, 0, sizeof(Para));
8219 Para.Para32[0] = PhysPortIndex;
8220 Para.Para32[1] = -1;
8221 SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
8222 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
8223 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8224 RetCode = SK_PNMI_ERR_OK;
8226 else { /* RetCode: 2 => Running! */
8227 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8228 RetCode = SK_PNMI_ERR_OK;
8231 else { /* RetCode: 4 => Link! */
8233 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8234 RetCode = SK_PNMI_ERR_OK;
8236 Offset += sizeof(SK_U32);
8241 return (SK_PNMI_ERR_GENERAL);
8250 PNMI_STATIC void CheckVctStatus(
8255 SK_U32 PhysPortIndex)
8258 SK_PNMI_VCT *pVctData;
8260 SK_U8 LinkSpeedUsed;
8262 pPrt = &pAC->GIni.GP[PhysPortIndex];
8264 pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
8265 pVctData->VctStatus = SK_PNMI_VCT_NONE;
8267 if (!pPrt->PHWLinkUp) {
8269 /* Was a VCT test ever made before? */
8270 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8271 if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
8272 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8275 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8279 /* Check VCT test status. */
8280 RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
8281 if (RetCode == 2) { /* VCT test is running. */
8282 pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
8284 else { /* VCT data was copied to pAC here. Check PENDING state. */
8285 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
8286 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8290 if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
8291 pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
8296 /* Was a VCT test ever made before? */
8297 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8298 pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8299 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8302 /* DSP only valid in 100/1000 modes. */
8303 LinkSpeedUsed = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
8304 if (LinkSpeedUsed != SK_LSPEED_STAT_10MBPS) {
8305 pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
8309 } /* CheckVctStatus */