1 /*****************************************************************************
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.102 $
6 * Date: $Date: 2002/12/16 14:03:24 $
7 * Purpose: Private Network Management Interface
9 ****************************************************************************/
11 /******************************************************************************
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * The information in this file is provided "AS IS" without warranty.
22 ******************************************************************************/
24 /*****************************************************************************
28 * $Log: skgepnmi.c,v $
29 * Revision 1.102 2002/12/16 14:03:24 tschilli
30 * VCT code in Vct() changed.
32 * Revision 1.101 2002/12/16 09:04:10 tschilli
33 * Code for VCT handling added.
35 * Revision 1.100 2002/09/26 14:28:13 tschilli
36 * For XMAC the values in the SK_PNMI_PORT Port struct are copied to
37 * the new SK_PNMI_PORT BufPort struct during a MacUpdate() call.
38 * These values are used when GetPhysStatVal() is called. With this
39 * mechanism you get the best results when software corrections for
40 * counters are needed. Example: RX_LONGFRAMES.
42 * Revision 1.99 2002/09/17 12:31:19 tschilli
43 * OID_SKGE_TX_HW_ERROR_CTS, OID_SKGE_OUT_ERROR_CTS, OID_GEN_XMIT_ERROR:
44 * Double count of SK_PNMI_HTX_EXCESS_COL in function General() removed.
45 * OID_PNP_CAPABILITIES: sizeof(SK_PM_WAKE_UP_CAPABILITIES) changed to
46 * sizeof(SK_PNP_CAPABILITIES) in function PowerManagement().
48 * Revision 1.98 2002/09/10 09:00:03 rwahl
49 * Adapted boolean definitions according sktypes.
51 * Revision 1.97 2002/09/05 15:07:03 rwahl
54 * Revision 1.96 2002/09/05 11:04:14 rwahl
55 * - Rx/Tx packets statistics of virtual port were zero on link down (#10750)
56 * - For GMAC the overflow IRQ for Rx longframe counter was not counted.
57 * - Incorrect calculation for oids OID_SKGE_RX_HW_ERROR_CTS,
58 * OID_SKGE_IN_ERRORS_CTS, OID_GEN_RCV_ERROR.
59 * - Moved correction for OID_SKGE_STAT_RX_TOO_LONG to GetPhysStatVal().
60 * - Editorial changes.
62 * Revision 1.95 2002/09/04 08:53:37 rwahl
63 * - Incorrect statistics for Rx_too_long counter with jumbo frame (#10751)
64 * - StatRxFrameTooLong & StatRxPMaccErr counters were not reset.
65 * - Fixed compiler warning for debug msg arg types.
67 * Revision 1.94 2002/08/09 15:42:14 rwahl
68 * - Fixed StatAddr table for GMAC.
69 * - VirtualConf(): returned indeterminated status for speed oids if no
72 * Revision 1.93 2002/08/09 11:04:59 rwahl
73 * Added handler for link speed caps.
75 * Revision 1.92 2002/08/09 09:43:03 rwahl
76 * - Added handler for NDIS OID_PNP_xxx ids.
78 * Revision 1.91 2002/07/17 19:53:03 rwahl
79 * - Added StatOvrflwBit table for XMAC & GMAC.
80 * - Extended StatAddr table for GMAC. Added check of number of counters
81 * in enumeration and size of StatAddr table on init level.
82 * - Added use of GIFunc table.
83 * - ChipSet is not static anymore,
84 * - Extended SIRQ event handler for both mac types.
85 * - Fixed rx short counter bug (#10620)
86 * - Added handler for oids SKGE_SPEED_MODE & SKGE_SPEED_STATUS.
87 * - Extendet GetPhysStatVal() for GMAC.
88 * - Editorial changes.
90 * Revision 1.90 2002/05/22 08:56:25 rwahl
91 * - Moved OID table to separate source file.
92 * - Fix: TX_DEFFERAL counter incremented in full-duplex mode.
93 * - Use string definitions for error msgs.
95 * Revision 1.89 2001/09/18 10:01:30 mkunz
96 * some OID's fixed for dualnetmode
98 * Revision 1.88 2001/08/02 07:58:08 rwahl
99 * - Fixed NetIndex to csum module at ResetCounter().
101 * Revision 1.87 2001/04/06 13:35:09 mkunz
102 * -Bugs fixed in handling of OID_SKGE_MTU and the VPD OID's
104 * Revision 1.86 2001/03/09 09:18:03 mkunz
105 * Changes in SK_DBG_MSG
107 * Revision 1.85 2001/03/08 09:37:31 mkunz
108 * Bugfix in ResetCounter for Pnmi.Port structure
110 * Revision 1.84 2001/03/06 09:04:55 mkunz
111 * Made some changes in instance calculation
113 * Revision 1.83 2001/02/15 09:15:32 mkunz
114 * Necessary changes for dual net mode added
116 * Revision 1.82 2001/02/07 08:24:19 mkunz
117 * -Made changes in handling of OID_SKGE_MTU
119 * Revision 1.81 2001/02/06 09:58:00 mkunz
121 * -OID_SKGE_MTU added
122 * -pnmi support for dual net mode. Interface function and macros extended
124 * Revision 1.80 2001/01/22 13:41:35 rassmann
125 * Supporting two nets on dual-port adapters.
127 * Revision 1.79 2000/12/05 14:57:40 cgoos
128 * SetStruct failed before first Link Up (link mode of virtual
129 * port "INDETERMINATED").
131 * Revision 1.78 2000/09/12 10:44:58 cgoos
132 * Fixed SK_PNMI_STORE_U32 calls with typecasted argument.
134 * Revision 1.77 2000/09/07 08:10:19 rwahl
135 * - Modified algorithm for 64bit NDIS statistic counters;
136 * returns 64bit or 32bit value depending on passed buffer
137 * size. Indicate capability for 64bit NDIS counter, if passed
138 * buffer size is zero. OID_GEN_XMIT_ERROR, OID_GEN_RCV_ERROR,
139 * and OID_GEN_RCV_NO_BUFFER handled as 64bit counter, too.
140 * - corrected OID_SKGE_RLMT_PORT_PREFERRED.
142 * Revision 1.76 2000/08/03 15:23:39 rwahl
143 * - Correction for FrameTooLong counter has to be moved to OID handling
144 * routines (instead of statistic counter routine).
145 * - Fix in XMAC Reset Event handling: Only offset counter for hardware
146 * statistic registers are updated.
148 * Revision 1.75 2000/08/01 16:46:05 rwahl
149 * - Added StatRxLongFrames counter and correction of FrameTooLong counter.
150 * - Added directive to control width (default = 32bit) of NDIS statistic
151 * counters (SK_NDIS_64BIT_CTR).
153 * Revision 1.74 2000/07/04 11:41:53 rwahl
154 * - Added volition connector type.
156 * Revision 1.73 2000/03/15 16:33:10 rwahl
157 * Fixed bug 10510; wrong reset of virtual port statistic counters.
159 * Revision 1.72 1999/12/06 16:15:53 rwahl
160 * Fixed problem of instance range for current and factory MAC address.
162 * Revision 1.71 1999/12/06 10:14:20 rwahl
163 * Fixed bug 10476; set operation for PHY_OPERATION_MODE.
165 * Revision 1.70 1999/11/22 13:33:34 cgoos
166 * Changed license header to GPL.
168 * Revision 1.69 1999/10/18 11:42:15 rwahl
169 * Added typecasts for checking event dependent param (debug only).
171 * Revision 1.68 1999/10/06 09:35:59 cgoos
172 * Added state check to PHY_READ call (hanged if called during startup).
174 * Revision 1.67 1999/09/22 09:53:20 rwahl
175 * - Read Broadcom register for updating fcs error counter (1000Base-T).
177 * Revision 1.66 1999/08/26 13:47:56 rwahl
178 * Added SK_DRIVER_SENDEVENT when queueing RLMT_CHANGE_THRES trap.
180 * Revision 1.65 1999/07/26 07:49:35 cgoos
181 * Added two typecasts to avoid compiler warnings.
183 * Revision 1.64 1999/05/20 09:24:12 cgoos
184 * Changes for 1000Base-T (sensors, Master/Slave).
186 * Revision 1.63 1999/04/13 15:11:58 mhaveman
187 * Moved include of rlmt.h to header skgepnmi.h because some macros
190 * Revision 1.62 1999/04/13 15:08:07 mhaveman
191 * Replaced again SK_RLMT_CHECK_LINK with SK_PNMI_RLMT_MODE_CHK_LINK
192 * to grant unified interface by only using the PNMI header file.
193 * SK_PNMI_RLMT_MODE_CHK_LINK is defined the same as SK_RLMT_CHECK_LINK.
195 * Revision 1.61 1999/04/13 15:02:48 mhaveman
196 * Changes caused by review:
197 * -Changed some comments
198 * -Removed redundant check for OID_SKGE_PHYS_FAC_ADDR
199 * -Optimized PRESET check.
200 * -Meaning of error SK_ADDR_DUPLICATE_ADDRESS changed. Set of same
201 * address will now not cause this error. Removed corresponding check.
203 * Revision 1.60 1999/03/23 10:41:23 mhaveman
206 * Revision 1.59 1999/02/19 08:01:28 mhaveman
207 * Fixed bug 10372 that after counter reset all ports were displayed
210 * Revision 1.58 1999/02/16 18:04:47 mhaveman
211 * Fixed problem of twisted OIDs SENSOR_WAR_TIME and SENSOR_ERR_TIME.
213 * Revision 1.56 1999/01/27 12:29:11 mhaveman
214 * SkTimerStart was called with time value in milli seconds but needs
217 * Revision 1.55 1999/01/25 15:00:38 mhaveman
218 * Added support to allow multiple ports to be active. If this feature in
219 * future will be used, the Management Data Base variables PORT_ACTIVE
220 * and PORT_PREFERED should be moved to the port specific part of RLMT.
221 * Currently they return the values of the first active physical port
222 * found. A set to the virtual port will actually change all active
223 * physical ports. A get returns the melted values of all active physical
224 * ports. If the port values differ a return value INDETERMINATED will
225 * be returned. This effects especially the CONF group.
227 * Revision 1.54 1999/01/19 10:10:22 mhaveman
228 * -Fixed bug 10354: Counter values of virtual port were wrong after port
230 * -Added check if a switch to the same port is notified.
232 * Revision 1.53 1999/01/07 09:25:21 mhaveman
233 * Forgot to initialize a variable.
235 * Revision 1.52 1999/01/05 10:34:33 mhaveman
236 * Fixed little error in RlmtChangeEstimate calculation.
238 * Revision 1.51 1999/01/05 09:59:07 mhaveman
239 * -Moved timer start to init level 2
240 * -Redesigned port switch average calculation to avoid 64bit
243 * Revision 1.50 1998/12/10 15:13:59 mhaveman
244 * -Fixed: PHYS_CUR_ADDR returned wrong addresses
245 * -Fixed: RLMT_PORT_PREFERED and RLMT_CHANGE_THRES preset returned
247 * -Fixed: TRAP buffer seemed to sometimes suddenly empty
249 * Revision 1.49 1998/12/09 16:17:07 mhaveman
250 * Fixed: Couldnot delete VPD keys on UNIX.
252 * Revision 1.48 1998/12/09 14:11:10 mhaveman
253 * -Add: Debugmessage for XMAC_RESET supressed to minimize output.
254 * -Fixed: RlmtChangeThreshold will now be initialized.
255 * -Fixed: VPD_ENTRIES_LIST extended value with unnecessary space char.
256 * -Fixed: On VPD key creation an invalid key name could be created
258 * -Some minor changes in comments and code.
260 * Revision 1.47 1998/12/08 16:00:31 mhaveman
261 * -Fixed: For RLMT_PORT_ACTIVE will now be returned a 0 if no port
263 * -Fixed: For the RLMT statistics group only the last value was
264 * returned and the rest of the buffer was filled with 0xff
265 * -Fixed: Mysteriously the preset on RLMT_MODE still returned
267 * Revision 1.46 1998/12/08 10:04:56 mhaveman
268 * -Fixed: Preset on RLMT_MODE returned always BAD_VALUE error.
269 * -Fixed: Alignment error in GetStruct
270 * -Fixed: If for Get/Preset/SetStruct the buffer size is equal or
271 * larger than SK_PNMI_MIN_STRUCT_SIZE the return value is stored
272 * to the buffer. In this case the caller should always return
273 * ok to its upper routines. Only if the buffer size is less
274 * than SK_PNMI_MIN_STRUCT_SIZE and the return value is unequal
275 * to 0, an error should be returned by the caller.
276 * -Fixed: Wrong number of instances with RLMT statistic.
277 * -Fixed: Return now SK_LMODE_STAT_UNKNOWN if the LinkModeStatus is 0.
279 * Revision 1.45 1998/12/03 17:17:24 mhaveman
280 * -Removed for VPD create action the buffer size limitation to 4 bytes.
281 * -Pass now physical/active physical port to ADDR for CUR_ADDR set
283 * Revision 1.44 1998/12/03 15:14:35 mhaveman
284 * Another change to Vpd instance evaluation.
286 * Revision 1.43 1998/12/03 14:18:10 mhaveman
287 * -Fixed problem in PnmiSetStruct. It was impossible to set any value.
288 * -Removed VPD key evaluation for VPD_FREE_BYTES and VPD_ACTION.
290 * Revision 1.42 1998/12/03 11:31:47 mhaveman
291 * Inserted cast to satisfy lint.
293 * Revision 1.41 1998/12/03 11:28:16 mhaveman
294 * Removed SK_PNMI_CHECKPTR
296 * Revision 1.40 1998/12/03 11:19:07 mhaveman
298 * -A set to virtual port will now be ignored. A set with broadcast
299 * address to any port will be ignored.
300 * -GetStruct function made VPD instance calculation wrong.
301 * -Prefered port returned -1 instead of 0.
303 * Revision 1.39 1998/11/26 15:30:29 mhaveman
304 * Added sense mode to link mode.
306 * Revision 1.38 1998/11/23 15:34:00 mhaveman
307 * -Fixed bug for RX counters. On an RX overflow interrupt the high
308 * words of all RX counters were incremented.
309 * -SET operations on FLOWCTRL_MODE and LINK_MODE accept now the
310 * value 0, which has no effect. It is usefull for multiple instance
313 * Revision 1.37 1998/11/20 08:02:04 mhaveman
314 * -Fixed: Ports were compared with MAX_SENSORS
315 * -Fixed: Crash in GetTrapEntry with MEMSET macro
316 * -Fixed: Conversions between physical, logical port index and instance
318 * Revision 1.36 1998/11/16 07:48:53 mhaveman
319 * Casted SK_DRIVER_SENDEVENT with (void) to eleminate compiler warnings
322 * Revision 1.35 1998/11/16 07:45:34 mhaveman
323 * SkAddrOverride now returns value and will be checked.
325 * Revision 1.34 1998/11/10 13:40:37 mhaveman
326 * Needed to change interface, because NT driver needs a return value
327 * of needed buffer space on TOO_SHORT errors. Therefore all
328 * SkPnmiGet/Preset/Set functions now have a pointer to the length
329 * parameter, where the needed space on error is returned.
331 * Revision 1.33 1998/11/03 13:52:46 mhaveman
332 * Made file lint conform.
334 * Revision 1.32 1998/11/03 13:19:07 mhaveman
335 * The events SK_HWEV_SET_LMODE and SK_HWEV_SET_FLOWMODE pass now in
336 * Para32[0] the physical MAC index and in Para32[1] the new mode.
338 * Revision 1.31 1998/11/03 12:30:40 gklug
339 * fix: compiler warning memset
341 * Revision 1.30 1998/11/03 12:04:46 mhaveman
342 * Fixed problem in SENSOR_VALUE, which wrote beyond the buffer end
343 * Fixed alignment problem with CHIPSET.
345 * Revision 1.29 1998/11/02 11:23:54 mhaveman
346 * Corrected SK_ERROR_LOG to SK_ERR_LOG. Sorry.
348 * Revision 1.28 1998/11/02 10:47:16 mhaveman
349 * Added syslog messages for internal errors.
351 * Revision 1.27 1998/10/30 15:48:06 mhaveman
352 * Fixed problems after simulation of SK_PNMI_EVT_CHG_EST_TIMER and
353 * RlmtChangeThreshold calculation.
355 * Revision 1.26 1998/10/29 15:36:55 mhaveman
356 * -Fixed bug in trap buffer handling.
357 * -OID_SKGE_DRIVER_DESCR, OID_SKGE_DRIVER_VERSION, OID_SKGE_HW_DESCR,
358 * OID_SKGE_HW_VERSION, OID_SKGE_VPD_ENTRIES_LIST, OID_SKGE_VPD_KEY,
359 * OID_SKGE_VPD_VALUE, and OID_SKGE_SENSOR_DESCR return values with
360 * a leading octet before each string storing the string length.
361 * -Perform a RlmtUpdate during SK_PNMI_EVT_XMAC_RESET to minimize
362 * RlmtUpdate calls in GetStatVal.
363 * -Inserted SK_PNMI_CHECKFLAGS macro increase readability.
365 * Revision 1.25 1998/10/29 08:50:36 mhaveman
366 * Fixed problems after second event simulation.
368 * Revision 1.24 1998/10/28 08:44:37 mhaveman
369 * -Fixed alignment problem
370 * -Fixed problems during event simulation
371 * -Fixed sequence of error return code (INSTANCE -> ACCESS -> SHORT)
372 * -Changed type of parameter Instance back to SK_U32 because of VPD
373 * -Updated new VPD function calls
375 * Revision 1.23 1998/10/23 10:16:37 mhaveman
376 * Fixed bugs after buffer test simulation.
378 * Revision 1.22 1998/10/21 13:23:52 mhaveman
379 * -Call syntax of SkOsGetTime() changed to SkOsGetTime(pAc).
380 * -Changed calculation of hundrets of seconds.
382 * Revision 1.20 1998/10/20 07:30:45 mhaveman
383 * Made type changes to unsigned integer where possible.
385 * Revision 1.19 1998/10/19 10:51:30 mhaveman
386 * -Made Bug fixes after simulation run
387 * -Renamed RlmtMAC... to RlmtPort...
388 * -Marked workarounds with Errata comments
390 * Revision 1.18 1998/10/14 07:50:08 mhaveman
391 * -For OID_SKGE_LINK_STATUS the link down detection has moved from RLMT
393 * -Provided all MEMCPY/MEMSET macros with (char *) pointers, because
394 * Solaris throwed warnings when mapping to bcopy/bset.
396 * Revision 1.17 1998/10/13 07:42:01 mhaveman
397 * -Added OIDs OID_SKGE_TRAP_NUMBER and OID_SKGE_ALL_DATA
398 * -Removed old cvs history entries
399 * -Renamed MacNumber to PortNumber
401 * Revision 1.16 1998/10/07 10:52:49 mhaveman
402 * -Inserted handling of some OID_GEN_ Ids for windows
403 * -Fixed problem with 803.2 statistic.
405 * Revision 1.15 1998/10/01 09:16:29 mhaveman
406 * Added Debug messages for function call and UpdateFlag tracing.
408 * Revision 1.14 1998/09/30 13:39:09 mhaveman
409 * -Reduced namings of 'MAC' by replacing them with 'PORT'.
410 * -Completed counting of OID_SKGE_RX_HW_ERROR_CTS,
411 * OID_SKGE_TX_HW_ERROR_CTS,
412 * OID_SKGE_IN_ERRORS_CTS, and OID_SKGE_OUT_ERROR_CTS.
413 * -SET check for RlmtMode
415 * Revision 1.13 1998/09/28 13:13:08 mhaveman
416 * Hide strcmp, strlen, and strncpy behind macros SK_STRCMP, SK_STRLEN,
417 * and SK_STRNCPY. (Same reasons as for mem.. and MEM..)
419 * Revision 1.12 1998/09/16 08:18:36 cgoos
420 * Fix: XM_INxx and XM_OUTxx called with different parameter order:
421 * sometimes IoC,Mac,... sometimes Mac,IoC,... Now always first variant.
422 * Fix: inserted "Pnmi." into some pAC->pDriverDescription / Version.
423 * Change: memset, memcpy to makros SK_MEMSET, SK_MEMCPY
425 * Revision 1.11 1998/09/04 17:01:45 mhaveman
426 * Added SyncCounter as macro and OID_SKGE_.._NO_DESCR_CTS to
427 * OID_SKGE_RX_NO_BUF_CTS.
429 * Revision 1.10 1998/09/04 14:35:35 mhaveman
430 * Added macro counters, that are counted by driver.
432 ****************************************************************************/
439 static const char SysKonnectFileId[] =
440 "@(#) $Id: skgepnmi.c,v 1.102 2002/12/16 14:03:24 tschilli Exp $"
443 #include "h/skdrv1st.h"
444 #include "h/sktypes.h"
445 #include "h/xmac_ii.h"
446 #include "h/skdebug.h"
447 #include "h/skqueue.h"
448 #include "h/skgepnmi.h"
449 #include "h/skgesirq.h"
450 #include "h/skcsum.h"
452 #include "h/skgehw.h"
453 #include "h/skgeinit.h"
454 #include "h/skdrv2nd.h"
455 #include "h/skgepnm2.h"
457 #include "h/skgepmgt.h"
459 /* defines *******************************************************************/
462 #define PNMI_STATIC static
468 * Public Function prototypes
470 int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level);
471 int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
472 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
473 int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
474 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
475 int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
476 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
477 int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
478 unsigned int *pLen, SK_U32 NetIndex);
479 int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
480 unsigned int *pLen, SK_U32 NetIndex);
481 int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
482 unsigned int *pLen, SK_U32 NetIndex);
483 int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
487 * Private Function prototypes
490 PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
492 PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
494 PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac);
495 PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
496 PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
497 unsigned int PhysPortIndex, unsigned int StatIndex);
498 PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
499 unsigned int StatIndex, SK_U32 NetIndex);
500 PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
501 PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
502 unsigned int *pEntries);
503 PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr,
504 unsigned int KeyArrLen, unsigned int *pKeyNo);
505 PNMI_STATIC int LookupId(SK_U32 Id);
506 PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
507 unsigned int LastMac);
508 PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
509 unsigned int *pLen, SK_U32 NetIndex);
510 PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id,
511 char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
512 PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
513 PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
514 unsigned int PortIndex);
515 PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
516 unsigned int SensorIndex);
517 PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
518 PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
519 PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
520 PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
521 PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
522 PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
523 unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
524 PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
527 * Table to correlate OID with handler function and index to
528 * hardware register stored in StatAddress if applicable.
532 /* global variables **********************************************************/
535 * Overflow status register bit table and corresponding counter
536 * dependent on MAC type - the number relates to the size of overflow
537 * mask returned by the pFnMacOverflow function
539 PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = {
540 /* Bit0 */ { SK_PNMI_HTX, SK_PNMI_HTX_UNICAST},
541 /* Bit1 */ { SK_PNMI_HTX_OCTETHIGH, SK_PNMI_HTX_BROADCAST},
542 /* Bit2 */ { SK_PNMI_HTX_OCTETLOW, SK_PNMI_HTX_PMACC},
543 /* Bit3 */ { SK_PNMI_HTX_BROADCAST, SK_PNMI_HTX_MULTICAST},
544 /* Bit4 */ { SK_PNMI_HTX_MULTICAST, SK_PNMI_HTX_OCTETLOW},
545 /* Bit5 */ { SK_PNMI_HTX_UNICAST, SK_PNMI_HTX_OCTETHIGH},
546 /* Bit6 */ { SK_PNMI_HTX_LONGFRAMES, SK_PNMI_HTX_64},
547 /* Bit7 */ { SK_PNMI_HTX_BURST, SK_PNMI_HTX_127},
548 /* Bit8 */ { SK_PNMI_HTX_PMACC, SK_PNMI_HTX_255},
549 /* Bit9 */ { SK_PNMI_HTX_MACC, SK_PNMI_HTX_511},
550 /* Bit10 */ { SK_PNMI_HTX_SINGLE_COL, SK_PNMI_HTX_1023},
551 /* Bit11 */ { SK_PNMI_HTX_MULTI_COL, SK_PNMI_HTX_MAX},
552 /* Bit12 */ { SK_PNMI_HTX_EXCESS_COL, SK_PNMI_HTX_LONGFRAMES},
553 /* Bit13 */ { SK_PNMI_HTX_LATE_COL, SK_PNMI_HTX_RESERVED},
554 /* Bit14 */ { SK_PNMI_HTX_DEFFERAL, SK_PNMI_HTX_COL},
555 /* Bit15 */ { SK_PNMI_HTX_EXCESS_DEF, SK_PNMI_HTX_LATE_COL},
556 /* Bit16 */ { SK_PNMI_HTX_UNDERRUN, SK_PNMI_HTX_EXCESS_COL},
557 /* Bit17 */ { SK_PNMI_HTX_CARRIER, SK_PNMI_HTX_MULTI_COL},
558 /* Bit18 */ { SK_PNMI_HTX_UTILUNDER, SK_PNMI_HTX_SINGLE_COL},
559 /* Bit19 */ { SK_PNMI_HTX_UTILOVER, SK_PNMI_HTX_UNDERRUN},
560 /* Bit20 */ { SK_PNMI_HTX_64, SK_PNMI_HTX_RESERVED},
561 /* Bit21 */ { SK_PNMI_HTX_127, SK_PNMI_HTX_RESERVED},
562 /* Bit22 */ { SK_PNMI_HTX_255, SK_PNMI_HTX_RESERVED},
563 /* Bit23 */ { SK_PNMI_HTX_511, SK_PNMI_HTX_RESERVED},
564 /* Bit24 */ { SK_PNMI_HTX_1023, SK_PNMI_HTX_RESERVED},
565 /* Bit25 */ { SK_PNMI_HTX_MAX, SK_PNMI_HTX_RESERVED},
566 /* Bit26 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
567 /* Bit27 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
568 /* Bit28 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
569 /* Bit29 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
570 /* Bit30 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
571 /* Bit31 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
572 /* Bit32 */ { SK_PNMI_HRX, SK_PNMI_HRX_UNICAST},
573 /* Bit33 */ { SK_PNMI_HRX_OCTETHIGH, SK_PNMI_HRX_BROADCAST},
574 /* Bit34 */ { SK_PNMI_HRX_OCTETLOW, SK_PNMI_HRX_PMACC},
575 /* Bit35 */ { SK_PNMI_HRX_BROADCAST, SK_PNMI_HRX_MULTICAST},
576 /* Bit36 */ { SK_PNMI_HRX_MULTICAST, SK_PNMI_HRX_FCS},
577 /* Bit37 */ { SK_PNMI_HRX_UNICAST, SK_PNMI_HRX_RESERVED},
578 /* Bit38 */ { SK_PNMI_HRX_PMACC, SK_PNMI_HRX_OCTETLOW},
579 /* Bit39 */ { SK_PNMI_HRX_MACC, SK_PNMI_HRX_OCTETHIGH},
580 /* Bit40 */ { SK_PNMI_HRX_PMACC_ERR, SK_PNMI_HRX_BADOCTETLOW},
581 /* Bit41 */ { SK_PNMI_HRX_MACC_UNKWN, SK_PNMI_HRX_BADOCTETHIGH},
582 /* Bit42 */ { SK_PNMI_HRX_BURST, SK_PNMI_HRX_UNDERSIZE},
583 /* Bit43 */ { SK_PNMI_HRX_MISSED, SK_PNMI_HRX_RUNT},
584 /* Bit44 */ { SK_PNMI_HRX_FRAMING, SK_PNMI_HRX_64},
585 /* Bit45 */ { SK_PNMI_HRX_OVERFLOW, SK_PNMI_HRX_127},
586 /* Bit46 */ { SK_PNMI_HRX_JABBER, SK_PNMI_HRX_255},
587 /* Bit47 */ { SK_PNMI_HRX_CARRIER, SK_PNMI_HRX_511},
588 /* Bit48 */ { SK_PNMI_HRX_IRLENGTH, SK_PNMI_HRX_1023},
589 /* Bit49 */ { SK_PNMI_HRX_SYMBOL, SK_PNMI_HRX_MAX},
590 /* Bit50 */ { SK_PNMI_HRX_SHORTS, SK_PNMI_HRX_LONGFRAMES},
591 /* Bit51 */ { SK_PNMI_HRX_RUNT, SK_PNMI_HRX_TOO_LONG},
592 /* Bit52 */ { SK_PNMI_HRX_TOO_LONG, SK_PNMI_HRX_JABBER},
593 /* Bit53 */ { SK_PNMI_HRX_FCS, SK_PNMI_HRX_RESERVED},
594 /* Bit54 */ { SK_PNMI_HRX_RESERVED, SK_PNMI_HRX_OVERFLOW},
595 /* Bit55 */ { SK_PNMI_HRX_CEXT, SK_PNMI_HRX_RESERVED},
596 /* Bit56 */ { SK_PNMI_HRX_UTILUNDER, SK_PNMI_HRX_RESERVED},
597 /* Bit57 */ { SK_PNMI_HRX_UTILOVER, SK_PNMI_HRX_RESERVED},
598 /* Bit58 */ { SK_PNMI_HRX_64, SK_PNMI_HRX_RESERVED},
599 /* Bit59 */ { SK_PNMI_HRX_127, SK_PNMI_HRX_RESERVED},
600 /* Bit60 */ { SK_PNMI_HRX_255, SK_PNMI_HRX_RESERVED},
601 /* Bit61 */ { SK_PNMI_HRX_511, SK_PNMI_HRX_RESERVED},
602 /* Bit62 */ { SK_PNMI_HRX_1023, SK_PNMI_HRX_RESERVED},
603 /* Bit63 */ { SK_PNMI_HRX_MAX, SK_PNMI_HRX_RESERVED}
607 * Table for hardware register saving on resets and port switches
609 PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = {
611 {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}},
612 /* SK_PNMI_HTX_OCTETHIGH */
613 {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}},
614 /* SK_PNMI_HTX_OCTETLOW */
615 {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}},
616 /* SK_PNMI_HTX_BROADCAST */
617 {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}},
618 /* SK_PNMI_HTX_MULTICAST */
619 {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}},
620 /* SK_PNMI_HTX_UNICAST */
621 {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}},
622 /* SK_PNMI_HTX_BURST */
623 {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}},
624 /* SK_PNMI_HTX_PMACC */
625 {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}},
626 /* SK_PNMI_HTX_MACC */
627 {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
628 /* SK_PNMI_HTX_COL */
629 {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}},
630 /* SK_PNMI_HTX_SINGLE_COL */
631 {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}},
632 /* SK_PNMI_HTX_MULTI_COL */
633 {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}},
634 /* SK_PNMI_HTX_EXCESS_COL */
635 {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}},
636 /* SK_PNMI_HTX_LATE_COL */
637 {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}},
638 /* SK_PNMI_HTX_DEFFERAL */
639 {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}},
640 /* SK_PNMI_HTX_EXCESS_DEF */
641 {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}},
642 /* SK_PNMI_HTX_UNDERRUN */
643 {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}},
644 /* SK_PNMI_HTX_CARRIER */
645 {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}},
646 /* SK_PNMI_HTX_UTILUNDER */
647 {{0, SK_FALSE}, {0, SK_FALSE}},
648 /* SK_PNMI_HTX_UTILOVER */
649 {{0, SK_FALSE}, {0, SK_FALSE}},
651 {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}},
652 /* SK_PNMI_HTX_127 */
653 {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}},
654 /* SK_PNMI_HTX_255 */
655 {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}},
656 /* SK_PNMI_HTX_511 */
657 {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}},
658 /* SK_PNMI_HTX_1023 */
659 {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}},
660 /* SK_PNMI_HTX_MAX */
661 {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}},
662 /* SK_PNMI_HTX_LONGFRAMES */
663 {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}},
664 /* SK_PNMI_HTX_SYNC */
665 {{0, SK_FALSE}, {0, SK_FALSE}},
666 /* SK_PNMI_HTX_SYNC_OCTET */
667 {{0, SK_FALSE}, {0, SK_FALSE}},
668 /* SK_PNMI_HTX_RESERVED */
669 {{0, SK_FALSE}, {0, SK_FALSE}},
671 {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}},
672 /* SK_PNMI_HRX_OCTETHIGH */
673 {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}},
674 /* SK_PNMI_HRX_OCTETLOW */
675 {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}},
676 /* SK_PNMI_HRX_BADOCTETHIGH */
677 {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}},
678 /* SK_PNMI_HRX_BADOCTETLOW */
679 {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}},
680 /* SK_PNMI_HRX_BROADCAST */
681 {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}},
682 /* SK_PNMI_HRX_MULTICAST */
683 {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}},
684 /* SK_PNMI_HRX_UNICAST */
685 {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}},
686 /* SK_PNMI_HRX_PMACC */
687 {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}},
688 /* SK_PNMI_HRX_MACC */
689 {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
690 /* SK_PNMI_HRX_PMACC_ERR */
691 {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}},
692 /* SK_PNMI_HRX_MACC_UNKWN */
693 {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}},
694 /* SK_PNMI_HRX_BURST */
695 {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}},
696 /* SK_PNMI_HRX_MISSED */
697 {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}},
698 /* SK_PNMI_HRX_FRAMING */
699 {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}},
700 /* SK_PNMI_HRX_UNDERSIZE */
701 {{0, SK_FALSE},{GM_RXF_SHT, SK_TRUE}},
702 /* SK_PNMI_HRX_OVERFLOW */
703 {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}},
704 /* SK_PNMI_HRX_JABBER */
705 {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}},
706 /* SK_PNMI_HRX_CARRIER */
707 {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}},
708 /* SK_PNMI_HRX_IRLENGTH */
709 {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}},
710 /* SK_PNMI_HRX_SYMBOL */
711 {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}},
712 /* SK_PNMI_HRX_SHORTS */
713 {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}},
714 /* SK_PNMI_HRX_RUNT */
715 {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}},
716 /* SK_PNMI_HRX_TOO_LONG */
717 {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}},
718 /* SK_PNMI_HRX_FCS */
719 {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}},
720 /* SK_PNMI_HRX_CEXT */
721 {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}},
722 /* SK_PNMI_HRX_UTILUNDER */
723 {{0, SK_FALSE}, {0, SK_FALSE}},
724 /* SK_PNMI_HRX_UTILOVER */
725 {{0, SK_FALSE}, {0, SK_FALSE}},
727 {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}},
728 /* SK_PNMI_HRX_127 */
729 {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}},
730 /* SK_PNMI_HRX_255 */
731 {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}},
732 /* SK_PNMI_HRX_511 */
733 {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}},
734 /* SK_PNMI_HRX_1023 */
735 {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}},
736 /* SK_PNMI_HRX_MAX */
737 {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}},
738 /* SK_PNMI_HRX_LONGFRAMES */
739 {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}},
740 /* SK_PNMI_HRX_RESERVED */
741 {{0, SK_FALSE}, {0, SK_FALSE}}
745 /*****************************************************************************
751 /*****************************************************************************
753 * SkPnmiInit - Init function of PNMI
756 * SK_INIT_DATA: Initialises the data structures
757 * SK_INIT_IO: Resets the XMAC statistics, determines the device and
759 * SK_INIT_RUN: Starts a timer event for port switch per hour
766 SK_AC *pAC, /* Pointer to adapter context */
767 SK_IOC IoC, /* IO context handle */
768 int Level) /* Initialization level */
770 unsigned int PortMax; /* Number of ports */
771 unsigned int PortIndex; /* Current port index in loop */
772 SK_U16 Val16; /* Multiple purpose 16 bit variable */
773 SK_U8 Val8; /* Mulitple purpose 8 bit variable */
774 SK_EVPARA EventParam; /* Event struct for timer event */
776 SK_PNMI_VCT *pVctBackupData;
779 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
780 ("PNMI: SkPnmiInit: Called, level=%d\n", Level));
785 SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
786 pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
787 pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
788 pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
789 for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
791 pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
792 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
796 if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) {
798 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG);
800 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
801 ("CounterOffset struct size (%d) differs from"
802 "SK_PNMI_MAX_IDX (%d)\n",
803 SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
807 if (SK_PNMI_MAX_IDX !=
808 (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) {
810 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG);
812 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
813 ("StatAddr table size (%d) differs from "
814 "SK_PNMI_MAX_IDX (%d)\n",
816 (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)),
820 #endif /* SK_PNMI_CHECK */
827 PortMax = pAC->GIni.GIMacsFound;
829 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
831 pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
834 /* Initialize DSP variables for Vct() to 0xff => Never written! */
835 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
836 pPrt = &pAC->GIni.GP[PortIndex];
837 pPrt->PCableLen =0xff;
838 pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
839 pVctBackupData->PCableLen = 0xff;
845 SK_IN16(IoC, B0_CTST, &Val16);
846 if ((Val16 & CS_BUS_CLOCK) == 0) {
848 pAC->Pnmi.PciBusSpeed = 33;
851 pAC->Pnmi.PciBusSpeed = 66;
857 SK_IN16(IoC, B0_CTST, &Val16);
858 if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
860 pAC->Pnmi.PciBusWidth = 32;
863 pAC->Pnmi.PciBusWidth = 64;
869 switch (pAC->GIni.GIChipId) {
870 case CHIP_ID_GENESIS:
871 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
875 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
883 * Get PMD and DeviceType
885 SK_IN8(IoC, B2_PMD_TYP, &Val8);
889 if (pAC->GIni.GIMacsFound > 1) {
891 pAC->Pnmi.DeviceType = 0x00020002;
894 pAC->Pnmi.DeviceType = 0x00020001;
900 if (pAC->GIni.GIMacsFound > 1) {
902 pAC->Pnmi.DeviceType = 0x00020004;
905 pAC->Pnmi.DeviceType = 0x00020003;
911 if (pAC->GIni.GIMacsFound > 1) {
913 pAC->Pnmi.DeviceType = 0x00020006;
916 pAC->Pnmi.DeviceType = 0x00020005;
922 if (pAC->GIni.GIMacsFound > 1) {
924 pAC->Pnmi.DeviceType = 0x00020008;
927 pAC->Pnmi.DeviceType = 0x00020007;
933 pAC->Pnmi.DeviceType = 0;
940 SK_IN8(IoC, B2_CONN_TYP, &Val8);
943 pAC->Pnmi.Connector = 2;
947 pAC->Pnmi.Connector = 3;
951 pAC->Pnmi.Connector = 4;
955 pAC->Pnmi.Connector = 5;
959 pAC->Pnmi.Connector = 6;
963 pAC->Pnmi.Connector = 1;
970 * Start timer for RLMT change counter
972 SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
973 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
974 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
979 break; /* Nothing todo */
985 /*****************************************************************************
987 * SkPnmiGetVar - Retrieves the value of a single OID
990 * Calls a general sub-function for all this stuff. If the instance
991 * -1 is passed, the values of all instances are returned in an
995 * SK_PNMI_ERR_OK The request was successfully performed
996 * SK_PNMI_ERR_GENERAL A general severe internal error occured
997 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
999 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
1000 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1001 * exist (e.g. port instance 3 on a two port
1005 SK_AC *pAC, /* Pointer to adapter context */
1006 SK_IOC IoC, /* IO context handle */
1007 SK_U32 Id, /* Object ID that is to be processed */
1008 void *pBuf, /* Buffer to which to mgmt data will be retrieved */
1009 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
1010 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
1011 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1013 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1014 ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
1015 Id, *pLen, Instance, NetIndex));
1017 return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
1018 Instance, NetIndex));
1021 /*****************************************************************************
1023 * SkPnmiPreSetVar - Presets the value of a single OID
1026 * Calls a general sub-function for all this stuff. The preset does
1027 * the same as a set, but returns just before finally setting the
1028 * new value. This is usefull to check if a set might be successfull.
1029 * If as instance a -1 is passed, an array of values is supposed and
1030 * all instance of the OID will be set.
1033 * SK_PNMI_ERR_OK The request was successfully performed.
1034 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1035 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1036 * the correct data (e.g. a 32bit value is
1037 * needed, but a 16 bit value was passed).
1038 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1040 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
1041 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
1042 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1043 * exist (e.g. port instance 3 on a two port
1046 int SkPnmiPreSetVar(
1047 SK_AC *pAC, /* Pointer to adapter context */
1048 SK_IOC IoC, /* IO context handle */
1049 SK_U32 Id, /* Object ID that is to be processed */
1050 void *pBuf, /* Buffer which stores the mgmt data to be set */
1051 unsigned int *pLen, /* Total length of mgmt data */
1052 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
1053 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1055 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1056 ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
1057 Id, *pLen, Instance, NetIndex));
1060 return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
1061 Instance, NetIndex));
1064 /*****************************************************************************
1066 * SkPnmiSetVar - Sets the value of a single OID
1069 * Calls a general sub-function for all this stuff. The preset does
1070 * the same as a set, but returns just before finally setting the
1071 * new value. This is usefull to check if a set might be successfull.
1072 * If as instance a -1 is passed, an array of values is supposed and
1073 * all instance of the OID will be set.
1076 * SK_PNMI_ERR_OK The request was successfully performed.
1077 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1078 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1079 * the correct data (e.g. a 32bit value is
1080 * needed, but a 16 bit value was passed).
1081 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1083 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
1084 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
1085 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1086 * exist (e.g. port instance 3 on a two port
1090 SK_AC *pAC, /* Pointer to adapter context */
1091 SK_IOC IoC, /* IO context handle */
1092 SK_U32 Id, /* Object ID that is to be processed */
1093 void *pBuf, /* Buffer which stores the mgmt data to be set */
1094 unsigned int *pLen, /* Total length of mgmt data */
1095 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
1096 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1098 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1099 ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
1100 Id, *pLen, Instance, NetIndex));
1102 return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
1103 Instance, NetIndex));
1106 /*****************************************************************************
1108 * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA
1111 * Runs through the IdTable, queries the single OIDs and stores the
1112 * returned data into the management database structure
1113 * SK_PNMI_STRUCT_DATA. The offset of the OID in the structure
1114 * is stored in the IdTable. The return value of the function will also
1115 * be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
1116 * minimum size of SK_PNMI_MIN_STRUCT_SIZE.
1119 * SK_PNMI_ERR_OK The request was successfully performed
1120 * SK_PNMI_ERR_GENERAL A general severe internal error occured
1121 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
1123 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
1125 int SkPnmiGetStruct(
1126 SK_AC *pAC, /* Pointer to adapter context */
1127 SK_IOC IoC, /* IO context handle */
1128 void *pBuf, /* Buffer which will store the retrieved data */
1129 unsigned int *pLen, /* Length of buffer */
1130 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1133 unsigned int TableIndex;
1134 unsigned int DstOffset;
1135 unsigned int InstanceNo;
1136 unsigned int InstanceCnt;
1138 unsigned int TmpLen;
1139 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
1142 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1143 ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
1146 if (*pLen < SK_PNMI_STRUCT_SIZE) {
1148 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
1150 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
1154 *pLen = SK_PNMI_STRUCT_SIZE;
1155 return (SK_PNMI_ERR_TOO_SHORT);
1161 if (NetIndex >= pAC->Rlmt.NumNets) {
1162 return (SK_PNMI_ERR_UNKNOWN_NET);
1165 /* Update statistic */
1166 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
1168 if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
1171 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1172 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1176 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
1178 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1179 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1183 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
1185 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1186 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1191 * Increment semaphores to indicate that an update was
1194 pAC->Pnmi.MacUpdatedFlag ++;
1195 pAC->Pnmi.RlmtUpdatedFlag ++;
1196 pAC->Pnmi.SirqUpdatedFlag ++;
1198 /* Get vpd keys for instance calculation */
1199 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
1200 if (Ret != SK_PNMI_ERR_OK) {
1202 pAC->Pnmi.MacUpdatedFlag --;
1203 pAC->Pnmi.RlmtUpdatedFlag --;
1204 pAC->Pnmi.SirqUpdatedFlag --;
1206 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
1207 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1208 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1209 return (SK_PNMI_ERR_GENERAL);
1212 /* Retrieve values */
1213 SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
1214 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
1216 InstanceNo = IdTable[TableIndex].InstanceNo;
1217 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
1220 DstOffset = IdTable[TableIndex].Offset +
1222 IdTable[TableIndex].StructSize;
1225 * For the VPD the instance is not an index number
1226 * but the key itself. Determin with the instance
1227 * counter the VPD key to be used.
1229 if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
1230 IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
1231 IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
1232 IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
1234 SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
1237 Instance = (SK_U32)InstanceCnt;
1240 TmpLen = *pLen - DstOffset;
1241 Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
1242 IdTable[TableIndex].Id, (char *)pBuf +
1243 DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
1246 * An unknown instance error means that we reached
1247 * the last instance of that variable. Proceed with
1248 * the next OID in the table and ignore the return
1251 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
1256 if (Ret != SK_PNMI_ERR_OK) {
1258 pAC->Pnmi.MacUpdatedFlag --;
1259 pAC->Pnmi.RlmtUpdatedFlag --;
1260 pAC->Pnmi.SirqUpdatedFlag --;
1262 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
1263 SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
1264 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1270 pAC->Pnmi.MacUpdatedFlag --;
1271 pAC->Pnmi.RlmtUpdatedFlag --;
1272 pAC->Pnmi.SirqUpdatedFlag --;
1274 *pLen = SK_PNMI_STRUCT_SIZE;
1275 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
1276 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
1277 return (SK_PNMI_ERR_OK);
1280 /*****************************************************************************
1282 * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
1285 * Calls a general sub-function for all this set stuff. The preset does
1286 * the same as a set, but returns just before finally setting the
1287 * new value. This is usefull to check if a set might be successfull.
1288 * The sub-function runs through the IdTable, checks which OIDs are able
1289 * to set, and calls the handler function of the OID to perform the
1290 * preset. The return value of the function will also be stored in
1291 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
1292 * SK_PNMI_MIN_STRUCT_SIZE.
1295 * SK_PNMI_ERR_OK The request was successfully performed.
1296 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1297 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1298 * the correct data (e.g. a 32bit value is
1299 * needed, but a 16 bit value was passed).
1300 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1303 int SkPnmiPreSetStruct(
1304 SK_AC *pAC, /* Pointer to adapter context */
1305 SK_IOC IoC, /* IO context handle */
1306 void *pBuf, /* Buffer which contains the data to be set */
1307 unsigned int *pLen, /* Length of buffer */
1308 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1310 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1311 ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
1314 return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf,
1318 /*****************************************************************************
1320 * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA
1323 * Calls a general sub-function for all this set stuff. The return value
1324 * of the function will also be stored in SK_PNMI_STRUCT_DATA if the
1325 * passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE.
1326 * The sub-function runs through the IdTable, checks which OIDs are able
1327 * to set, and calls the handler function of the OID to perform the
1328 * set. The return value of the function will also be stored in
1329 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
1330 * SK_PNMI_MIN_STRUCT_SIZE.
1333 * SK_PNMI_ERR_OK The request was successfully performed.
1334 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1335 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1336 * the correct data (e.g. a 32bit value is
1337 * needed, but a 16 bit value was passed).
1338 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1341 int SkPnmiSetStruct(
1342 SK_AC *pAC, /* Pointer to adapter context */
1343 SK_IOC IoC, /* IO context handle */
1344 void *pBuf, /* Buffer which contains the data to be set */
1345 unsigned int *pLen, /* Length of buffer */
1346 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1348 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1349 ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
1352 return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf,
1356 /*****************************************************************************
1358 * SkPnmiEvent - Event handler
1361 * Handles the following events:
1362 * SK_PNMI_EVT_SIRQ_OVERFLOW When a hardware counter overflows an
1363 * interrupt will be generated which is
1364 * first handled by SIRQ which generates a
1365 * this event. The event increments the
1366 * upper 32 bit of the 64 bit counter.
1367 * SK_PNMI_EVT_SEN_XXX The event is generated by the I2C module
1368 * when a sensor reports a warning or
1369 * error. The event will store a trap
1370 * message in the trap buffer.
1371 * SK_PNMI_EVT_CHG_EST_TIMER The timer event was initiated by this
1372 * module and is used to calculate the
1373 * port switches per hour.
1374 * SK_PNMI_EVT_CLEAR_COUNTER The event clears all counters and
1376 * SK_PNMI_EVT_XMAC_RESET The event is generated by the driver
1377 * before a hard reset of the XMAC is
1378 * performed. All counters will be saved
1379 * and added to the hardware counter
1380 * values after reset to grant continuous
1382 * SK_PNMI_EVT_RLMT_PORT_UP Generated by RLMT to notify that a port
1383 * went logically up. A trap message will
1384 * be stored to the trap buffer.
1385 * SK_PNMI_EVT_RLMT_PORT_DOWN Generated by RLMT to notify that a port
1386 * went logically down. A trap message will
1387 * be stored to the trap buffer.
1388 * SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
1389 * spanning tree root bridges were
1390 * detected. A trap message will be stored
1391 * to the trap buffer.
1392 * SK_PNMI_EVT_RLMT_ACTIVE_DOWN Notifies PNMI that an active port went
1393 * down. PNMI will not further add the
1394 * statistic values to the virtual port.
1395 * SK_PNMI_EVT_RLMT_ACTIVE_UP Notifies PNMI that a port went up and
1396 * is now an active port. PNMI will now
1397 * add the statistic data of this port to
1399 * SK_PNMI_EVT_RLMT_SET_NETS Notifies PNMI about the net mode. The first Parameter
1400 * contains the number of nets. 1 means single net, 2 means
1401 * dual net. The second Parameter is -1
1407 SK_AC *pAC, /* Pointer to adapter context */
1408 SK_IOC IoC, /* IO context handle */
1409 SK_U32 Event, /* Event-Id */
1410 SK_EVPARA Param) /* Event dependent parameter */
1412 unsigned int PhysPortIndex;
1413 unsigned int MaxNetNumber;
1417 SK_U64 OverflowStatus;
1423 SK_EVPARA EventParam;
1427 SK_PNMI_ESTIMATE *pEst;
1430 SK_PNMI_VCT *pVctBackupData;
1437 if (Event != SK_PNMI_EVT_XMAC_RESET) {
1439 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1440 ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n",
1441 (unsigned int)Event, (unsigned int)Param.Para64));
1444 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call");
1446 MacType = pAC->GIni.GIMacType;
1450 case SK_PNMI_EVT_SIRQ_OVERFLOW:
1451 PhysPortIndex = (int)Param.Para32[0];
1452 MacStatus = (SK_U16)Param.Para32[1];
1454 if (PhysPortIndex >= SK_MAX_MACS) {
1456 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1457 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter"
1458 " wrong, PhysPortIndex=0x%x\n",
1466 * Check which source caused an overflow interrupt.
1468 if ((pAC->GIni.GIFunc.pFnMacOverflow(
1469 pAC, IoC, PhysPortIndex, MacStatus, &OverflowStatus) != 0) ||
1470 (OverflowStatus == 0)) {
1472 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1477 * Check the overflow status register and increment
1478 * the upper dword of corresponding counter.
1480 for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8;
1483 Mask = (SK_U64)1 << CounterIndex;
1484 if ((OverflowStatus & Mask) == 0) {
1489 switch (StatOvrflwBit[CounterIndex][MacType]) {
1491 case SK_PNMI_HTX_UTILUNDER:
1492 case SK_PNMI_HTX_UTILOVER:
1493 XM_IN16(IoC, PhysPortIndex, XM_TX_CMD,
1495 Register |= XM_TX_SAM_LINE;
1496 XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD,
1500 case SK_PNMI_HRX_UTILUNDER:
1501 case SK_PNMI_HRX_UTILOVER:
1502 XM_IN16(IoC, PhysPortIndex, XM_RX_CMD,
1504 Register |= XM_RX_SAM_LINE;
1505 XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD,
1509 case SK_PNMI_HTX_OCTETHIGH:
1510 case SK_PNMI_HTX_OCTETLOW:
1511 case SK_PNMI_HTX_RESERVED:
1512 case SK_PNMI_HRX_OCTETHIGH:
1513 case SK_PNMI_HRX_OCTETLOW:
1514 case SK_PNMI_HRX_IRLENGTH:
1515 case SK_PNMI_HRX_RESERVED:
1518 * the following counters aren't be handled (id > 63)
1520 case SK_PNMI_HTX_SYNC:
1521 case SK_PNMI_HTX_SYNC_OCTET:
1524 case SK_PNMI_HRX_LONGFRAMES:
1525 if (MacType == SK_MAC_GMAC) {
1526 pAC->Pnmi.Port[PhysPortIndex].
1527 CounterHigh[CounterIndex] ++;
1532 pAC->Pnmi.Port[PhysPortIndex].
1533 CounterHigh[CounterIndex] ++;
1538 case SK_PNMI_EVT_SEN_WAR_LOW:
1540 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1542 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1543 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n",
1544 (unsigned int)Param.Para64));
1549 * Store a trap message in the trap buffer and generate
1550 * an event for user space applications with the
1551 * SK_DRIVER_SENDEVENT macro.
1553 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW,
1554 (unsigned int)Param.Para64);
1555 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1558 case SK_PNMI_EVT_SEN_WAR_UPP:
1560 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1562 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1563 ("PNMI: ERR:SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n",
1564 (unsigned int)Param.Para64));
1569 * Store a trap message in the trap buffer and generate
1570 * an event for user space applications with the
1571 * SK_DRIVER_SENDEVENT macro.
1573 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP,
1574 (unsigned int)Param.Para64);
1575 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1578 case SK_PNMI_EVT_SEN_ERR_LOW:
1580 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1582 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1583 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n",
1584 (unsigned int)Param.Para64));
1589 * Store a trap message in the trap buffer and generate
1590 * an event for user space applications with the
1591 * SK_DRIVER_SENDEVENT macro.
1593 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW,
1594 (unsigned int)Param.Para64);
1595 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1598 case SK_PNMI_EVT_SEN_ERR_UPP:
1600 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1602 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1603 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
1604 (unsigned int)Param.Para64));
1609 * Store a trap message in the trap buffer and generate
1610 * an event for user space applications with the
1611 * SK_DRIVER_SENDEVENT macro.
1613 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP,
1614 (unsigned int)Param.Para64);
1615 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1618 case SK_PNMI_EVT_CHG_EST_TIMER:
1620 * Calculate port switch average on a per hour basis
1621 * Time interval for check : 28125 ms
1622 * Number of values for average : 8
1624 * Be careful in changing these values, on change check
1625 * - typedef of SK_PNMI_ESTIMATE (Size of EstValue
1626 * array one less than value number)
1627 * - Timer initilization SkTimerStart() in SkPnmiInit
1628 * - Delta value below must be multiplicated with
1632 pEst = &pAC->Pnmi.RlmtChangeEstimate;
1633 CounterIndex = pEst->EstValueIndex + 1;
1634 if (CounterIndex == 7) {
1638 pEst->EstValueIndex = CounterIndex;
1640 NewestValue = pAC->Pnmi.RlmtChangeCts;
1641 OldestValue = pEst->EstValue[CounterIndex];
1642 pEst->EstValue[CounterIndex] = NewestValue;
1645 * Calculate average. Delta stores the number of
1646 * port switches per 28125 * 8 = 225000 ms
1648 if (NewestValue >= OldestValue) {
1650 Delta = NewestValue - OldestValue;
1653 /* Overflow situation */
1654 Delta = (SK_U64)(0 - OldestValue) + NewestValue;
1658 * Extrapolate delta to port switches per hour.
1659 * Estimate = Delta * (3600000 / 225000)
1663 pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4;
1666 * Check if threshold is exceeded. If the threshold is
1667 * permanently exceeded every 28125 ms an event will be
1668 * generated to remind the user of this condition.
1670 if ((pAC->Pnmi.RlmtChangeThreshold != 0) &&
1671 (pAC->Pnmi.RlmtChangeEstimate.Estimate >=
1672 pAC->Pnmi.RlmtChangeThreshold)) {
1674 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES);
1675 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1678 SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
1679 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
1680 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
1684 case SK_PNMI_EVT_CLEAR_COUNTER:
1686 * Param.Para32[0] contains the NetIndex (0 ..1).
1687 * Param.Para32[1] is reserved, contains -1.
1689 NetIndex = (SK_U32)Param.Para32[0];
1692 if (NetIndex >= pAC->Rlmt.NumNets) {
1694 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1695 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
1703 * Set all counters and timestamps to zero
1705 ResetCounter(pAC, IoC, NetIndex); /* the according NetIndex is required
1706 as a Parameter of the Event */
1709 case SK_PNMI_EVT_XMAC_RESET:
1711 * To grant continuous counter values store the current
1712 * XMAC statistic values to the entries 1..n of the
1713 * CounterOffset array. XMAC Errata #2
1716 if ((unsigned int)Param.Para64 >= SK_MAX_MACS) {
1718 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1719 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n",
1720 (unsigned int)Param.Para64));
1724 PhysPortIndex = (unsigned int)Param.Para64;
1727 * Update XMAC statistic to get fresh values
1729 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
1730 if (Ret != SK_PNMI_ERR_OK) {
1732 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1736 * Increment semaphore to indicate that an update was
1739 pAC->Pnmi.MacUpdatedFlag ++;
1741 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1744 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1749 pAC->Pnmi.Port[PhysPortIndex].
1750 CounterOffset[CounterIndex] = GetPhysStatVal(
1751 pAC, IoC, PhysPortIndex, CounterIndex);
1752 pAC->Pnmi.Port[PhysPortIndex].
1753 CounterHigh[CounterIndex] = 0;
1756 pAC->Pnmi.MacUpdatedFlag --;
1759 case SK_PNMI_EVT_RLMT_PORT_UP:
1760 PhysPortIndex = (unsigned int)Param.Para32[0];
1762 if (PhysPortIndex >= SK_MAX_MACS) {
1764 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1765 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter"
1766 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1772 * Store a trap message in the trap buffer and generate an event for
1773 * user space applications with the SK_DRIVER_SENDEVENT macro.
1775 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
1776 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1778 /* Bugfix for XMAC errata (#10620)*/
1779 if (pAC->GIni.GIMacType == SK_MAC_XMAC){
1781 /* Add incremental difference to offset (#10620)*/
1782 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1783 XM_RXE_SHT_ERR, &Val32);
1785 Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1786 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1787 pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
1788 Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
1791 /* Tell VctStatus() that a link was up meanwhile. */
1792 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK;
1795 case SK_PNMI_EVT_RLMT_PORT_DOWN:
1796 PhysPortIndex = (unsigned int)Param.Para32[0];
1799 if (PhysPortIndex >= SK_MAX_MACS) {
1801 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1802 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter"
1803 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1809 * Store a trap message in the trap buffer and generate an event for
1810 * user space applications with the SK_DRIVER_SENDEVENT macro.
1812 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
1813 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1815 /* Bugfix #10620 - get zero level for incremental difference */
1816 if ((pAC->GIni.GIMacType == SK_MAC_XMAC)) {
1818 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1819 XM_RXE_SHT_ERR, &Val32);
1820 pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark =
1821 (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1822 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1826 case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
1827 PhysPortIndex = (unsigned int)Param.Para32[0];
1828 NetIndex = (SK_U32)Param.Para32[1];
1831 if (PhysPortIndex >= SK_MAX_MACS) {
1833 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1834 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
1838 if (NetIndex >= pAC->Rlmt.NumNets) {
1840 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1841 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
1846 * For now, ignore event if NetIndex != 0.
1848 if (Param.Para32[1] != 0) {
1854 * Nothing to do if port is already inactive
1856 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1862 * Update statistic counters to calculate new offset for the virtual
1863 * port and increment semaphore to indicate that an update was already
1866 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1869 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1872 pAC->Pnmi.MacUpdatedFlag ++;
1875 * Calculate new counter offset for virtual port to grant continous
1876 * counting on port switches. The virtual port consists of all currently
1877 * active ports. The port down event indicates that a port is removed
1878 * from the virtual port. Therefore add the counter value of the removed
1879 * port to the CounterOffset for the virtual port to grant the same
1882 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1885 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1890 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1892 pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
1896 * Set port to inactive
1898 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
1900 pAC->Pnmi.MacUpdatedFlag --;
1903 case SK_PNMI_EVT_RLMT_ACTIVE_UP:
1904 PhysPortIndex = (unsigned int)Param.Para32[0];
1905 NetIndex = (SK_U32)Param.Para32[1];
1908 if (PhysPortIndex >= SK_MAX_MACS) {
1910 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1911 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
1915 if (NetIndex >= pAC->Rlmt.NumNets) {
1917 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1918 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
1923 * For now, ignore event if NetIndex != 0.
1925 if (Param.Para32[1] != 0) {
1931 * Nothing to do if port is already active
1933 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1939 * Statistic maintenance
1941 pAC->Pnmi.RlmtChangeCts ++;
1942 pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
1945 * Store a trap message in the trap buffer and generate an event for
1946 * user space applications with the SK_DRIVER_SENDEVENT macro.
1948 QueueRlmtNewMacTrap(pAC, PhysPortIndex);
1949 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1952 * Update statistic counters to calculate new offset for the virtual
1953 * port and increment semaphore to indicate that an update was
1956 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1959 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1962 pAC->Pnmi.MacUpdatedFlag ++;
1965 * Calculate new counter offset for virtual port to grant continous
1966 * counting on port switches. A new port is added to the virtual port.
1967 * Therefore substract the counter value of the new port from the
1968 * CounterOffset for the virtual port to grant the same value.
1970 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1973 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1978 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1980 pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
1984 * Set port to active
1986 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
1988 pAC->Pnmi.MacUpdatedFlag --;
1991 case SK_PNMI_EVT_RLMT_SEGMENTATION:
1993 * Para.Para32[0] contains the NetIndex.
1997 * Store a trap message in the trap buffer and generate an event for
1998 * user space applications with the SK_DRIVER_SENDEVENT macro.
2000 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
2001 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
2004 case SK_PNMI_EVT_RLMT_SET_NETS:
2006 * Param.Para32[0] contains the number of Nets.
2007 * Param.Para32[1] is reserved, contains -1.
2010 * Check number of nets
2012 MaxNetNumber = pAC->GIni.GIMacsFound;
2013 if (((unsigned int)Param.Para32[0] < 1)
2014 || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
2015 return (SK_PNMI_ERR_UNKNOWN_NET);
2018 if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
2019 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
2021 else { /* dual net mode */
2022 pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
2026 case SK_PNMI_EVT_VCT_RESET:
2027 PhysPortIndex = Param.Para32[0];
2028 pPrt = &pAC->GIni.GP[PhysPortIndex];
2029 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
2031 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
2032 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
2035 * VCT test is still running.
2036 * Start VCT timer counter again.
2038 SK_MEMSET((char *) &Param, 0, sizeof(Param));
2039 Param.Para32[0] = PhysPortIndex;
2040 Param.Para32[1] = -1;
2041 SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
2042 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
2045 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
2046 pAC->Pnmi.VctStatus[PhysPortIndex] |=
2047 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
2049 /* Copy results for later use to PNMI struct. */
2050 for (i = 0; i < 4; i++) {
2051 if (pPrt->PMdiPairLen[i] > 35) {
2052 CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
2057 pVctBackupData->PMdiPairLen[i] = CableLength;
2058 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
2061 Param.Para32[0] = PhysPortIndex;
2062 Param.Para32[1] = -1;
2063 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
2064 SkEventDispatcher(pAC, IoC);
2073 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
2078 /******************************************************************************
2084 /*****************************************************************************
2086 * PnmiVar - Gets, presets, and sets single OIDs
2089 * Looks up the requested OID, calls the corresponding handler
2090 * function, and passes the parameters with the get, preset, or
2091 * set command. The function is called by SkGePnmiGetVar,
2092 * SkGePnmiPreSetVar, or SkGePnmiSetVar.
2095 * SK_PNMI_ERR_XXX. For details have a look to the description of the
2096 * calling functions.
2097 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
2099 PNMI_STATIC int PnmiVar(
2100 SK_AC *pAC, /* Pointer to adapter context */
2101 SK_IOC IoC, /* IO context handle */
2102 int Action, /* Get/PreSet/Set action */
2103 SK_U32 Id, /* Object ID that is to be processed */
2104 char *pBuf, /* Buffer which stores the mgmt data to be set */
2105 unsigned int *pLen, /* Total length of mgmt data */
2106 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
2107 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2109 unsigned int TableIndex;
2113 if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
2116 return (SK_PNMI_ERR_UNKNOWN_OID);
2122 if (NetIndex >= pAC->Rlmt.NumNets) {
2123 return (SK_PNMI_ERR_UNKNOWN_NET);
2126 SK_PNMI_CHECKFLAGS("PnmiVar: On call");
2128 Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
2129 Instance, TableIndex, NetIndex);
2131 SK_PNMI_CHECKFLAGS("PnmiVar: On return");
2136 /*****************************************************************************
2138 * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA
2141 * The return value of the function will also be stored in
2142 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
2143 * SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable,
2144 * checks which OIDs are able to set, and calls the handler function of
2145 * the OID to perform the set. The return value of the function will
2146 * also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
2147 * minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called
2148 * by SkGePnmiPreSetStruct and SkGePnmiSetStruct.
2151 * SK_PNMI_ERR_XXX. The codes are described in the calling functions.
2152 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
2154 PNMI_STATIC int PnmiStruct(
2155 SK_AC *pAC, /* Pointer to adapter context */
2156 SK_IOC IoC, /* IO context handle */
2157 int Action, /* Set action to be performed */
2158 char *pBuf, /* Buffer which contains the data to be set */
2159 unsigned int *pLen, /* Length of buffer */
2160 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2163 unsigned int TableIndex;
2164 unsigned int DstOffset;
2166 unsigned int InstanceNo;
2167 unsigned int InstanceCnt;
2172 /* Check if the passed buffer has the right size */
2173 if (*pLen < SK_PNMI_STRUCT_SIZE) {
2175 /* Check if we can return the error within the buffer */
2176 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
2178 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
2182 *pLen = SK_PNMI_STRUCT_SIZE;
2183 return (SK_PNMI_ERR_TOO_SHORT);
2189 if (NetIndex >= pAC->Rlmt.NumNets) {
2190 return (SK_PNMI_ERR_UNKNOWN_NET);
2193 SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
2196 * Update the values of RLMT and SIRQ and increment semaphores to
2197 * indicate that an update was already done.
2199 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
2201 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
2202 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2206 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
2208 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
2209 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2213 pAC->Pnmi.RlmtUpdatedFlag ++;
2214 pAC->Pnmi.SirqUpdatedFlag ++;
2216 /* Preset/Set values */
2217 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
2219 if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
2220 (IdTable[TableIndex].Access != SK_PNMI_WO)) {
2225 InstanceNo = IdTable[TableIndex].InstanceNo;
2226 Id = IdTable[TableIndex].Id;
2228 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
2231 DstOffset = IdTable[TableIndex].Offset +
2233 IdTable[TableIndex].StructSize;
2236 * Because VPD multiple instance variables are
2237 * not setable we do not need to evaluate VPD
2238 * instances. Have a look to VPD instance
2239 * calculation in SkPnmiGetStruct().
2241 Instance = (SK_U32)InstanceCnt;
2244 * Evaluate needed buffer length
2247 Ret = IdTable[TableIndex].Func(pAC, IoC,
2248 SK_PNMI_GET, IdTable[TableIndex].Id,
2249 NULL, &Len, Instance, TableIndex, NetIndex);
2251 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
2255 if (Ret != SK_PNMI_ERR_TOO_SHORT) {
2257 pAC->Pnmi.RlmtUpdatedFlag --;
2258 pAC->Pnmi.SirqUpdatedFlag --;
2260 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
2261 SK_PNMI_SET_STAT(pBuf,
2262 SK_PNMI_ERR_GENERAL, DstOffset);
2263 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2264 return (SK_PNMI_ERR_GENERAL);
2266 if (Id == OID_SKGE_VPD_ACTION) {
2268 switch (*(pBuf + DstOffset)) {
2270 case SK_PNMI_VPD_CREATE:
2271 Len = 3 + *(pBuf + DstOffset + 3);
2274 case SK_PNMI_VPD_DELETE:
2284 /* Call the OID handler function */
2285 Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
2286 IdTable[TableIndex].Id, pBuf + DstOffset,
2287 &Len, Instance, TableIndex, NetIndex);
2289 if (Ret != SK_PNMI_ERR_OK) {
2291 pAC->Pnmi.RlmtUpdatedFlag --;
2292 pAC->Pnmi.SirqUpdatedFlag --;
2294 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
2295 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
2297 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2298 return (SK_PNMI_ERR_BAD_VALUE);
2303 pAC->Pnmi.RlmtUpdatedFlag --;
2304 pAC->Pnmi.SirqUpdatedFlag --;
2306 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
2307 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
2308 return (SK_PNMI_ERR_OK);
2311 /*****************************************************************************
2313 * LookupId - Lookup an OID in the IdTable
2316 * Scans the IdTable to find the table entry of an OID.
2319 * The table index or -1 if not found.
2321 PNMI_STATIC int LookupId(
2322 SK_U32 Id) /* Object identifier to be searched */
2326 for (i = 0; i < ID_TABLE_SIZE; i++) {
2328 if (IdTable[i].Id == Id) {
2337 /*****************************************************************************
2339 * OidStruct - Handler of OID_SKGE_ALL_DATA
2342 * This OID performs a Get/Preset/SetStruct call and returns all data
2343 * in a SK_PNMI_STRUCT_DATA structure.
2346 * SK_PNMI_ERR_OK The request was successfully performed.
2347 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2348 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2349 * the correct data (e.g. a 32bit value is
2350 * needed, but a 16 bit value was passed).
2351 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2353 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2354 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2355 * exist (e.g. port instance 3 on a two port
2358 PNMI_STATIC int OidStruct(
2359 SK_AC *pAC, /* Pointer to adapter context */
2360 SK_IOC IoC, /* IO context handle */
2361 int Action, /* Get/PreSet/Set action */
2362 SK_U32 Id, /* Object ID that is to be processed */
2363 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2364 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2365 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2366 unsigned int TableIndex, /* Index to the Id table */
2367 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2369 if (Id != OID_SKGE_ALL_DATA) {
2371 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
2375 return (SK_PNMI_ERR_GENERAL);
2379 * Check instance. We only handle single instance variables
2381 if (Instance != (SK_U32)(-1) && Instance != 1) {
2384 return (SK_PNMI_ERR_UNKNOWN_INST);
2390 return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
2392 case SK_PNMI_PRESET:
2393 return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
2396 return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
2399 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
2402 return (SK_PNMI_ERR_GENERAL);
2405 /*****************************************************************************
2407 * Perform - OID handler of OID_SKGE_ACTION
2413 * SK_PNMI_ERR_OK The request was successfully performed.
2414 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2415 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2416 * the correct data (e.g. a 32bit value is
2417 * needed, but a 16 bit value was passed).
2418 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2420 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2421 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2422 * exist (e.g. port instance 3 on a two port
2425 PNMI_STATIC int Perform(
2426 SK_AC *pAC, /* Pointer to adapter context */
2427 SK_IOC IoC, /* IO context handle */
2428 int Action, /* Get/PreSet/Set action */
2429 SK_U32 Id, /* Object ID that is to be processed */
2430 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2431 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2432 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2433 unsigned int TableIndex, /* Index to the Id table */
2434 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2441 * Check instance. We only handle single instance variables
2443 if (Instance != (SK_U32)(-1) && Instance != 1) {
2446 return (SK_PNMI_ERR_UNKNOWN_INST);
2449 if (*pLen < sizeof(SK_U32)) {
2451 *pLen = sizeof(SK_U32);
2452 return (SK_PNMI_ERR_TOO_SHORT);
2455 /* Check if a get should be performed */
2456 if (Action == SK_PNMI_GET) {
2458 /* A get is easy. We always return the same value */
2459 ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
2460 SK_PNMI_STORE_U32(pBuf, ActionOp);
2461 *pLen = sizeof(SK_U32);
2463 return (SK_PNMI_ERR_OK);
2466 /* Continue with PRESET/SET action */
2467 if (*pLen > sizeof(SK_U32)) {
2469 return (SK_PNMI_ERR_BAD_VALUE);
2472 /* Check if the command is a known one */
2473 SK_PNMI_READ_U32(pBuf, ActionOp);
2474 if (*pLen > sizeof(SK_U32) ||
2475 (ActionOp != SK_PNMI_ACT_IDLE &&
2476 ActionOp != SK_PNMI_ACT_RESET &&
2477 ActionOp != SK_PNMI_ACT_SELFTEST &&
2478 ActionOp != SK_PNMI_ACT_RESETCNT)) {
2481 return (SK_PNMI_ERR_BAD_VALUE);
2484 /* A preset ends here */
2485 if (Action == SK_PNMI_PRESET) {
2487 return (SK_PNMI_ERR_OK);
2492 case SK_PNMI_ACT_IDLE:
2496 case SK_PNMI_ACT_RESET:
2498 * Perform a driver reset or something that comes near
2501 Ret = SK_DRIVER_RESET(pAC, IoC);
2504 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
2507 return (SK_PNMI_ERR_GENERAL);
2511 case SK_PNMI_ACT_SELFTEST:
2513 * Perform a driver selftest or something similar to this.
2514 * Currently this feature is not used and will probably
2515 * implemented in another way.
2517 Ret = SK_DRIVER_SELFTEST(pAC, IoC);
2518 pAC->Pnmi.TestResult = Ret;
2521 case SK_PNMI_ACT_RESETCNT:
2522 /* Set all counters and timestamps to zero */
2523 ResetCounter(pAC, IoC, NetIndex);
2527 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
2530 return (SK_PNMI_ERR_GENERAL);
2533 return (SK_PNMI_ERR_OK);
2536 /*****************************************************************************
2538 * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX
2541 * Retrieves the statistic values of the virtual port (logical
2542 * index 0). Only special OIDs of NDIS are handled which consist
2543 * of a 32 bit instead of a 64 bit value. The OIDs are public
2544 * because perhaps some other platform can use them too.
2547 * SK_PNMI_ERR_OK The request was successfully performed.
2548 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2549 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2550 * the correct data (e.g. a 32bit value is
2551 * needed, but a 16 bit value was passed).
2552 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2553 * exist (e.g. port instance 3 on a two port
2556 PNMI_STATIC int Mac8023Stat(
2557 SK_AC *pAC, /* Pointer to adapter context */
2558 SK_IOC IoC, /* IO context handle */
2559 int Action, /* Get/PreSet/Set action */
2560 SK_U32 Id, /* Object ID that is to be processed */
2561 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2562 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2563 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2564 unsigned int TableIndex, /* Index to the Id table */
2565 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2570 SK_BOOL Is64BitReq = SK_FALSE;
2573 * Only the active Mac is returned
2575 if (Instance != (SK_U32)(-1) && Instance != 1) {
2578 return (SK_PNMI_ERR_UNKNOWN_INST);
2584 if (Action != SK_PNMI_GET) {
2587 return (SK_PNMI_ERR_READ_ONLY);
2595 case OID_802_3_PERMANENT_ADDRESS:
2596 case OID_802_3_CURRENT_ADDRESS:
2597 if (*pLen < sizeof(SK_MAC_ADDR)) {
2599 *pLen = sizeof(SK_MAC_ADDR);
2600 return (SK_PNMI_ERR_TOO_SHORT);
2605 #ifndef SK_NDIS_64BIT_CTR
2606 if (*pLen < sizeof(SK_U32)) {
2607 *pLen = sizeof(SK_U32);
2608 return (SK_PNMI_ERR_TOO_SHORT);
2611 #else /* SK_NDIS_64BIT_CTR */
2614 * for compatibility, at least 32bit are required for oid
2616 if (*pLen < sizeof(SK_U32)) {
2618 * but indicate handling for 64bit values,
2619 * if insufficient space is provided
2621 *pLen = sizeof(SK_U64);
2622 return (SK_PNMI_ERR_TOO_SHORT);
2625 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
2626 #endif /* SK_NDIS_64BIT_CTR */
2631 * Update all statistics, because we retrieve virtual MAC, which
2632 * consists of multiple physical statistics and increment semaphore
2633 * to indicate that an update was already done.
2635 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2636 if ( Ret != SK_PNMI_ERR_OK) {
2641 pAC->Pnmi.MacUpdatedFlag ++;
2644 * Get value (MAC Index 0 identifies the virtual MAC)
2648 case OID_802_3_PERMANENT_ADDRESS:
2649 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2650 *pLen = sizeof(SK_MAC_ADDR);
2653 case OID_802_3_CURRENT_ADDRESS:
2654 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2655 *pLen = sizeof(SK_MAC_ADDR);
2659 StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
2662 * by default 32bit values are evaluated
2665 StatVal32 = (SK_U32)StatVal;
2666 SK_PNMI_STORE_U32(pBuf, StatVal32);
2667 *pLen = sizeof(SK_U32);
2670 SK_PNMI_STORE_U64(pBuf, StatVal);
2671 *pLen = sizeof(SK_U64);
2676 pAC->Pnmi.MacUpdatedFlag --;
2678 return (SK_PNMI_ERR_OK);
2681 /*****************************************************************************
2683 * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX
2686 * Retrieves the XMAC statistic data.
2689 * SK_PNMI_ERR_OK The request was successfully performed.
2690 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2691 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2692 * the correct data (e.g. a 32bit value is
2693 * needed, but a 16 bit value was passed).
2694 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2695 * exist (e.g. port instance 3 on a two port
2698 PNMI_STATIC int MacPrivateStat(
2699 SK_AC *pAC, /* Pointer to adapter context */
2700 SK_IOC IoC, /* IO context handle */
2701 int Action, /* Get/PreSet/Set action */
2702 SK_U32 Id, /* Object ID that is to be processed */
2703 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2704 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2705 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2706 unsigned int TableIndex, /* Index to the Id table */
2707 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2709 unsigned int LogPortMax;
2710 unsigned int LogPortIndex;
2711 unsigned int PhysPortMax;
2713 unsigned int Offset;
2719 * Calculate instance if wished. MAC index 0 is the virtual
2722 PhysPortMax = pAC->GIni.GIMacsFound;
2723 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2725 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2729 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2730 /* Check instance range */
2731 if ((Instance < 1) || (Instance > LogPortMax)) {
2734 return (SK_PNMI_ERR_UNKNOWN_INST);
2736 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2737 Limit = LogPortIndex + 1;
2740 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2750 if (Action != SK_PNMI_GET) {
2753 return (SK_PNMI_ERR_READ_ONLY);
2759 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
2761 *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
2762 return (SK_PNMI_ERR_TOO_SHORT);
2766 * Update XMAC statistic and increment semaphore to indicate that
2767 * an update was already done.
2769 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2770 if (Ret != SK_PNMI_ERR_OK) {
2775 pAC->Pnmi.MacUpdatedFlag ++;
2781 for (; LogPortIndex < Limit; LogPortIndex ++) {
2785 /* XXX not yet implemented due to XMAC problems
2786 case OID_SKGE_STAT_TX_UTIL:
2787 return (SK_PNMI_ERR_GENERAL);
2789 /* XXX not yet implemented due to XMAC problems
2790 case OID_SKGE_STAT_RX_UTIL:
2791 return (SK_PNMI_ERR_GENERAL);
2793 case OID_SKGE_STAT_RX:
2794 case OID_SKGE_STAT_TX:
2795 switch (pAC->GIni.GIMacType) {
2797 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2798 IdTable[TableIndex].Param, NetIndex);
2802 if (Id == OID_SKGE_STAT_TX) {
2805 GetStatVal(pAC, IoC, LogPortIndex,
2806 SK_PNMI_HTX_BROADCAST, NetIndex) +
2807 GetStatVal(pAC, IoC, LogPortIndex,
2808 SK_PNMI_HTX_MULTICAST, NetIndex) +
2809 GetStatVal(pAC, IoC, LogPortIndex,
2810 SK_PNMI_HTX_UNICAST, NetIndex);
2814 GetStatVal(pAC, IoC, LogPortIndex,
2815 SK_PNMI_HRX_BROADCAST, NetIndex) +
2816 GetStatVal(pAC, IoC, LogPortIndex,
2817 SK_PNMI_HRX_MULTICAST, NetIndex) +
2818 GetStatVal(pAC, IoC, LogPortIndex,
2819 SK_PNMI_HRX_UNICAST, NetIndex) +
2820 GetStatVal(pAC, IoC, LogPortIndex,
2821 SK_PNMI_HRX_UNDERSIZE, NetIndex);
2830 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2834 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2835 IdTable[TableIndex].Param, NetIndex);
2836 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2840 Offset += sizeof(SK_U64);
2844 pAC->Pnmi.MacUpdatedFlag --;
2846 return (SK_PNMI_ERR_OK);
2849 /*****************************************************************************
2851 * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR
2854 * Get/Presets/Sets the current and factory MAC address. The MAC
2855 * address of the virtual port, which is reported to the OS, may
2856 * not be changed, but the physical ones. A set to the virtual port
2857 * will be ignored. No error should be reported because otherwise
2858 * a multiple instance set (-1) would always fail.
2861 * SK_PNMI_ERR_OK The request was successfully performed.
2862 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2863 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2864 * the correct data (e.g. a 32bit value is
2865 * needed, but a 16 bit value was passed).
2866 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2868 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2869 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2870 * exist (e.g. port instance 3 on a two port
2873 PNMI_STATIC int Addr(
2874 SK_AC *pAC, /* Pointer to adapter context */
2875 SK_IOC IoC, /* IO context handle */
2876 int Action, /* Get/PreSet/Set action */
2877 SK_U32 Id, /* Object ID that is to be processed */
2878 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2879 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2880 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2881 unsigned int TableIndex, /* Index to the Id table */
2882 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2885 unsigned int LogPortMax;
2886 unsigned int PhysPortMax;
2887 unsigned int LogPortIndex;
2888 unsigned int PhysPortIndex;
2890 unsigned int Offset = 0;
2893 * Calculate instance if wished. MAC index 0 is the virtual
2896 PhysPortMax = pAC->GIni.GIMacsFound;
2897 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2899 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2903 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2904 /* Check instance range */
2905 if ((Instance < 1) || (Instance > LogPortMax)) {
2908 return (SK_PNMI_ERR_UNKNOWN_INST);
2910 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2911 Limit = LogPortIndex + 1;
2914 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2923 if (Action == SK_PNMI_GET) {
2928 if (*pLen < (Limit - LogPortIndex) * 6) {
2930 *pLen = (Limit - LogPortIndex) * 6;
2931 return (SK_PNMI_ERR_TOO_SHORT);
2937 for (; LogPortIndex < Limit; LogPortIndex ++) {
2941 case OID_SKGE_PHYS_CUR_ADDR:
2942 if (LogPortIndex == 0) {
2943 CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2946 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
2948 CopyMac(pBuf + Offset,
2949 &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
2954 case OID_SKGE_PHYS_FAC_ADDR:
2955 if (LogPortIndex == 0) {
2956 CopyMac(pBuf + Offset,
2957 &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2960 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
2963 CopyMac(pBuf + Offset,
2964 &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
2970 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
2974 return (SK_PNMI_ERR_GENERAL);
2982 * The logical MAC address may not be changed only
2985 if (Id == OID_SKGE_PHYS_FAC_ADDR) {
2988 return (SK_PNMI_ERR_READ_ONLY);
2992 * Only the current address may be changed
2994 if (Id != OID_SKGE_PHYS_CUR_ADDR) {
2996 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
3000 return (SK_PNMI_ERR_GENERAL);
3006 if (*pLen < (Limit - LogPortIndex) * 6) {
3008 *pLen = (Limit - LogPortIndex) * 6;
3009 return (SK_PNMI_ERR_TOO_SHORT);
3011 if (*pLen > (Limit - LogPortIndex) * 6) {
3014 return (SK_PNMI_ERR_BAD_VALUE);
3020 if (Action == SK_PNMI_PRESET) {
3023 return (SK_PNMI_ERR_OK);
3027 * Set OID_SKGE_MAC_CUR_ADDR
3029 for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
3032 * A set to virtual port and set of broadcast
3033 * address will be ignored
3035 if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
3036 "\xff\xff\xff\xff\xff\xff", 6) == 0) {
3041 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
3044 Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
3045 (SK_MAC_ADDR *)(pBuf + Offset),
3046 (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
3047 SK_ADDR_PHYSICAL_ADDRESS));
3048 if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {
3050 return (SK_PNMI_ERR_GENERAL);
3056 return (SK_PNMI_ERR_OK);
3059 /*****************************************************************************
3061 * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
3064 * Retrieves the statistic values of the CSUM module. The CSUM data
3065 * structure must be available in the SK_AC even if the CSUM module
3066 * is not included, because PNMI reads the statistic data from the
3067 * CSUM part of SK_AC directly.
3070 * SK_PNMI_ERR_OK The request was successfully performed.
3071 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3072 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3073 * the correct data (e.g. a 32bit value is
3074 * needed, but a 16 bit value was passed).
3075 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3076 * exist (e.g. port instance 3 on a two port
3079 PNMI_STATIC int CsumStat(
3080 SK_AC *pAC, /* Pointer to adapter context */
3081 SK_IOC IoC, /* IO context handle */
3082 int Action, /* Get/PreSet/Set action */
3083 SK_U32 Id, /* Object ID that is to be processed */
3084 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
3085 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3086 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3087 unsigned int TableIndex, /* Index to the Id table */
3088 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
3092 unsigned int Offset = 0;
3097 * Calculate instance if wished
3099 if (Instance != (SK_U32)(-1)) {
3101 if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
3104 return (SK_PNMI_ERR_UNKNOWN_INST);
3106 Index = (unsigned int)Instance - 1;
3111 Limit = SKCS_NUM_PROTOCOLS;
3117 if (Action != SK_PNMI_GET) {
3120 return (SK_PNMI_ERR_READ_ONLY);
3126 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
3128 *pLen = (Limit - Index) * sizeof(SK_U64);
3129 return (SK_PNMI_ERR_TOO_SHORT);
3135 for (; Index < Limit; Index ++) {
3139 case OID_SKGE_CHKSM_RX_OK_CTS:
3140 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
3143 case OID_SKGE_CHKSM_RX_UNABLE_CTS:
3144 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
3147 case OID_SKGE_CHKSM_RX_ERR_CTS:
3148 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
3151 case OID_SKGE_CHKSM_TX_OK_CTS:
3152 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
3155 case OID_SKGE_CHKSM_TX_UNABLE_CTS:
3156 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
3160 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
3164 return (SK_PNMI_ERR_GENERAL);
3167 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
3168 Offset += sizeof(SK_U64);
3172 * Store used buffer space
3176 return (SK_PNMI_ERR_OK);
3179 /*****************************************************************************
3181 * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
3184 * Retrieves the statistic values of the I2C module, which handles
3185 * the temperature and voltage sensors.
3188 * SK_PNMI_ERR_OK The request was successfully performed.
3189 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3190 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3191 * the correct data (e.g. a 32bit value is
3192 * needed, but a 16 bit value was passed).
3193 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3194 * exist (e.g. port instance 3 on a two port
3197 PNMI_STATIC int SensorStat(
3198 SK_AC *pAC, /* Pointer to adapter context */
3199 SK_IOC IoC, /* IO context handle */
3200 int Action, /* Get/PreSet/Set action */
3201 SK_U32 Id, /* Object ID that is to be processed */
3202 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
3203 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3204 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3205 unsigned int TableIndex, /* Index to the Id table */
3206 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
3211 unsigned int Offset;
3218 * Calculate instance if wished
3220 if ((Instance != (SK_U32)(-1))) {
3222 if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
3225 return (SK_PNMI_ERR_UNKNOWN_INST);
3228 Index = (unsigned int)Instance -1;
3229 Limit = (unsigned int)Instance;
3233 Limit = (unsigned int) pAC->I2c.MaxSens;
3239 if (Action != SK_PNMI_GET) {
3242 return (SK_PNMI_ERR_READ_ONLY);
3250 case OID_SKGE_SENSOR_VALUE:
3251 case OID_SKGE_SENSOR_WAR_THRES_LOW:
3252 case OID_SKGE_SENSOR_WAR_THRES_UPP:
3253 case OID_SKGE_SENSOR_ERR_THRES_LOW:
3254 case OID_SKGE_SENSOR_ERR_THRES_UPP:
3255 if (*pLen < (Limit - Index) * sizeof(SK_U32)) {
3257 *pLen = (Limit - Index) * sizeof(SK_U32);
3258 return (SK_PNMI_ERR_TOO_SHORT);
3262 case OID_SKGE_SENSOR_DESCR:
3263 for (Offset = 0, i = Index; i < Limit; i ++) {
3265 Len = (unsigned int)
3266 SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1;
3267 if (Len >= SK_PNMI_STRINGLEN2) {
3269 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011,
3273 return (SK_PNMI_ERR_GENERAL);
3277 if (*pLen < Offset) {
3280 return (SK_PNMI_ERR_TOO_SHORT);
3284 case OID_SKGE_SENSOR_INDEX:
3285 case OID_SKGE_SENSOR_TYPE:
3286 case OID_SKGE_SENSOR_STATUS:
3287 if (*pLen < Limit - Index) {
3289 *pLen = Limit - Index;
3290 return (SK_PNMI_ERR_TOO_SHORT);
3294 case OID_SKGE_SENSOR_WAR_CTS:
3295 case OID_SKGE_SENSOR_WAR_TIME:
3296 case OID_SKGE_SENSOR_ERR_CTS:
3297 case OID_SKGE_SENSOR_ERR_TIME:
3298 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
3300 *pLen = (Limit - Index) * sizeof(SK_U64);
3301 return (SK_PNMI_ERR_TOO_SHORT);
3306 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
3310 return (SK_PNMI_ERR_GENERAL);
3317 for (Offset = 0; Index < Limit; Index ++) {
3321 case OID_SKGE_SENSOR_INDEX:
3322 *(pBuf + Offset) = (char)Index;
3323 Offset += sizeof(char);
3326 case OID_SKGE_SENSOR_DESCR:
3327 Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
3328 SK_MEMCPY(pBuf + Offset + 1,
3329 pAC->I2c.SenTable[Index].SenDesc, Len);
3330 *(pBuf + Offset) = (char)Len;
3334 case OID_SKGE_SENSOR_TYPE:
3336 (char)pAC->I2c.SenTable[Index].SenType;
3337 Offset += sizeof(char);
3340 case OID_SKGE_SENSOR_VALUE:
3341 Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
3342 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3343 Offset += sizeof(SK_U32);
3346 case OID_SKGE_SENSOR_WAR_THRES_LOW:
3347 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
3349 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3350 Offset += sizeof(SK_U32);
3353 case OID_SKGE_SENSOR_WAR_THRES_UPP:
3354 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
3356 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3357 Offset += sizeof(SK_U32);
3360 case OID_SKGE_SENSOR_ERR_THRES_LOW:
3361 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
3363 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3364 Offset += sizeof(SK_U32);
3367 case OID_SKGE_SENSOR_ERR_THRES_UPP:
3368 Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
3369 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3370 Offset += sizeof(SK_U32);
3373 case OID_SKGE_SENSOR_STATUS:
3375 (char)pAC->I2c.SenTable[Index].SenErrFlag;
3376 Offset += sizeof(char);
3379 case OID_SKGE_SENSOR_WAR_CTS:
3380 Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
3381 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3382 Offset += sizeof(SK_U64);
3385 case OID_SKGE_SENSOR_ERR_CTS:
3386 Val64 = pAC->I2c.SenTable[Index].SenErrCts;
3387 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3388 Offset += sizeof(SK_U64);
3391 case OID_SKGE_SENSOR_WAR_TIME:
3392 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
3394 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3395 Offset += sizeof(SK_U64);
3398 case OID_SKGE_SENSOR_ERR_TIME:
3399 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
3401 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3402 Offset += sizeof(SK_U64);
3406 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
3407 ("SensorStat: Unknown OID should be handled before"));
3409 return (SK_PNMI_ERR_GENERAL);
3414 * Store used buffer space
3418 return (SK_PNMI_ERR_OK);
3421 /*****************************************************************************
3423 * Vpd - OID handler function of OID_SKGE_VPD_XXX
3426 * Get/preset/set of VPD data. As instance the name of a VPD key
3427 * can be passed. The Instance parameter is a SK_U32 and can be
3428 * used as a string buffer for the VPD key, because their maximum
3432 * SK_PNMI_ERR_OK The request was successfully performed.
3433 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3434 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3435 * the correct data (e.g. a 32bit value is
3436 * needed, but a 16 bit value was passed).
3437 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
3439 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
3440 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3441 * exist (e.g. port instance 3 on a two port
3444 PNMI_STATIC int Vpd(
3445 SK_AC *pAC, /* Pointer to adapter context */
3446 SK_IOC IoC, /* IO context handle */
3447 int Action, /* Get/PreSet/Set action */
3448 SK_U32 Id, /* Object ID that is to be processed */
3449 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
3450 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3451 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3452 unsigned int TableIndex, /* Index to the Id table */
3453 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
3455 SK_VPD_STATUS *pVpdStatus;
3456 unsigned int BufLen;
3458 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
3459 char KeyStr[SK_PNMI_VPD_KEY_SIZE];
3461 unsigned int Offset;
3463 unsigned int FirstIndex;
3464 unsigned int LastIndex;
3470 * Get array of all currently stored VPD keys
3472 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr),
3474 if (Ret != SK_PNMI_ERR_OK) {
3480 * If instance is not -1, try to find the requested VPD key for
3481 * the multiple instance variables. The other OIDs as for example
3482 * OID VPD_ACTION are single instance variables and must be
3483 * handled separatly.
3488 if ((Instance != (SK_U32)(-1))) {
3490 if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
3491 Id == OID_SKGE_VPD_ACCESS) {
3493 SK_STRNCPY(KeyStr, (char *)&Instance, 4);
3496 for (Index = 0; Index < KeyNo; Index ++) {
3498 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3500 LastIndex = Index+1;
3504 if (Index == KeyNo) {
3507 return (SK_PNMI_ERR_UNKNOWN_INST);
3510 else if (Instance != 1) {
3513 return (SK_PNMI_ERR_UNKNOWN_INST);
3518 * Get value, if a query should be performed
3520 if (Action == SK_PNMI_GET) {
3524 case OID_SKGE_VPD_FREE_BYTES:
3525 /* Check length of buffer */
3526 if (*pLen < sizeof(SK_U32)) {
3528 *pLen = sizeof(SK_U32);
3529 return (SK_PNMI_ERR_TOO_SHORT);
3531 /* Get number of free bytes */
3532 pVpdStatus = VpdStat(pAC, IoC);
3533 if (pVpdStatus == NULL) {
3535 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
3539 return (SK_PNMI_ERR_GENERAL);
3541 if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
3543 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
3547 return (SK_PNMI_ERR_GENERAL);
3550 Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
3551 SK_PNMI_STORE_U32(pBuf, Val32);
3552 *pLen = sizeof(SK_U32);
3555 case OID_SKGE_VPD_ENTRIES_LIST:
3557 for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
3559 Len += SK_STRLEN(KeyArr[Index]) + 1;
3564 return (SK_PNMI_ERR_TOO_SHORT);
3568 *(pBuf) = (char)Len - 1;
3569 for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
3571 Len = SK_STRLEN(KeyArr[Index]);
3572 SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
3576 if (Index < KeyNo - 1) {
3578 *(pBuf + Offset) = ' ';
3585 case OID_SKGE_VPD_ENTRIES_NUMBER:
3587 if (*pLen < sizeof(SK_U32)) {
3589 *pLen = sizeof(SK_U32);
3590 return (SK_PNMI_ERR_TOO_SHORT);
3593 Val32 = (SK_U32)KeyNo;
3594 SK_PNMI_STORE_U32(pBuf, Val32);
3595 *pLen = sizeof(SK_U32);
3598 case OID_SKGE_VPD_KEY:
3599 /* Check buffer length, if it is large enough */
3600 for (Len = 0, Index = FirstIndex;
3601 Index < LastIndex; Index ++) {
3603 Len += SK_STRLEN(KeyArr[Index]) + 1;
3608 return (SK_PNMI_ERR_TOO_SHORT);
3612 * Get the key to an intermediate buffer, because
3613 * we have to prepend a length byte.
3615 for (Offset = 0, Index = FirstIndex;
3616 Index < LastIndex; Index ++) {
3618 Len = SK_STRLEN(KeyArr[Index]);
3620 *(pBuf + Offset) = (char)Len;
3621 SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
3628 case OID_SKGE_VPD_VALUE:
3629 /* Check the buffer length if it is large enough */
3630 for (Offset = 0, Index = FirstIndex;
3631 Index < LastIndex; Index ++) {
3634 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3635 (int *)&BufLen) > 0 ||
3636 BufLen >= SK_PNMI_VPD_DATALEN) {
3638 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3642 return (SK_PNMI_ERR_GENERAL);
3644 Offset += BufLen + 1;
3646 if (*pLen < Offset) {
3649 return (SK_PNMI_ERR_TOO_SHORT);
3653 * Get the value to an intermediate buffer, because
3654 * we have to prepend a length byte.
3656 for (Offset = 0, Index = FirstIndex;
3657 Index < LastIndex; Index ++) {
3660 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3661 (int *)&BufLen) > 0 ||
3662 BufLen >= SK_PNMI_VPD_DATALEN) {
3664 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3669 return (SK_PNMI_ERR_GENERAL);
3672 *(pBuf + Offset) = (char)BufLen;
3673 SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
3674 Offset += BufLen + 1;
3679 case OID_SKGE_VPD_ACCESS:
3680 if (*pLen < LastIndex - FirstIndex) {
3682 *pLen = LastIndex - FirstIndex;
3683 return (SK_PNMI_ERR_TOO_SHORT);
3686 for (Offset = 0, Index = FirstIndex;
3687 Index < LastIndex; Index ++) {
3689 if (VpdMayWrite(KeyArr[Index])) {
3691 *(pBuf + Offset) = SK_PNMI_VPD_RW;
3694 *(pBuf + Offset) = SK_PNMI_VPD_RO;
3701 case OID_SKGE_VPD_ACTION:
3702 Offset = LastIndex - FirstIndex;
3703 if (*pLen < Offset) {
3706 return (SK_PNMI_ERR_TOO_SHORT);
3708 SK_MEMSET(pBuf, 0, Offset);
3713 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
3717 return (SK_PNMI_ERR_GENERAL);
3721 /* The only OID which can be set is VPD_ACTION */
3722 if (Id != OID_SKGE_VPD_ACTION) {
3724 if (Id == OID_SKGE_VPD_FREE_BYTES ||
3725 Id == OID_SKGE_VPD_ENTRIES_LIST ||
3726 Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
3727 Id == OID_SKGE_VPD_KEY ||
3728 Id == OID_SKGE_VPD_VALUE ||
3729 Id == OID_SKGE_VPD_ACCESS) {
3732 return (SK_PNMI_ERR_READ_ONLY);
3735 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
3739 return (SK_PNMI_ERR_GENERAL);
3743 * From this point we handle VPD_ACTION. Check the buffer
3744 * length. It should at least have the size of one byte.
3749 return (SK_PNMI_ERR_TOO_SHORT);
3753 * The first byte contains the VPD action type we should
3758 case SK_PNMI_VPD_IGNORE:
3762 case SK_PNMI_VPD_CREATE:
3764 * We have to create a new VPD entry or we modify
3765 * an existing one. Check first the buffer length.
3770 return (SK_PNMI_ERR_TOO_SHORT);
3772 KeyStr[0] = pBuf[1];
3773 KeyStr[1] = pBuf[2];
3777 * Is the entry writable or does it belong to the
3780 if (!VpdMayWrite(KeyStr)) {
3783 return (SK_PNMI_ERR_BAD_VALUE);
3786 Offset = (int)pBuf[3] & 0xFF;
3788 SK_MEMCPY(Buf, pBuf + 4, Offset);
3791 /* A preset ends here */
3792 if (Action == SK_PNMI_PRESET) {
3794 return (SK_PNMI_ERR_OK);
3797 /* Write the new entry or modify an existing one */
3798 Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
3799 if (Ret == SK_PNMI_VPD_NOWRITE ) {
3802 return (SK_PNMI_ERR_BAD_VALUE);
3804 else if (Ret != SK_PNMI_VPD_OK) {
3806 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
3810 return (SK_PNMI_ERR_GENERAL);
3814 * Perform an update of the VPD data. This is
3815 * not mandantory, but just to be sure.
3817 Ret = VpdUpdate(pAC, IoC);
3818 if (Ret != SK_PNMI_VPD_OK) {
3820 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
3824 return (SK_PNMI_ERR_GENERAL);
3828 case SK_PNMI_VPD_DELETE:
3829 /* Check if the buffer size is plausible */
3833 return (SK_PNMI_ERR_TOO_SHORT);
3838 return (SK_PNMI_ERR_BAD_VALUE);
3840 KeyStr[0] = pBuf[1];
3841 KeyStr[1] = pBuf[2];
3844 /* Find the passed key in the array */
3845 for (Index = 0; Index < KeyNo; Index ++) {
3847 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3853 * If we cannot find the key it is wrong, so we
3854 * return an appropriate error value.
3856 if (Index == KeyNo) {
3859 return (SK_PNMI_ERR_BAD_VALUE);
3862 if (Action == SK_PNMI_PRESET) {
3864 return (SK_PNMI_ERR_OK);
3867 /* Ok, you wanted it and you will get it */
3868 Ret = VpdDelete(pAC, IoC, KeyStr);
3869 if (Ret != SK_PNMI_VPD_OK) {
3871 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
3875 return (SK_PNMI_ERR_GENERAL);
3879 * Perform an update of the VPD data. This is
3880 * not mandantory, but just to be sure.
3882 Ret = VpdUpdate(pAC, IoC);
3883 if (Ret != SK_PNMI_VPD_OK) {
3885 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
3889 return (SK_PNMI_ERR_GENERAL);
3895 return (SK_PNMI_ERR_BAD_VALUE);
3899 return (SK_PNMI_ERR_OK);
3902 /*****************************************************************************
3904 * General - OID handler function of various single instance OIDs
3907 * The code is simple. No description necessary.
3910 * SK_PNMI_ERR_OK The request was successfully performed.
3911 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3912 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3913 * the correct data (e.g. a 32bit value is
3914 * needed, but a 16 bit value was passed).
3915 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3916 * exist (e.g. port instance 3 on a two port
3919 PNMI_STATIC int General(
3920 SK_AC *pAC, /* Pointer to adapter context */
3921 SK_IOC IoC, /* IO context handle */
3922 int Action, /* Get/PreSet/Set action */
3923 SK_U32 Id, /* Object ID that is to be processed */
3924 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
3925 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3926 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3927 unsigned int TableIndex, /* Index to the Id table */
3928 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
3933 unsigned int Offset;
3939 SK_U64 Val64RxHwErrs = 0;
3940 SK_U64 Val64TxHwErrs = 0;
3941 SK_BOOL Is64BitReq = SK_FALSE;
3946 * Check instance. We only handle single instance variables
3948 if (Instance != (SK_U32)(-1) && Instance != 1) {
3951 return (SK_PNMI_ERR_UNKNOWN_INST);
3955 * Check action. We only allow get requests.
3957 if (Action != SK_PNMI_GET) {
3960 return (SK_PNMI_ERR_READ_ONLY);
3963 MacType = pAC->GIni.GIMacType;
3966 * Check length for the various supported OIDs
3970 case OID_GEN_XMIT_ERROR:
3971 case OID_GEN_RCV_ERROR:
3972 case OID_GEN_RCV_NO_BUFFER:
3973 #ifndef SK_NDIS_64BIT_CTR
3974 if (*pLen < sizeof(SK_U32)) {
3975 *pLen = sizeof(SK_U32);
3976 return (SK_PNMI_ERR_TOO_SHORT);
3979 #else /* SK_NDIS_64BIT_CTR */
3982 * for compatibility, at least 32bit are required for oid
3984 if (*pLen < sizeof(SK_U32)) {
3986 * but indicate handling for 64bit values,
3987 * if insufficient space is provided
3989 *pLen = sizeof(SK_U64);
3990 return (SK_PNMI_ERR_TOO_SHORT);
3993 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
3994 #endif /* SK_NDIS_64BIT_CTR */
3997 case OID_SKGE_PORT_NUMBER:
3998 case OID_SKGE_DEVICE_TYPE:
3999 case OID_SKGE_RESULT:
4000 case OID_SKGE_RLMT_MONITOR_NUMBER:
4001 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
4002 case OID_SKGE_TRAP_NUMBER:
4003 case OID_SKGE_MDB_VERSION:
4004 if (*pLen < sizeof(SK_U32)) {
4006 *pLen = sizeof(SK_U32);
4007 return (SK_PNMI_ERR_TOO_SHORT);
4011 case OID_SKGE_CHIPSET:
4012 if (*pLen < sizeof(SK_U16)) {
4014 *pLen = sizeof(SK_U16);
4015 return (SK_PNMI_ERR_TOO_SHORT);
4019 case OID_SKGE_BUS_TYPE:
4020 case OID_SKGE_BUS_SPEED:
4021 case OID_SKGE_BUS_WIDTH:
4022 case OID_SKGE_SENSOR_NUMBER:
4023 case OID_SKGE_CHKSM_NUMBER:
4024 if (*pLen < sizeof(SK_U8)) {
4026 *pLen = sizeof(SK_U8);
4027 return (SK_PNMI_ERR_TOO_SHORT);
4031 case OID_SKGE_TX_SW_QUEUE_LEN:
4032 case OID_SKGE_TX_SW_QUEUE_MAX:
4033 case OID_SKGE_TX_RETRY:
4034 case OID_SKGE_RX_INTR_CTS:
4035 case OID_SKGE_TX_INTR_CTS:
4036 case OID_SKGE_RX_NO_BUF_CTS:
4037 case OID_SKGE_TX_NO_BUF_CTS:
4038 case OID_SKGE_TX_USED_DESCR_NO:
4039 case OID_SKGE_RX_DELIVERED_CTS:
4040 case OID_SKGE_RX_OCTETS_DELIV_CTS:
4041 case OID_SKGE_RX_HW_ERROR_CTS:
4042 case OID_SKGE_TX_HW_ERROR_CTS:
4043 case OID_SKGE_IN_ERRORS_CTS:
4044 case OID_SKGE_OUT_ERROR_CTS:
4045 case OID_SKGE_ERR_RECOVERY_CTS:
4046 case OID_SKGE_SYSUPTIME:
4047 if (*pLen < sizeof(SK_U64)) {
4049 *pLen = sizeof(SK_U64);
4050 return (SK_PNMI_ERR_TOO_SHORT);
4059 /* Update statistic */
4060 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
4061 Id == OID_SKGE_TX_HW_ERROR_CTS ||
4062 Id == OID_SKGE_IN_ERRORS_CTS ||
4063 Id == OID_SKGE_OUT_ERROR_CTS ||
4064 Id == OID_GEN_XMIT_ERROR ||
4065 Id == OID_GEN_RCV_ERROR) {
4067 /* Force the XMAC to update its statistic counters and
4068 * Increment semaphore to indicate that an update was
4071 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
4072 if (Ret != SK_PNMI_ERR_OK) {
4077 pAC->Pnmi.MacUpdatedFlag ++;
4080 * Some OIDs consist of multiple hardware counters. Those
4081 * values which are contained in all of them will be added
4086 case OID_SKGE_RX_HW_ERROR_CTS:
4087 case OID_SKGE_IN_ERRORS_CTS:
4088 case OID_GEN_RCV_ERROR:
4090 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
4091 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
4092 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex)+
4093 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
4094 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
4095 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex)+
4096 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
4097 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
4098 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
4099 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
4100 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
4101 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
4104 case OID_SKGE_TX_HW_ERROR_CTS:
4105 case OID_SKGE_OUT_ERROR_CTS:
4106 case OID_GEN_XMIT_ERROR:
4108 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
4109 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex)+
4110 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex)+
4111 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex);
4121 case OID_SKGE_SUPPORTED_LIST:
4122 Len = ID_TABLE_SIZE * sizeof(SK_U32);
4126 return (SK_PNMI_ERR_TOO_SHORT);
4128 for (Offset = 0, Index = 0; Offset < Len;
4129 Offset += sizeof(SK_U32), Index ++) {
4131 Val32 = (SK_U32)IdTable[Index].Id;
4132 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4137 case OID_SKGE_PORT_NUMBER:
4138 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
4139 SK_PNMI_STORE_U32(pBuf, Val32);
4140 *pLen = sizeof(SK_U32);
4143 case OID_SKGE_DEVICE_TYPE:
4144 Val32 = (SK_U32)pAC->Pnmi.DeviceType;
4145 SK_PNMI_STORE_U32(pBuf, Val32);
4146 *pLen = sizeof(SK_U32);
4149 case OID_SKGE_DRIVER_DESCR:
4150 if (pAC->Pnmi.pDriverDescription == NULL) {
4152 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
4156 return (SK_PNMI_ERR_GENERAL);
4159 Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
4160 if (Len > SK_PNMI_STRINGLEN1) {
4162 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
4166 return (SK_PNMI_ERR_GENERAL);
4172 return (SK_PNMI_ERR_TOO_SHORT);
4174 *pBuf = (char)(Len - 1);
4175 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
4179 case OID_SKGE_DRIVER_VERSION:
4180 if (pAC->Pnmi.pDriverVersion == NULL) {
4182 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
4186 return (SK_PNMI_ERR_GENERAL);
4189 Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
4190 if (Len > SK_PNMI_STRINGLEN1) {
4192 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
4196 return (SK_PNMI_ERR_GENERAL);
4202 return (SK_PNMI_ERR_TOO_SHORT);
4204 *pBuf = (char)(Len - 1);
4205 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
4209 case OID_SKGE_HW_DESCR:
4211 * The hardware description is located in the VPD. This
4212 * query may move to the initialisation routine. But
4213 * the VPD data is cached and therefore a call here
4214 * will not make much difference.
4217 if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
4219 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
4223 return (SK_PNMI_ERR_GENERAL);
4226 if (Len > SK_PNMI_STRINGLEN1) {
4228 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
4232 return (SK_PNMI_ERR_GENERAL);
4237 return (SK_PNMI_ERR_TOO_SHORT);
4239 *pBuf = (char)(Len - 1);
4240 SK_MEMCPY(pBuf + 1, Buf, Len - 1);
4244 case OID_SKGE_HW_VERSION:
4245 /* Oh, I love to do some string manipulation */
4249 return (SK_PNMI_ERR_TOO_SHORT);
4251 Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
4254 pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
4256 pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
4260 case OID_SKGE_CHIPSET:
4261 Val16 = pAC->Pnmi.Chipset;
4262 SK_PNMI_STORE_U16(pBuf, Val16);
4263 *pLen = sizeof(SK_U16);
4266 case OID_SKGE_BUS_TYPE:
4267 *pBuf = (char)SK_PNMI_BUS_PCI;
4268 *pLen = sizeof(char);
4271 case OID_SKGE_BUS_SPEED:
4272 *pBuf = pAC->Pnmi.PciBusSpeed;
4273 *pLen = sizeof(char);
4276 case OID_SKGE_BUS_WIDTH:
4277 *pBuf = pAC->Pnmi.PciBusWidth;
4278 *pLen = sizeof(char);
4281 case OID_SKGE_RESULT:
4282 Val32 = pAC->Pnmi.TestResult;
4283 SK_PNMI_STORE_U32(pBuf, Val32);
4284 *pLen = sizeof(SK_U32);
4287 case OID_SKGE_SENSOR_NUMBER:
4288 *pBuf = (char)pAC->I2c.MaxSens;
4289 *pLen = sizeof(char);
4292 case OID_SKGE_CHKSM_NUMBER:
4293 *pBuf = SKCS_NUM_PROTOCOLS;
4294 *pLen = sizeof(char);
4297 case OID_SKGE_TRAP_NUMBER:
4298 GetTrapQueueLen(pAC, &Len, &Val);
4299 Val32 = (SK_U32)Val;
4300 SK_PNMI_STORE_U32(pBuf, Val32);
4301 *pLen = sizeof(SK_U32);
4305 GetTrapQueueLen(pAC, &Len, &Val);
4309 return (SK_PNMI_ERR_TOO_SHORT);
4311 CopyTrapQueue(pAC, pBuf);
4315 case OID_SKGE_RLMT_MONITOR_NUMBER:
4316 /* XXX Not yet implemented by RLMT therefore we return zero elements */
4318 SK_PNMI_STORE_U32(pBuf, Val32);
4319 *pLen = sizeof(SK_U32);
4322 case OID_SKGE_TX_SW_QUEUE_LEN:
4323 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4324 if (MacType == SK_MAC_XMAC) {
4326 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4327 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
4329 /* Single net mode */
4331 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
4332 pAC->Pnmi.BufPort[1].TxSwQueueLen;
4337 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4338 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
4340 /* Single net mode */
4342 Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
4343 pAC->Pnmi.Port[1].TxSwQueueLen;
4346 SK_PNMI_STORE_U64(pBuf, Val64);
4347 *pLen = sizeof(SK_U64);
4351 case OID_SKGE_TX_SW_QUEUE_MAX:
4352 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4353 if (MacType == SK_MAC_XMAC) {
4355 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4356 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
4358 /* Single net mode */
4360 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
4361 pAC->Pnmi.BufPort[1].TxSwQueueMax;
4366 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4367 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
4369 /* Single net mode */
4371 Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
4372 pAC->Pnmi.Port[1].TxSwQueueMax;
4375 SK_PNMI_STORE_U64(pBuf, Val64);
4376 *pLen = sizeof(SK_U64);
4379 case OID_SKGE_TX_RETRY:
4380 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4381 if (MacType == SK_MAC_XMAC) {
4383 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4384 Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
4386 /* Single net mode */
4388 Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
4389 pAC->Pnmi.BufPort[1].TxRetryCts;
4394 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4395 Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
4397 /* Single net mode */
4399 Val64 = pAC->Pnmi.Port[0].TxRetryCts +
4400 pAC->Pnmi.Port[1].TxRetryCts;
4403 SK_PNMI_STORE_U64(pBuf, Val64);
4404 *pLen = sizeof(SK_U64);
4407 case OID_SKGE_RX_INTR_CTS:
4408 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4409 if (MacType == SK_MAC_XMAC) {
4411 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4412 Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
4414 /* Single net mode */
4416 Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
4417 pAC->Pnmi.BufPort[1].RxIntrCts;
4422 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4423 Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
4425 /* Single net mode */
4427 Val64 = pAC->Pnmi.Port[0].RxIntrCts +
4428 pAC->Pnmi.Port[1].RxIntrCts;
4431 SK_PNMI_STORE_U64(pBuf, Val64);
4432 *pLen = sizeof(SK_U64);
4435 case OID_SKGE_TX_INTR_CTS:
4436 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4437 if (MacType == SK_MAC_XMAC) {
4439 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4440 Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
4442 /* Single net mode */
4444 Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
4445 pAC->Pnmi.BufPort[1].TxIntrCts;
4450 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4451 Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
4453 /* Single net mode */
4455 Val64 = pAC->Pnmi.Port[0].TxIntrCts +
4456 pAC->Pnmi.Port[1].TxIntrCts;
4459 SK_PNMI_STORE_U64(pBuf, Val64);
4460 *pLen = sizeof(SK_U64);
4463 case OID_SKGE_RX_NO_BUF_CTS:
4464 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4465 if (MacType == SK_MAC_XMAC) {
4467 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4468 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4470 /* Single net mode */
4472 Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
4473 pAC->Pnmi.BufPort[1].RxNoBufCts;
4478 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4479 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4481 /* Single net mode */
4483 Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
4484 pAC->Pnmi.Port[1].RxNoBufCts;
4487 SK_PNMI_STORE_U64(pBuf, Val64);
4488 *pLen = sizeof(SK_U64);
4491 case OID_SKGE_TX_NO_BUF_CTS:
4492 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4493 if (MacType == SK_MAC_XMAC) {
4495 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4496 Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4498 /* Single net mode */
4500 Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
4501 pAC->Pnmi.BufPort[1].TxNoBufCts;
4506 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4507 Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4509 /* Single net mode */
4511 Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
4512 pAC->Pnmi.Port[1].TxNoBufCts;
4515 SK_PNMI_STORE_U64(pBuf, Val64);
4516 *pLen = sizeof(SK_U64);
4519 case OID_SKGE_TX_USED_DESCR_NO:
4520 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4521 if (MacType == SK_MAC_XMAC) {
4523 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4524 Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
4526 /* Single net mode */
4528 Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
4529 pAC->Pnmi.BufPort[1].TxUsedDescrNo;
4534 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4535 Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
4537 /* Single net mode */
4539 Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
4540 pAC->Pnmi.Port[1].TxUsedDescrNo;
4543 SK_PNMI_STORE_U64(pBuf, Val64);
4544 *pLen = sizeof(SK_U64);
4547 case OID_SKGE_RX_DELIVERED_CTS:
4548 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4549 if (MacType == SK_MAC_XMAC) {
4551 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4552 Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
4554 /* Single net mode */
4556 Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
4557 pAC->Pnmi.BufPort[1].RxDeliveredCts;
4562 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4563 Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
4565 /* Single net mode */
4567 Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
4568 pAC->Pnmi.Port[1].RxDeliveredCts;
4571 SK_PNMI_STORE_U64(pBuf, Val64);
4572 *pLen = sizeof(SK_U64);
4575 case OID_SKGE_RX_OCTETS_DELIV_CTS:
4576 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4577 if (MacType == SK_MAC_XMAC) {
4579 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4580 Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
4582 /* Single net mode */
4584 Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
4585 pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
4590 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4591 Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
4593 /* Single net mode */
4595 Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
4596 pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
4599 SK_PNMI_STORE_U64(pBuf, Val64);
4600 *pLen = sizeof(SK_U64);
4603 case OID_SKGE_RX_HW_ERROR_CTS:
4604 SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
4605 *pLen = sizeof(SK_U64);
4608 case OID_SKGE_TX_HW_ERROR_CTS:
4609 SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
4610 *pLen = sizeof(SK_U64);
4613 case OID_SKGE_IN_ERRORS_CTS:
4614 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4615 if (MacType == SK_MAC_XMAC) {
4617 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4618 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4620 /* Single net mode */
4622 Val64 = Val64RxHwErrs +
4623 pAC->Pnmi.BufPort[0].RxNoBufCts +
4624 pAC->Pnmi.BufPort[1].RxNoBufCts;
4629 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4630 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4632 /* Single net mode */
4634 Val64 = Val64RxHwErrs +
4635 pAC->Pnmi.Port[0].RxNoBufCts +
4636 pAC->Pnmi.Port[1].RxNoBufCts;
4639 SK_PNMI_STORE_U64(pBuf, Val64);
4640 *pLen = sizeof(SK_U64);
4643 case OID_SKGE_OUT_ERROR_CTS:
4644 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4645 if (MacType == SK_MAC_XMAC) {
4647 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4648 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4650 /* Single net mode */
4652 Val64 = Val64TxHwErrs +
4653 pAC->Pnmi.BufPort[0].TxNoBufCts +
4654 pAC->Pnmi.BufPort[1].TxNoBufCts;
4659 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4660 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4662 /* Single net mode */
4664 Val64 = Val64TxHwErrs +
4665 pAC->Pnmi.Port[0].TxNoBufCts +
4666 pAC->Pnmi.Port[1].TxNoBufCts;
4669 SK_PNMI_STORE_U64(pBuf, Val64);
4670 *pLen = sizeof(SK_U64);
4673 case OID_SKGE_ERR_RECOVERY_CTS:
4674 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4675 if (MacType == SK_MAC_XMAC) {
4677 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4678 Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
4680 /* Single net mode */
4682 Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
4683 pAC->Pnmi.BufPort[1].ErrRecoveryCts;
4688 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4689 Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
4691 /* Single net mode */
4693 Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
4694 pAC->Pnmi.Port[1].ErrRecoveryCts;
4697 SK_PNMI_STORE_U64(pBuf, Val64);
4698 *pLen = sizeof(SK_U64);
4701 case OID_SKGE_SYSUPTIME:
4702 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
4703 Val64 -= pAC->Pnmi.StartUpTime;
4704 SK_PNMI_STORE_U64(pBuf, Val64);
4705 *pLen = sizeof(SK_U64);
4708 case OID_SKGE_MDB_VERSION:
4709 Val32 = SK_PNMI_MDB_VERSION;
4710 SK_PNMI_STORE_U32(pBuf, Val32);
4711 *pLen = sizeof(SK_U32);
4714 case OID_GEN_RCV_ERROR:
4715 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4716 if (MacType == SK_MAC_XMAC) {
4717 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4720 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4724 * by default 32bit values are evaluated
4727 Val32 = (SK_U32)Val64;
4728 SK_PNMI_STORE_U32(pBuf, Val32);
4729 *pLen = sizeof(SK_U32);
4732 SK_PNMI_STORE_U64(pBuf, Val64);
4733 *pLen = sizeof(SK_U64);
4737 case OID_GEN_XMIT_ERROR:
4738 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4739 if (MacType == SK_MAC_XMAC) {
4740 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4743 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4747 * by default 32bit values are evaluated
4750 Val32 = (SK_U32)Val64;
4751 SK_PNMI_STORE_U32(pBuf, Val32);
4752 *pLen = sizeof(SK_U32);
4755 SK_PNMI_STORE_U64(pBuf, Val64);
4756 *pLen = sizeof(SK_U64);
4760 case OID_GEN_RCV_NO_BUFFER:
4761 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4762 if (MacType == SK_MAC_XMAC) {
4763 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4766 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4770 * by default 32bit values are evaluated
4773 Val32 = (SK_U32)Val64;
4774 SK_PNMI_STORE_U32(pBuf, Val32);
4775 *pLen = sizeof(SK_U32);
4778 SK_PNMI_STORE_U64(pBuf, Val64);
4779 *pLen = sizeof(SK_U64);
4783 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
4784 Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
4785 SK_PNMI_STORE_U32(pBuf, Val32);
4786 *pLen = sizeof(SK_U32);
4790 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
4794 return (SK_PNMI_ERR_GENERAL);
4797 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
4798 Id == OID_SKGE_TX_HW_ERROR_CTS ||
4799 Id == OID_SKGE_IN_ERRORS_CTS ||
4800 Id == OID_SKGE_OUT_ERROR_CTS ||
4801 Id == OID_GEN_XMIT_ERROR ||
4802 Id == OID_GEN_RCV_ERROR) {
4804 pAC->Pnmi.MacUpdatedFlag --;
4807 return (SK_PNMI_ERR_OK);
4810 /*****************************************************************************
4812 * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
4815 * Get/Presets/Sets the RLMT OIDs.
4818 * SK_PNMI_ERR_OK The request was successfully performed.
4819 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4820 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4821 * the correct data (e.g. a 32bit value is
4822 * needed, but a 16 bit value was passed).
4823 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
4825 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
4826 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4827 * exist (e.g. port instance 3 on a two port
4830 PNMI_STATIC int Rlmt(
4831 SK_AC *pAC, /* Pointer to adapter context */
4832 SK_IOC IoC, /* IO context handle */
4833 int Action, /* Get/PreSet/Set action */
4834 SK_U32 Id, /* Object ID that is to be processed */
4835 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
4836 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
4837 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4838 unsigned int TableIndex, /* Index to the Id table */
4839 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
4842 unsigned int PhysPortIndex;
4843 unsigned int PhysPortMax;
4844 SK_EVPARA EventParam;
4850 * Check instance. Only single instance OIDs are allowed here.
4852 if (Instance != (SK_U32)(-1) && Instance != 1) {
4855 return (SK_PNMI_ERR_UNKNOWN_INST);
4859 * Perform the requested action
4861 if (Action == SK_PNMI_GET) {
4864 * Check if the buffer length is large enough.
4869 case OID_SKGE_RLMT_MODE:
4870 case OID_SKGE_RLMT_PORT_ACTIVE:
4871 case OID_SKGE_RLMT_PORT_PREFERRED:
4872 if (*pLen < sizeof(SK_U8)) {
4874 *pLen = sizeof(SK_U8);
4875 return (SK_PNMI_ERR_TOO_SHORT);
4879 case OID_SKGE_RLMT_PORT_NUMBER:
4880 if (*pLen < sizeof(SK_U32)) {
4882 *pLen = sizeof(SK_U32);
4883 return (SK_PNMI_ERR_TOO_SHORT);
4887 case OID_SKGE_RLMT_CHANGE_CTS:
4888 case OID_SKGE_RLMT_CHANGE_TIME:
4889 case OID_SKGE_RLMT_CHANGE_ESTIM:
4890 case OID_SKGE_RLMT_CHANGE_THRES:
4891 if (*pLen < sizeof(SK_U64)) {
4893 *pLen = sizeof(SK_U64);
4894 return (SK_PNMI_ERR_TOO_SHORT);
4899 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
4903 return (SK_PNMI_ERR_GENERAL);
4907 * Update RLMT statistic and increment semaphores to indicate
4908 * that an update was already done. Maybe RLMT will hold its
4909 * statistic always up to date some time. Then we can
4910 * remove this type of call.
4912 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4917 pAC->Pnmi.RlmtUpdatedFlag ++;
4924 case OID_SKGE_RLMT_MODE:
4925 *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
4926 *pLen = sizeof(char);
4929 case OID_SKGE_RLMT_PORT_NUMBER:
4930 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
4931 SK_PNMI_STORE_U32(pBuf, Val32);
4932 *pLen = sizeof(SK_U32);
4935 case OID_SKGE_RLMT_PORT_ACTIVE:
4938 * If multiple ports may become active this OID
4939 * doesn't make sense any more. A new variable in
4940 * the port structure should be created. However,
4941 * for this variable the first active port is
4944 PhysPortMax = pAC->GIni.GIMacsFound;
4946 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
4949 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4951 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
4955 *pLen = sizeof(char);
4958 case OID_SKGE_RLMT_PORT_PREFERRED:
4959 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
4960 *pLen = sizeof(char);
4963 case OID_SKGE_RLMT_CHANGE_CTS:
4964 Val64 = pAC->Pnmi.RlmtChangeCts;
4965 SK_PNMI_STORE_U64(pBuf, Val64);
4966 *pLen = sizeof(SK_U64);
4969 case OID_SKGE_RLMT_CHANGE_TIME:
4970 Val64 = pAC->Pnmi.RlmtChangeTime;
4971 SK_PNMI_STORE_U64(pBuf, Val64);
4972 *pLen = sizeof(SK_U64);
4975 case OID_SKGE_RLMT_CHANGE_ESTIM:
4976 Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
4977 SK_PNMI_STORE_U64(pBuf, Val64);
4978 *pLen = sizeof(SK_U64);
4981 case OID_SKGE_RLMT_CHANGE_THRES:
4982 Val64 = pAC->Pnmi.RlmtChangeThreshold;
4983 SK_PNMI_STORE_U64(pBuf, Val64);
4984 *pLen = sizeof(SK_U64);
4988 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
4989 ("Rlmt: Unknown OID should be handled before"));
4991 pAC->Pnmi.RlmtUpdatedFlag --;
4993 return (SK_PNMI_ERR_GENERAL);
4996 pAC->Pnmi.RlmtUpdatedFlag --;
4999 /* Perform a preset or set */
5002 case OID_SKGE_RLMT_MODE:
5003 /* Check if the buffer length is plausible */
5004 if (*pLen < sizeof(char)) {
5006 *pLen = sizeof(char);
5007 return (SK_PNMI_ERR_TOO_SHORT);
5009 /* Check if the value range is correct */
5010 if (*pLen != sizeof(char) ||
5011 (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
5012 *(SK_U8 *)pBuf > 15) {
5015 return (SK_PNMI_ERR_BAD_VALUE);
5017 /* The preset ends here */
5018 if (Action == SK_PNMI_PRESET) {
5021 return (SK_PNMI_ERR_OK);
5023 /* Send an event to RLMT to change the mode */
5024 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
5025 EventParam.Para32[0] |= (SK_U32)(*pBuf);
5026 EventParam.Para32[1] = 0;
5027 if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
5030 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
5034 return (SK_PNMI_ERR_GENERAL);
5038 case OID_SKGE_RLMT_PORT_PREFERRED:
5039 /* Check if the buffer length is plausible */
5040 if (*pLen < sizeof(char)) {
5042 *pLen = sizeof(char);
5043 return (SK_PNMI_ERR_TOO_SHORT);
5045 /* Check if the value range is correct */
5046 if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
5047 (SK_U8)pAC->GIni.GIMacsFound) {
5050 return (SK_PNMI_ERR_BAD_VALUE);
5052 /* The preset ends here */
5053 if (Action == SK_PNMI_PRESET) {
5056 return (SK_PNMI_ERR_OK);
5060 * Send an event to RLMT change the preferred port.
5061 * A param of -1 means automatic mode. RLMT will
5062 * make the decision which is the preferred port.
5064 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
5065 EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
5066 EventParam.Para32[1] = NetIndex;
5067 if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
5070 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
5074 return (SK_PNMI_ERR_GENERAL);
5078 case OID_SKGE_RLMT_CHANGE_THRES:
5079 /* Check if the buffer length is plausible */
5080 if (*pLen < sizeof(SK_U64)) {
5082 *pLen = sizeof(SK_U64);
5083 return (SK_PNMI_ERR_TOO_SHORT);
5086 * There are not many restrictions to the
5089 if (*pLen != sizeof(SK_U64)) {
5092 return (SK_PNMI_ERR_BAD_VALUE);
5094 /* A preset ends here */
5095 if (Action == SK_PNMI_PRESET) {
5098 return (SK_PNMI_ERR_OK);
5101 * Store the new threshold, which will be taken
5102 * on the next timer event.
5104 SK_PNMI_READ_U64(pBuf, Val64);
5105 pAC->Pnmi.RlmtChangeThreshold = Val64;
5109 /* The other OIDs are not be able for set */
5111 return (SK_PNMI_ERR_READ_ONLY);
5115 return (SK_PNMI_ERR_OK);
5118 /*****************************************************************************
5120 * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
5123 * Performs get requests on multiple instance variables.
5126 * SK_PNMI_ERR_OK The request was successfully performed.
5127 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
5128 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
5129 * the correct data (e.g. a 32bit value is
5130 * needed, but a 16 bit value was passed).
5131 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
5132 * exist (e.g. port instance 3 on a two port
5135 PNMI_STATIC int RlmtStat(
5136 SK_AC *pAC, /* Pointer to adapter context */
5137 SK_IOC IoC, /* IO context handle */
5138 int Action, /* Get/PreSet/Set action */
5139 SK_U32 Id, /* Object ID that is to be processed */
5140 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
5141 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
5142 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5143 unsigned int TableIndex, /* Index to the Id table */
5144 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
5146 unsigned int PhysPortMax;
5147 unsigned int PhysPortIndex;
5149 unsigned int Offset;
5155 * Calculate the port indexes from the instance
5157 PhysPortMax = pAC->GIni.GIMacsFound;
5159 if ((Instance != (SK_U32)(-1))) {
5160 /* Check instance range */
5161 if ((Instance < 1) || (Instance > PhysPortMax)) {
5164 return (SK_PNMI_ERR_UNKNOWN_INST);
5167 /* Single net mode */
5168 PhysPortIndex = Instance - 1;
5171 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
5172 PhysPortIndex = NetIndex;
5175 /* Both net modes */
5176 Limit = PhysPortIndex + 1;
5179 /* Single net mode */
5181 Limit = PhysPortMax;
5184 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
5185 PhysPortIndex = NetIndex;
5186 Limit = PhysPortIndex + 1;
5191 * Currently only get requests are allowed.
5193 if (Action != SK_PNMI_GET) {
5196 return (SK_PNMI_ERR_READ_ONLY);
5200 * Check if the buffer length is large enough.
5204 case OID_SKGE_RLMT_PORT_INDEX:
5205 case OID_SKGE_RLMT_STATUS:
5206 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
5208 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
5209 return (SK_PNMI_ERR_TOO_SHORT);
5213 case OID_SKGE_RLMT_TX_HELLO_CTS:
5214 case OID_SKGE_RLMT_RX_HELLO_CTS:
5215 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
5216 case OID_SKGE_RLMT_RX_SP_CTS:
5217 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
5219 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
5220 return (SK_PNMI_ERR_TOO_SHORT);
5225 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
5229 return (SK_PNMI_ERR_GENERAL);
5234 * Update statistic and increment semaphores to indicate that
5235 * an update was already done.
5237 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
5242 pAC->Pnmi.RlmtUpdatedFlag ++;
5248 for (; PhysPortIndex < Limit; PhysPortIndex ++) {
5252 case OID_SKGE_RLMT_PORT_INDEX:
5253 Val32 = PhysPortIndex;
5254 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
5255 Offset += sizeof(SK_U32);
5258 case OID_SKGE_RLMT_STATUS:
5259 if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
5261 pAC->Rlmt.Port[PhysPortIndex].PortState ==
5264 Val32 = SK_PNMI_RLMT_STATUS_ERROR;
5266 else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
5268 Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
5271 Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
5273 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
5274 Offset += sizeof(SK_U32);
5277 case OID_SKGE_RLMT_TX_HELLO_CTS:
5278 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
5279 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5280 Offset += sizeof(SK_U64);
5283 case OID_SKGE_RLMT_RX_HELLO_CTS:
5284 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
5285 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5286 Offset += sizeof(SK_U64);
5289 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
5290 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
5291 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5292 Offset += sizeof(SK_U64);
5295 case OID_SKGE_RLMT_RX_SP_CTS:
5296 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
5297 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5298 Offset += sizeof(SK_U64);
5302 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5303 ("RlmtStat: Unknown OID should be errored before"));
5305 pAC->Pnmi.RlmtUpdatedFlag --;
5307 return (SK_PNMI_ERR_GENERAL);
5312 pAC->Pnmi.RlmtUpdatedFlag --;
5314 return (SK_PNMI_ERR_OK);
5317 /*****************************************************************************
5319 * MacPrivateConf - OID handler function of OIDs concerning the configuration
5322 * Get/Presets/Sets the OIDs concerning the configuration.
5325 * SK_PNMI_ERR_OK The request was successfully performed.
5326 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
5327 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
5328 * the correct data (e.g. a 32bit value is
5329 * needed, but a 16 bit value was passed).
5330 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
5332 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
5333 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
5334 * exist (e.g. port instance 3 on a two port
5337 PNMI_STATIC int MacPrivateConf(
5338 SK_AC *pAC, /* Pointer to adapter context */
5339 SK_IOC IoC, /* IO context handle */
5340 int Action, /* Get/PreSet/Set action */
5341 SK_U32 Id, /* Object ID that is to be processed */
5342 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
5343 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
5344 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5345 unsigned int TableIndex, /* Index to the Id table */
5346 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
5348 unsigned int PhysPortMax;
5349 unsigned int PhysPortIndex;
5350 unsigned int LogPortMax;
5351 unsigned int LogPortIndex;
5353 unsigned int Offset;
5356 SK_EVPARA EventParam;
5361 * Calculate instance if wished. MAC index 0 is the virtual
5364 PhysPortMax = pAC->GIni.GIMacsFound;
5365 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
5367 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
5371 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
5372 /* Check instance range */
5373 if ((Instance < 1) || (Instance > LogPortMax)) {
5376 return (SK_PNMI_ERR_UNKNOWN_INST);
5378 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
5379 Limit = LogPortIndex + 1;
5382 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
5391 if (Action == SK_PNMI_GET) {
5399 case OID_SKGE_CONNECTOR:
5400 case OID_SKGE_LINK_CAP:
5401 case OID_SKGE_LINK_MODE:
5402 case OID_SKGE_LINK_MODE_STATUS:
5403 case OID_SKGE_LINK_STATUS:
5404 case OID_SKGE_FLOWCTRL_CAP:
5405 case OID_SKGE_FLOWCTRL_MODE:
5406 case OID_SKGE_FLOWCTRL_STATUS:
5407 case OID_SKGE_PHY_OPERATION_CAP:
5408 case OID_SKGE_PHY_OPERATION_MODE:
5409 case OID_SKGE_PHY_OPERATION_STATUS:
5410 case OID_SKGE_SPEED_CAP:
5411 case OID_SKGE_SPEED_MODE:
5412 case OID_SKGE_SPEED_STATUS:
5413 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
5415 *pLen = (Limit - LogPortIndex) *
5417 return (SK_PNMI_ERR_TOO_SHORT);
5422 if (*pLen < sizeof(SK_U32)) {
5424 *pLen = sizeof(SK_U32);
5425 return (SK_PNMI_ERR_TOO_SHORT);
5430 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
5433 return (SK_PNMI_ERR_GENERAL);
5437 * Update statistic and increment semaphore to indicate
5438 * that an update was already done.
5440 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
5445 pAC->Pnmi.SirqUpdatedFlag ++;
5451 for (; LogPortIndex < Limit; LogPortIndex ++) {
5456 *(pBuf + Offset) = pAC->Pnmi.PMD;
5457 Offset += sizeof(char);
5460 case OID_SKGE_CONNECTOR:
5461 *(pBuf + Offset) = pAC->Pnmi.Connector;
5462 Offset += sizeof(char);
5465 case OID_SKGE_LINK_CAP:
5466 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5467 if (LogPortIndex == 0) {
5469 /* Get value for virtual port */
5470 VirtualConf(pAC, IoC, Id, pBuf +
5474 /* Get value for physical ports */
5475 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5478 *(pBuf + Offset) = pAC->GIni.GP[
5479 PhysPortIndex].PLinkCap;
5481 Offset += sizeof(char);
5483 else { /* DualNetMode */
5485 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkCap;
5486 Offset += sizeof(char);
5490 case OID_SKGE_LINK_MODE:
5491 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5492 if (LogPortIndex == 0) {
5494 /* Get value for virtual port */
5495 VirtualConf(pAC, IoC, Id, pBuf +
5499 /* Get value for physical ports */
5500 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5503 *(pBuf + Offset) = pAC->GIni.GP[
5504 PhysPortIndex].PLinkModeConf;
5506 Offset += sizeof(char);
5508 else { /* DualNetMode */
5510 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkModeConf;
5511 Offset += sizeof(char);
5515 case OID_SKGE_LINK_MODE_STATUS:
5516 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5517 if (LogPortIndex == 0) {
5519 /* Get value for virtual port */
5520 VirtualConf(pAC, IoC, Id, pBuf +
5524 /* Get value for physical port */
5525 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5529 CalculateLinkModeStatus(pAC,
5530 IoC, PhysPortIndex);
5532 Offset += sizeof(char);
5534 else { /* DualNetMode */
5535 *(pBuf + Offset) = CalculateLinkModeStatus(pAC, IoC, NetIndex);
5536 Offset += sizeof(char);
5540 case OID_SKGE_LINK_STATUS:
5541 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5542 if (LogPortIndex == 0) {
5544 /* Get value for virtual port */
5545 VirtualConf(pAC, IoC, Id, pBuf +
5549 /* Get value for physical ports */
5550 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5554 CalculateLinkStatus(pAC,
5555 IoC, PhysPortIndex);
5557 Offset += sizeof(char);
5559 else { /* DualNetMode */
5561 *(pBuf + Offset) = CalculateLinkStatus(pAC, IoC, NetIndex);
5562 Offset += sizeof(char);
5566 case OID_SKGE_FLOWCTRL_CAP:
5567 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5568 if (LogPortIndex == 0) {
5570 /* Get value for virtual port */
5571 VirtualConf(pAC, IoC, Id, pBuf +
5575 /* Get value for physical ports */
5576 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5579 *(pBuf + Offset) = pAC->GIni.GP[
5580 PhysPortIndex].PFlowCtrlCap;
5582 Offset += sizeof(char);
5584 else { /* DualNetMode */
5586 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
5587 Offset += sizeof(char);
5591 case OID_SKGE_FLOWCTRL_MODE:
5592 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5593 if (LogPortIndex == 0) {
5595 /* Get value for virtual port */
5596 VirtualConf(pAC, IoC, Id, pBuf +
5600 /* Get value for physical port */
5601 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5604 *(pBuf + Offset) = pAC->GIni.GP[
5605 PhysPortIndex].PFlowCtrlMode;
5607 Offset += sizeof(char);
5609 else { /* DualNetMode */
5611 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
5612 Offset += sizeof(char);
5616 case OID_SKGE_FLOWCTRL_STATUS:
5617 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5618 if (LogPortIndex == 0) {
5620 /* Get value for virtual port */
5621 VirtualConf(pAC, IoC, Id, pBuf +
5625 /* Get value for physical port */
5626 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5629 *(pBuf + Offset) = pAC->GIni.GP[
5630 PhysPortIndex].PFlowCtrlStatus;
5632 Offset += sizeof(char);
5634 else { /* DualNetMode */
5636 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
5637 Offset += sizeof(char);
5641 case OID_SKGE_PHY_OPERATION_CAP:
5642 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5643 if (LogPortIndex == 0) {
5645 /* Get value for virtual port */
5646 VirtualConf(pAC, IoC, Id, pBuf +
5650 /* Get value for physical ports */
5651 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5654 *(pBuf + Offset) = pAC->GIni.GP[
5655 PhysPortIndex].PMSCap;
5657 Offset += sizeof(char);
5659 else { /* DualNetMode */
5661 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSCap;
5662 Offset += sizeof(char);
5666 case OID_SKGE_PHY_OPERATION_MODE:
5667 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5668 if (LogPortIndex == 0) {
5670 /* Get value for virtual port */
5671 VirtualConf(pAC, IoC, Id, pBuf + Offset);
5674 /* Get value for physical port */
5675 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5678 *(pBuf + Offset) = pAC->GIni.GP[
5679 PhysPortIndex].PMSMode;
5681 Offset += sizeof(char);
5683 else { /* DualNetMode */
5685 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSMode;
5686 Offset += sizeof(char);
5690 case OID_SKGE_PHY_OPERATION_STATUS:
5691 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5692 if (LogPortIndex == 0) {
5694 /* Get value for virtual port */
5695 VirtualConf(pAC, IoC, Id, pBuf + Offset);
5698 /* Get value for physical port */
5699 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5702 *(pBuf + Offset) = pAC->GIni.GP[
5703 PhysPortIndex].PMSStatus;
5705 Offset += sizeof(char);
5709 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSStatus;
5710 Offset += sizeof(char);
5714 case OID_SKGE_SPEED_CAP:
5715 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5716 if (LogPortIndex == 0) {
5718 /* Get value for virtual port */
5719 VirtualConf(pAC, IoC, Id, pBuf +
5723 /* Get value for physical ports */
5724 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5727 *(pBuf + Offset) = pAC->GIni.GP[
5728 PhysPortIndex].PLinkSpeedCap;
5730 Offset += sizeof(char);
5732 else { /* DualNetMode */
5734 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
5735 Offset += sizeof(char);
5739 case OID_SKGE_SPEED_MODE:
5740 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5741 if (LogPortIndex == 0) {
5743 /* Get value for virtual port */
5744 VirtualConf(pAC, IoC, Id, pBuf + Offset);
5747 /* Get value for physical port */
5748 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5751 *(pBuf + Offset) = pAC->GIni.GP[
5752 PhysPortIndex].PLinkSpeed;
5754 Offset += sizeof(char);
5756 else { /* DualNetMode */
5758 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeed;
5759 Offset += sizeof(char);
5763 case OID_SKGE_SPEED_STATUS:
5764 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5765 if (LogPortIndex == 0) {
5767 /* Get value for virtual port */
5768 VirtualConf(pAC, IoC, Id, pBuf + Offset);
5771 /* Get value for physical port */
5772 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5775 *(pBuf + Offset) = pAC->GIni.GP[
5776 PhysPortIndex].PLinkSpeedUsed;
5778 Offset += sizeof(char);
5780 else { /* DualNetMode */
5782 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
5783 Offset += sizeof(char);
5788 Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
5789 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
5790 Offset += sizeof(SK_U32);
5794 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5795 ("MacPrivateConf: Unknown OID should be handled before"));
5797 pAC->Pnmi.SirqUpdatedFlag --;
5798 return (SK_PNMI_ERR_GENERAL);
5802 pAC->Pnmi.SirqUpdatedFlag --;
5804 return (SK_PNMI_ERR_OK);
5808 * From here SET or PRESET action. Check if the passed
5809 * buffer length is plausible.
5813 case OID_SKGE_LINK_MODE:
5814 case OID_SKGE_FLOWCTRL_MODE:
5815 case OID_SKGE_PHY_OPERATION_MODE:
5816 case OID_SKGE_SPEED_MODE:
5817 if (*pLen < Limit - LogPortIndex) {
5819 *pLen = Limit - LogPortIndex;
5820 return (SK_PNMI_ERR_TOO_SHORT);
5822 if (*pLen != Limit - LogPortIndex) {
5825 return (SK_PNMI_ERR_BAD_VALUE);
5830 if (*pLen < sizeof(SK_U32)) {
5832 *pLen = sizeof(SK_U32);
5833 return (SK_PNMI_ERR_TOO_SHORT);
5835 if (*pLen != sizeof(SK_U32)) {
5838 return (SK_PNMI_ERR_BAD_VALUE);
5844 return (SK_PNMI_ERR_READ_ONLY);
5848 * Perform preset or set
5851 for (; LogPortIndex < Limit; LogPortIndex ++) {
5855 case OID_SKGE_LINK_MODE:
5856 /* Check the value range */
5857 Val8 = *(pBuf + Offset);
5860 Offset += sizeof(char);
5863 if (Val8 < SK_LMODE_HALF ||
5864 (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
5865 (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
5868 return (SK_PNMI_ERR_BAD_VALUE);
5871 /* The preset ends here */
5872 if (Action == SK_PNMI_PRESET) {
5874 return (SK_PNMI_ERR_OK);
5877 if (LogPortIndex == 0) {
5880 * The virtual port consists of all currently
5881 * active ports. Find them and send an event
5882 * with the new link mode to SIRQ.
5884 for (PhysPortIndex = 0;
5885 PhysPortIndex < PhysPortMax;
5888 if (!pAC->Pnmi.Port[PhysPortIndex].
5894 EventParam.Para32[0] = PhysPortIndex;
5895 EventParam.Para32[1] = (SK_U32)Val8;
5896 if (SkGeSirqEvent(pAC, IoC,
5900 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5905 return (SK_PNMI_ERR_GENERAL);
5911 * Send an event with the new link mode to
5914 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5916 EventParam.Para32[1] = (SK_U32)Val8;
5917 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
5920 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5925 return (SK_PNMI_ERR_GENERAL);
5928 Offset += sizeof(char);
5931 case OID_SKGE_FLOWCTRL_MODE:
5932 /* Check the value range */
5933 Val8 = *(pBuf + Offset);
5936 Offset += sizeof(char);
5939 if (Val8 < SK_FLOW_MODE_NONE ||
5940 (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
5941 (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
5944 return (SK_PNMI_ERR_BAD_VALUE);
5947 /* The preset ends here */
5948 if (Action == SK_PNMI_PRESET) {
5950 return (SK_PNMI_ERR_OK);
5953 if (LogPortIndex == 0) {
5956 * The virtual port consists of all currently
5957 * active ports. Find them and send an event
5958 * with the new flow control mode to SIRQ.
5960 for (PhysPortIndex = 0;
5961 PhysPortIndex < PhysPortMax;
5964 if (!pAC->Pnmi.Port[PhysPortIndex].
5970 EventParam.Para32[0] = PhysPortIndex;
5971 EventParam.Para32[1] = (SK_U32)Val8;
5972 if (SkGeSirqEvent(pAC, IoC,
5973 SK_HWEV_SET_FLOWMODE,
5976 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5981 return (SK_PNMI_ERR_GENERAL);
5987 * Send an event with the new flow control
5988 * mode to the SIRQ module.
5990 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5992 EventParam.Para32[1] = (SK_U32)Val8;
5993 if (SkGeSirqEvent(pAC, IoC,
5994 SK_HWEV_SET_FLOWMODE, EventParam)
5997 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6002 return (SK_PNMI_ERR_GENERAL);
6005 Offset += sizeof(char);
6008 case OID_SKGE_PHY_OPERATION_MODE :
6009 /* Check the value range */
6010 Val8 = *(pBuf + Offset);
6012 /* mode of this port remains unchanged */
6013 Offset += sizeof(char);
6016 if (Val8 < SK_MS_MODE_AUTO ||
6017 (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
6018 (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
6021 return (SK_PNMI_ERR_BAD_VALUE);
6024 /* The preset ends here */
6025 if (Action == SK_PNMI_PRESET) {
6027 return (SK_PNMI_ERR_OK);
6030 if (LogPortIndex == 0) {
6033 * The virtual port consists of all currently
6034 * active ports. Find them and send an event
6035 * with new master/slave (role) mode to SIRQ.
6037 for (PhysPortIndex = 0;
6038 PhysPortIndex < PhysPortMax;
6041 if (!pAC->Pnmi.Port[PhysPortIndex].
6047 EventParam.Para32[0] = PhysPortIndex;
6048 EventParam.Para32[1] = (SK_U32)Val8;
6049 if (SkGeSirqEvent(pAC, IoC,
6053 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6058 return (SK_PNMI_ERR_GENERAL);
6064 * Send an event with the new master/slave
6065 * (role) mode to the SIRQ module.
6067 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
6069 EventParam.Para32[1] = (SK_U32)Val8;
6070 if (SkGeSirqEvent(pAC, IoC,
6071 SK_HWEV_SET_ROLE, EventParam) > 0) {
6073 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6078 return (SK_PNMI_ERR_GENERAL);
6082 Offset += sizeof(char);
6085 case OID_SKGE_SPEED_MODE:
6086 /* Check the value range */
6087 Val8 = *(pBuf + Offset);
6090 Offset += sizeof(char);
6093 if (Val8 < (SK_LSPEED_AUTO) ||
6094 (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) ||
6095 (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) {
6098 return (SK_PNMI_ERR_BAD_VALUE);
6101 /* The preset ends here */
6102 if (Action == SK_PNMI_PRESET) {
6104 return (SK_PNMI_ERR_OK);
6107 if (LogPortIndex == 0) {
6110 * The virtual port consists of all currently
6111 * active ports. Find them and send an event
6112 * with the new flow control mode to SIRQ.
6114 for (PhysPortIndex = 0;
6115 PhysPortIndex < PhysPortMax;
6118 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6123 EventParam.Para32[0] = PhysPortIndex;
6124 EventParam.Para32[1] = (SK_U32)Val8;
6125 if (SkGeSirqEvent(pAC, IoC,
6129 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6134 return (SK_PNMI_ERR_GENERAL);
6140 * Send an event with the new flow control
6141 * mode to the SIRQ module.
6143 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
6145 EventParam.Para32[1] = (SK_U32)Val8;
6146 if (SkGeSirqEvent(pAC, IoC,
6150 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6155 return (SK_PNMI_ERR_GENERAL);
6158 Offset += sizeof(char);
6162 /* Check the value range */
6163 Val32 = *(SK_U32*)(pBuf + Offset);
6165 /* mtu of this port remains unchanged */
6166 Offset += sizeof(SK_U32);
6169 if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
6171 return (SK_PNMI_ERR_BAD_VALUE);
6174 /* The preset ends here */
6175 if (Action == SK_PNMI_PRESET) {
6176 return (SK_PNMI_ERR_OK);
6179 if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
6180 return (SK_PNMI_ERR_GENERAL);
6183 Offset += sizeof(SK_U32);
6187 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
6188 ("MacPrivateConf: Unknown OID should be handled before set"));
6191 return (SK_PNMI_ERR_GENERAL);
6195 return (SK_PNMI_ERR_OK);
6198 /*****************************************************************************
6200 * Monitor - OID handler function for RLMT_MONITOR_XXX
6203 * Because RLMT currently does not support the monitoring of
6204 * remote adapter cards, we return always an empty table.
6207 * SK_PNMI_ERR_OK The request was successfully performed.
6208 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
6209 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
6210 * the correct data (e.g. a 32bit value is
6211 * needed, but a 16 bit value was passed).
6212 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
6214 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
6215 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
6216 * exist (e.g. port instance 3 on a two port
6219 PNMI_STATIC int Monitor(
6220 SK_AC *pAC, /* Pointer to adapter context */
6221 SK_IOC IoC, /* IO context handle */
6222 int Action, /* Get/PreSet/Set action */
6223 SK_U32 Id, /* Object ID that is to be processed */
6224 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
6225 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
6226 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
6227 unsigned int TableIndex, /* Index to the Id table */
6228 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6232 unsigned int Offset;
6233 unsigned int Entries;
6237 * Calculate instance if wished.
6239 /* XXX Not yet implemented. Return always an empty table. */
6242 if ((Instance != (SK_U32)(-1))) {
6244 if ((Instance < 1) || (Instance > Entries)) {
6247 return (SK_PNMI_ERR_UNKNOWN_INST);
6250 Index = (unsigned int)Instance - 1;
6251 Limit = (unsigned int)Instance;
6261 if (Action == SK_PNMI_GET) {
6263 for (Offset=0; Index < Limit; Index ++) {
6267 case OID_SKGE_RLMT_MONITOR_INDEX:
6268 case OID_SKGE_RLMT_MONITOR_ADDR:
6269 case OID_SKGE_RLMT_MONITOR_ERRS:
6270 case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
6271 case OID_SKGE_RLMT_MONITOR_ADMIN:
6275 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
6279 return (SK_PNMI_ERR_GENERAL);
6285 /* Only MONITOR_ADMIN can be set */
6286 if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
6289 return (SK_PNMI_ERR_READ_ONLY);
6292 /* Check if the length is plausible */
6293 if (*pLen < (Limit - Index)) {
6295 return (SK_PNMI_ERR_TOO_SHORT);
6297 /* Okay, we have a wide value range */
6298 if (*pLen != (Limit - Index)) {
6301 return (SK_PNMI_ERR_BAD_VALUE);
6304 for (Offset=0; Index < Limit; Index ++) {
6308 * XXX Not yet implemented. Return always BAD_VALUE, because the table
6312 return (SK_PNMI_ERR_BAD_VALUE);
6315 return (SK_PNMI_ERR_OK);
6318 /*****************************************************************************
6320 * VirtualConf - Calculates the values of configuration OIDs for virtual port
6323 * We handle here the get of the configuration group OIDs, which are
6324 * a little bit complicated. The virtual port consists of all currently
6325 * active physical ports. If multiple ports are active and configured
6326 * differently we get in some trouble to return a single value. So we
6327 * get the value of the first active port and compare it with that of
6328 * the other active ports. If they are not the same, we return a value
6329 * that indicates that the state is indeterminated.
6334 PNMI_STATIC void VirtualConf(
6335 SK_AC *pAC, /* Pointer to adapter context */
6336 SK_IOC IoC, /* IO context handle */
6337 SK_U32 Id, /* Object ID that is to be processed */
6338 char *pBuf) /* Buffer to which to mgmt data will be retrieved */
6340 unsigned int PhysPortMax;
6341 unsigned int PhysPortIndex;
6343 SK_BOOL PortActiveFlag;
6347 PortActiveFlag = SK_FALSE;
6348 PhysPortMax = pAC->GIni.GIMacsFound;
6350 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
6353 /* Check if the physical port is active */
6354 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6359 PortActiveFlag = SK_TRUE;
6363 case OID_SKGE_LINK_CAP:
6366 * Different capabilities should not happen, but
6367 * in the case of the cases OR them all together.
6368 * From a curious point of view the virtual port
6369 * is capable of all found capabilities.
6371 *pBuf |= pAC->GIni.GP[PhysPortIndex].PLinkCap;
6374 case OID_SKGE_LINK_MODE:
6375 /* Check if it is the first active port */
6378 *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
6383 * If we find an active port with a different link
6384 * mode than the first one we return a value that
6385 * indicates that the link mode is indeterminated.
6387 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkModeConf
6390 *pBuf = SK_LMODE_INDETERMINATED;
6394 case OID_SKGE_LINK_MODE_STATUS:
6395 /* Get the link mode of the physical port */
6396 Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
6398 /* Check if it is the first active port */
6406 * If we find an active port with a different link
6407 * mode status than the first one we return a value
6408 * that indicates that the link mode status is
6411 if (*pBuf != Val8) {
6413 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6417 case OID_SKGE_LINK_STATUS:
6418 /* Get the link status of the physical port */
6419 Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
6421 /* Check if it is the first active port */
6429 * If we find an active port with a different link
6430 * status than the first one, we return a value
6431 * that indicates that the link status is
6434 if (*pBuf != Val8) {
6436 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6440 case OID_SKGE_FLOWCTRL_CAP:
6441 /* Check if it is the first active port */
6444 *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
6449 * From a curious point of view the virtual port
6450 * is capable of all found capabilities.
6452 *pBuf |= pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
6455 case OID_SKGE_FLOWCTRL_MODE:
6456 /* Check if it is the first active port */
6459 *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
6464 * If we find an active port with a different flow
6465 * control mode than the first one, we return a value
6466 * that indicates that the mode is indeterminated.
6468 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode) {
6470 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6474 case OID_SKGE_FLOWCTRL_STATUS:
6475 /* Check if it is the first active port */
6478 *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
6483 * If we find an active port with a different flow
6484 * control status than the first one, we return a
6485 * value that indicates that the status is
6488 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus) {
6490 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6494 case OID_SKGE_PHY_OPERATION_CAP:
6495 /* Check if it is the first active port */
6498 *pBuf = pAC->GIni.GP[PhysPortIndex].PMSCap;
6503 * From a curious point of view the virtual port
6504 * is capable of all found capabilities.
6506 *pBuf |= pAC->GIni.GP[PhysPortIndex].PMSCap;
6509 case OID_SKGE_PHY_OPERATION_MODE:
6510 /* Check if it is the first active port */
6513 *pBuf = pAC->GIni.GP[PhysPortIndex].PMSMode;
6518 * If we find an active port with a different master/
6519 * slave mode than the first one, we return a value
6520 * that indicates that the mode is indeterminated.
6522 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PMSMode) {
6524 *pBuf = SK_MS_MODE_INDETERMINATED;
6528 case OID_SKGE_PHY_OPERATION_STATUS:
6529 /* Check if it is the first active port */
6532 *pBuf = pAC->GIni.GP[PhysPortIndex].PMSStatus;
6537 * If we find an active port with a different master/
6538 * slave status than the first one, we return a
6539 * value that indicates that the status is
6542 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PMSStatus) {
6544 *pBuf = SK_MS_STAT_INDETERMINATED;
6548 case OID_SKGE_SPEED_MODE:
6549 /* Check if it is the first active port */
6552 *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
6557 * If we find an active port with a different flow
6558 * control mode than the first one, we return a value
6559 * that indicates that the mode is indeterminated.
6561 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkSpeed) {
6563 *pBuf = SK_LSPEED_INDETERMINATED;
6567 case OID_SKGE_SPEED_STATUS:
6568 /* Check if it is the first active port */
6571 *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
6576 * If we find an active port with a different flow
6577 * control status than the first one, we return a
6578 * value that indicates that the status is
6581 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed) {
6583 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6590 * If no port is active return an indeterminated answer
6592 if (!PortActiveFlag) {
6596 case OID_SKGE_LINK_CAP:
6597 *pBuf = SK_LMODE_CAP_INDETERMINATED;
6600 case OID_SKGE_LINK_MODE:
6601 *pBuf = SK_LMODE_INDETERMINATED;
6604 case OID_SKGE_LINK_MODE_STATUS:
6605 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6608 case OID_SKGE_LINK_STATUS:
6609 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6612 case OID_SKGE_FLOWCTRL_CAP:
6613 case OID_SKGE_FLOWCTRL_MODE:
6614 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6617 case OID_SKGE_FLOWCTRL_STATUS:
6618 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6621 case OID_SKGE_PHY_OPERATION_CAP:
6622 *pBuf = SK_MS_CAP_INDETERMINATED;
6625 case OID_SKGE_PHY_OPERATION_MODE:
6626 *pBuf = SK_MS_MODE_INDETERMINATED;
6629 case OID_SKGE_PHY_OPERATION_STATUS:
6630 *pBuf = SK_MS_STAT_INDETERMINATED;
6632 case OID_SKGE_SPEED_CAP:
6633 *pBuf = SK_LSPEED_CAP_INDETERMINATED;
6636 case OID_SKGE_SPEED_MODE:
6637 *pBuf = SK_LSPEED_INDETERMINATED;
6640 case OID_SKGE_SPEED_STATUS:
6641 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6647 /*****************************************************************************
6649 * CalculateLinkStatus - Determins the link status of a physical port
6652 * Determins the link status the following way:
6653 * LSTAT_PHY_DOWN: Link is down
6654 * LSTAT_AUTONEG: Auto-negotiation failed
6655 * LSTAT_LOG_DOWN: Link is up but RLMT did not yet put the port
6657 * LSTAT_LOG_UP: RLMT marked the port as up
6660 * Link status of physical port
6662 PNMI_STATIC SK_U8 CalculateLinkStatus(
6663 SK_AC *pAC, /* Pointer to adapter context */
6664 SK_IOC IoC, /* IO context handle */
6665 unsigned int PhysPortIndex) /* Physical port index */
6670 if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
6672 Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
6674 else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
6676 Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
6678 else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
6680 Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
6683 Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
6689 /*****************************************************************************
6691 * CalculateLinkModeStatus - Determins the link mode status of a phys. port
6694 * The COMMON module only tells us if the mode is half or full duplex.
6695 * But in the decade of auto sensing it is usefull for the user to
6696 * know if the mode was negotiated or forced. Therefore we have a
6697 * look to the mode, which was last used by the negotiation process.
6700 * The link mode status
6702 PNMI_STATIC SK_U8 CalculateLinkModeStatus(
6703 SK_AC *pAC, /* Pointer to adapter context */
6704 SK_IOC IoC, /* IO context handle */
6705 unsigned int PhysPortIndex) /* Physical port index */
6710 /* Get the current mode, which can be full or half duplex */
6711 Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
6713 /* Check if no valid mode could be found (link is down) */
6714 if (Result < SK_LMODE_STAT_HALF) {
6716 Result = SK_LMODE_STAT_UNKNOWN;
6718 else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
6721 * Auto-negotiation was used to bring up the link. Change
6722 * the already found duplex status that it indicates
6723 * auto-negotiation was involved.
6725 if (Result == SK_LMODE_STAT_HALF) {
6727 Result = SK_LMODE_STAT_AUTOHALF;
6729 else if (Result == SK_LMODE_STAT_FULL) {
6731 Result = SK_LMODE_STAT_AUTOFULL;
6738 /*****************************************************************************
6740 * GetVpdKeyArr - Obtain an array of VPD keys
6743 * Read the VPD keys and build an array of VPD keys, which are
6747 * SK_PNMI_ERR_OK Task successfully performed.
6748 * SK_PNMI_ERR_GENERAL Something went wrong.
6750 PNMI_STATIC int GetVpdKeyArr(
6751 SK_AC *pAC, /* Pointer to adapter context */
6752 SK_IOC IoC, /* IO context handle */
6753 char *pKeyArr, /* Ptr KeyArray */
6754 unsigned int KeyArrLen, /* Length of array in bytes */
6755 unsigned int *pKeyNo) /* Number of keys */
6757 unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE;
6758 char BufKeys[SK_PNMI_VPD_BUFSIZE];
6759 unsigned int StartOffset;
6760 unsigned int Offset;
6765 SK_MEMSET(pKeyArr, 0, KeyArrLen);
6770 Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
6774 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
6777 return (SK_PNMI_ERR_GENERAL);
6779 /* If no keys are available return now */
6780 if (*pKeyNo == 0 || BufKeysLen == 0) {
6782 return (SK_PNMI_ERR_OK);
6785 * If the key list is too long for us trunc it and give a
6786 * errorlog notification. This case should not happen because
6787 * the maximum number of keys is limited due to RAM limitations
6789 if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
6791 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
6794 *pKeyNo = SK_PNMI_VPD_ENTRIES;
6798 * Now build an array of fixed string length size and copy
6799 * the keys together.
6801 for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
6804 if (BufKeys[Offset] != 0) {
6809 if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
6811 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
6813 return (SK_PNMI_ERR_GENERAL);
6816 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6817 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6820 StartOffset = Offset + 1;
6823 /* Last key not zero terminated? Get it anyway */
6824 if (StartOffset < Offset) {
6826 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6827 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6830 return (SK_PNMI_ERR_OK);
6833 /*****************************************************************************
6835 * SirqUpdate - Let the SIRQ update its internal values
6838 * Just to be sure that the SIRQ module holds its internal data
6839 * structures up to date, we send an update event before we make
6843 * SK_PNMI_ERR_OK Task successfully performed.
6844 * SK_PNMI_ERR_GENERAL Something went wrong.
6846 PNMI_STATIC int SirqUpdate(
6847 SK_AC *pAC, /* Pointer to adapter context */
6848 SK_IOC IoC) /* IO context handle */
6850 SK_EVPARA EventParam;
6853 /* Was the module already updated during the current PNMI call? */
6854 if (pAC->Pnmi.SirqUpdatedFlag > 0) {
6856 return (SK_PNMI_ERR_OK);
6859 /* Send an synchronuous update event to the module */
6860 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6861 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
6863 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
6866 return (SK_PNMI_ERR_GENERAL);
6869 return (SK_PNMI_ERR_OK);
6872 /*****************************************************************************
6874 * RlmtUpdate - Let the RLMT update its internal values
6877 * Just to be sure that the RLMT module holds its internal data
6878 * structures up to date, we send an update event before we make
6882 * SK_PNMI_ERR_OK Task successfully performed.
6883 * SK_PNMI_ERR_GENERAL Something went wrong.
6885 PNMI_STATIC int RlmtUpdate(
6886 SK_AC *pAC, /* Pointer to adapter context */
6887 SK_IOC IoC, /* IO context handle */
6888 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6890 SK_EVPARA EventParam;
6893 /* Was the module already updated during the current PNMI call? */
6894 if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
6896 return (SK_PNMI_ERR_OK);
6899 /* Send an synchronuous update event to the module */
6900 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6901 EventParam.Para32[0] = NetIndex;
6902 EventParam.Para32[1] = (SK_U32)-1;
6903 if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
6905 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
6908 return (SK_PNMI_ERR_GENERAL);
6911 return (SK_PNMI_ERR_OK);
6914 /*****************************************************************************
6916 * MacUpdate - Force the XMAC to output the current statistic
6919 * The XMAC holds its statistic internally. To obtain the current
6920 * values we send a command so that the statistic data will
6921 * be written to apredefined memory area on the adapter.
6924 * SK_PNMI_ERR_OK Task successfully performed.
6925 * SK_PNMI_ERR_GENERAL Something went wrong.
6927 PNMI_STATIC int MacUpdate(
6928 SK_AC *pAC, /* Pointer to adapter context */
6929 SK_IOC IoC, /* IO context handle */
6930 unsigned int FirstMac, /* Index of the first Mac to be updated */
6931 unsigned int LastMac) /* Index of the last Mac to be updated */
6933 unsigned int MacIndex;
6936 * Were the statistics already updated during the
6937 * current PNMI call?
6939 if (pAC->Pnmi.MacUpdatedFlag > 0) {
6941 return (SK_PNMI_ERR_OK);
6944 /* Send an update command to all MACs specified */
6945 for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
6948 * 2002-09-13 pweber: Freeze the current sw counters.
6949 * (That should be done as close as
6950 * possible to the update of the
6953 if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
6954 pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
6957 /* 2002-09-13 pweber: Update the hw counter */
6958 if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
6960 return (SK_PNMI_ERR_GENERAL);
6964 return (SK_PNMI_ERR_OK);
6967 /*****************************************************************************
6969 * GetStatVal - Retrieve an XMAC statistic counter
6972 * Retrieves the statistic counter of a virtual or physical port. The
6973 * virtual port is identified by the index 0. It consists of all
6974 * currently active ports. To obtain the counter value for this port
6975 * we must add the statistic counter of all active ports. To grant
6976 * continuous counter values for the virtual port even when port
6977 * switches occur we must additionally add a delta value, which was
6978 * calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
6981 * Requested statistic value
6983 PNMI_STATIC SK_U64 GetStatVal(
6984 SK_AC *pAC, /* Pointer to adapter context */
6985 SK_IOC IoC, /* IO context handle */
6986 unsigned int LogPortIndex, /* Index of the logical Port to be processed */
6987 unsigned int StatIndex, /* Index to statistic value */
6988 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6990 unsigned int PhysPortIndex;
6991 unsigned int PhysPortMax;
6995 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
6997 PhysPortIndex = NetIndex;
6998 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
7000 else { /* Single Net mode */
7002 if (LogPortIndex == 0) {
7004 PhysPortMax = pAC->GIni.GIMacsFound;
7006 /* Add counter of all active ports */
7007 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
7010 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
7012 Val += GetPhysStatVal(pAC, IoC, PhysPortIndex,
7017 /* Correct value because of port switches */
7018 Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
7021 /* Get counter value of physical port */
7022 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
7023 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
7029 /*****************************************************************************
7031 * GetPhysStatVal - Get counter value for physical port
7034 * Builds a 64bit counter value. Except for the octet counters
7035 * the lower 32bit are counted in hardware and the upper 32bit
7036 * in software by monitoring counter overflow interrupts in the
7037 * event handler. To grant continous counter values during XMAC
7038 * resets (caused by a workaround) we must add a delta value.
7039 * The delta was calculated in the event handler when a
7040 * SK_PNMI_EVT_XMAC_RESET was received.
7045 PNMI_STATIC SK_U64 GetPhysStatVal(
7046 SK_AC *pAC, /* Pointer to adapter context */
7047 SK_IOC IoC, /* IO context handle */
7048 unsigned int PhysPortIndex, /* Index of the logical Port to be processed */
7049 unsigned int StatIndex) /* Index to statistic value */
7057 SK_PNMI_PORT *pPnmiPrt;
7058 SK_GEMACFUNC *pFnMac;
7060 MacType = pAC->GIni.GIMacType;
7062 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
7063 if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
7064 pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
7067 pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex];
7070 pFnMac = &pAC->GIni.GIFunc;
7072 switch (StatIndex) {
7075 /* Not supported by GMAC */
7076 if (MacType == SK_MAC_GMAC) {
7080 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7081 StatAddr[StatIndex][MacType].Reg,
7083 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7086 case SK_PNMI_HTX_OCTET:
7087 case SK_PNMI_HRX_OCTET:
7088 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7089 StatAddr[StatIndex][MacType].Reg,
7091 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7092 StatAddr[StatIndex + 1][MacType].Reg,
7096 case SK_PNMI_HTX_BURST:
7097 case SK_PNMI_HTX_EXCESS_DEF:
7098 case SK_PNMI_HTX_CARRIER:
7099 /* Not supported by GMAC */
7100 if (MacType == SK_MAC_GMAC) {
7104 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7105 StatAddr[StatIndex][MacType].Reg,
7107 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7110 case SK_PNMI_HTX_MACC:
7111 /* GMAC only supports PAUSE MAC control frames */
7112 if (MacType == SK_MAC_GMAC) {
7113 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, SK_PNMI_HTX_PMACC);
7118 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7119 StatAddr[StatIndex][MacType].Reg,
7121 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7124 case SK_PNMI_HTX_COL:
7125 case SK_PNMI_HRX_UNDERSIZE:
7126 /* Not supported by XMAC */
7127 if (MacType == SK_MAC_XMAC) {
7131 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7132 StatAddr[StatIndex][MacType].Reg,
7134 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7138 case SK_PNMI_HTX_DEFFERAL:
7139 /* Not supported by GMAC */
7140 if (MacType == SK_MAC_GMAC) {
7145 * XMAC counts frames with deferred transmission
7146 * even in full-duplex mode.
7148 * In full-duplex mode the counter remains constant!
7150 if ((pAC->GIni.GP[PhysPortIndex].PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) ||
7151 (pAC->GIni.GP[PhysPortIndex].PLinkModeStatus == SK_LMODE_STAT_FULL)) {
7157 /* Otherwise get contents of hardware register. */
7158 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7159 StatAddr[SK_PNMI_HTX_DEFFERAL][MacType].Reg,
7161 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7165 case SK_PNMI_HRX_BADOCTET:
7166 /* Not supported by XMAC */
7167 if (MacType == SK_MAC_XMAC) {
7171 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7172 StatAddr[StatIndex][MacType].Reg,
7174 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7175 StatAddr[StatIndex + 1][MacType].Reg,
7179 case SK_PNMI_HTX_OCTETLOW:
7180 case SK_PNMI_HRX_OCTETLOW:
7181 case SK_PNMI_HRX_BADOCTETLOW:
7184 case SK_PNMI_HRX_LONGFRAMES:
7185 /* For XMAC the SW counter is managed by PNMI */
7186 if (MacType == SK_MAC_XMAC) {
7187 return (pPnmiPrt->StatRxLongFrameCts);
7190 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7191 StatAddr[StatIndex][MacType].Reg,
7193 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7196 case SK_PNMI_HRX_TOO_LONG:
7197 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7198 StatAddr[StatIndex][MacType].Reg,
7200 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7202 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7206 /* For GMAC the SW counter is additionally managed by PNMI */
7207 Val += pPnmiPrt->StatRxFrameTooLongCts;
7212 * Frames longer than IEEE 802.3 frame max size are counted
7213 * by XMAC in frame_too_long counter even reception of long
7214 * frames was enabled and the frame was correct.
7215 * So correct the value by subtracting RxLongFrame counter.
7217 Val -= pPnmiPrt->StatRxLongFrameCts;
7224 LowVal = (SK_U32)Val;
7225 HighVal = (SK_U32)(Val >> 32);
7228 case SK_PNMI_HRX_SHORTS:
7229 /* Not supported by GMAC */
7230 if (MacType == SK_MAC_GMAC) {
7236 * XMAC counts short frame errors even if link down (#10620)
7238 * If link-down the counter remains constant
7240 if (pAC->GIni.GP[PhysPortIndex].PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
7242 /* Otherwise get incremental difference */
7243 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7244 StatAddr[StatIndex][MacType].Reg,
7246 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7248 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7249 Val -= pPnmiPrt->RxShortZeroMark;
7251 LowVal = (SK_U32)Val;
7252 HighVal = (SK_U32)(Val >> 32);
7256 case SK_PNMI_HRX_MACC:
7257 case SK_PNMI_HRX_MACC_UNKWN:
7258 case SK_PNMI_HRX_BURST:
7259 case SK_PNMI_HRX_MISSED:
7260 case SK_PNMI_HRX_FRAMING:
7261 case SK_PNMI_HRX_CARRIER:
7262 case SK_PNMI_HRX_IRLENGTH:
7263 case SK_PNMI_HRX_SYMBOL:
7264 case SK_PNMI_HRX_CEXT:
7265 /* Not supported by GMAC */
7266 if (MacType == SK_MAC_GMAC) {
7271 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7272 StatAddr[StatIndex][MacType].Reg,
7274 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7277 case SK_PNMI_HRX_PMACC_ERR:
7278 /* For GMAC the SW counter is managed by PNMI */
7279 if (MacType == SK_MAC_GMAC) {
7280 return (pPnmiPrt->StatRxPMaccErr);
7283 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7284 StatAddr[StatIndex][MacType].Reg,
7286 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7289 /* SW counter managed by PNMI */
7290 case SK_PNMI_HTX_SYNC:
7291 LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
7292 HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
7295 /* SW counter managed by PNMI */
7296 case SK_PNMI_HTX_SYNC_OCTET:
7297 LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
7298 HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
7301 case SK_PNMI_HRX_FCS:
7303 * Broadcom filters fcs errors and counts it in
7304 * Receive Error Counter register
7306 if (pAC->GIni.GP[PhysPortIndex].PhyType == SK_PHY_BCOM) {
7307 /* do not read while not initialized (PHY_READ hangs!)*/
7308 if (pAC->GIni.GP[PhysPortIndex].PState) {
7309 PHY_READ(IoC, &pAC->GIni.GP[PhysPortIndex],
7310 PhysPortIndex, PHY_BCOM_RE_CTR,
7315 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7318 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7319 StatAddr[StatIndex][MacType].Reg,
7321 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7326 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7327 StatAddr[StatIndex][MacType].Reg,
7329 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7333 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7335 /* Correct value because of possible XMAC reset. XMAC Errata #2 */
7336 Val += pPnmiPrt->CounterOffset[StatIndex];
7341 /*****************************************************************************
7343 * ResetCounter - Set all counters and timestamps to zero
7346 * Notifies other common modules which store statistic data to
7347 * reset their counters and finally reset our own counters.
7352 PNMI_STATIC void ResetCounter(
7353 SK_AC *pAC, /* Pointer to adapter context */
7354 SK_IOC IoC, /* IO context handle */
7357 unsigned int PhysPortIndex;
7358 SK_EVPARA EventParam;
7361 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
7363 /* Notify sensor module */
7364 SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
7366 /* Notify RLMT module */
7367 EventParam.Para32[0] = NetIndex;
7368 EventParam.Para32[1] = (SK_U32)-1;
7369 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
7370 EventParam.Para32[1] = 0;
7372 /* Notify SIRQ module */
7373 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
7375 /* Notify CSUM module */
7377 EventParam.Para32[0] = NetIndex;
7378 EventParam.Para32[1] = (SK_U32)-1;
7379 SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
7383 /* Clear XMAC statistic */
7384 for (PhysPortIndex = 0; PhysPortIndex <
7385 (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
7387 (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex);
7389 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
7390 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
7391 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7392 CounterOffset, 0, sizeof(pAC->Pnmi.Port[
7393 PhysPortIndex].CounterOffset));
7394 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
7395 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
7396 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7397 StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
7398 PhysPortIndex].StatSyncOctetsCts));
7399 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7400 StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
7401 PhysPortIndex].StatRxLongFrameCts));
7402 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7403 StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[
7404 PhysPortIndex].StatRxFrameTooLongCts));
7405 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7406 StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[
7407 PhysPortIndex].StatRxPMaccErr));
7411 * Clear local statistics
7413 SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
7414 sizeof(pAC->Pnmi.VirtualCounterOffset));
7415 pAC->Pnmi.RlmtChangeCts = 0;
7416 pAC->Pnmi.RlmtChangeTime = 0;
7417 SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
7418 sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
7419 pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
7420 pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
7421 pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
7422 pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
7423 pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
7424 pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
7425 pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
7426 pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
7427 pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
7428 pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
7429 pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
7430 pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
7433 /*****************************************************************************
7435 * GetTrapEntry - Get an entry in the trap buffer
7438 * The trap buffer stores various events. A user application somehow
7439 * gets notified that an event occured and retrieves the trap buffer
7440 * contens (or simply polls the buffer). The buffer is organized as
7441 * a ring which stores the newest traps at the beginning. The oldest
7442 * traps are overwritten by the newest ones. Each trap entry has a
7443 * unique number, so that applications may detect new trap entries.
7446 * A pointer to the trap entry
7448 PNMI_STATIC char* GetTrapEntry(
7449 SK_AC *pAC, /* Pointer to adapter context */
7450 SK_U32 TrapId, /* SNMP ID of the trap */
7451 unsigned int Size) /* Space needed for trap entry */
7453 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7454 unsigned int BufFree = pAC->Pnmi.TrapBufFree;
7455 unsigned int Beg = pAC->Pnmi.TrapQueueBeg;
7456 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7457 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7459 unsigned int NeededSpace;
7460 unsigned int EntrySize;
7465 /* Last byte of entry will get a copy of the entry length */
7469 * Calculate needed buffer space */
7476 NeededSpace = Beg + Size;
7481 * Check if enough buffer space is provided. Otherwise
7482 * free some entries. Leave one byte space between begin
7483 * and end of buffer to make it possible to detect whether
7484 * the buffer is full or empty
7486 while (BufFree < NeededSpace + 1) {
7490 End = SK_PNMI_TRAP_QUEUE_LEN;
7493 EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
7494 BufFree += EntrySize;
7497 SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
7499 if (End == BufPad) {
7501 SK_MEMSET(pBuf, (char)(-1), End);
7510 * Insert new entry as first entry. Newest entries are
7511 * stored at the beginning of the queue.
7516 Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
7521 BufFree -= NeededSpace;
7523 /* Save the current offsets */
7524 pAC->Pnmi.TrapQueueBeg = Beg;
7525 pAC->Pnmi.TrapQueueEnd = End;
7526 pAC->Pnmi.TrapBufPad = BufPad;
7527 pAC->Pnmi.TrapBufFree = BufFree;
7529 /* Initialize the trap entry */
7530 *(pBuf + Beg + Size - 1) = (char)Size;
7531 *(pBuf + Beg) = (char)Size;
7532 Val32 = (pAC->Pnmi.TrapUnique) ++;
7533 SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
7534 SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
7535 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
7536 SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
7538 return (pBuf + Beg);
7541 /*****************************************************************************
7543 * CopyTrapQueue - Copies the trap buffer for the TRAP OID
7546 * On a query of the TRAP OID the trap buffer contents will be
7547 * copied continuously to the request buffer, which must be large
7548 * enough. No length check is performed.
7553 PNMI_STATIC void CopyTrapQueue(
7554 SK_AC *pAC, /* Pointer to adapter context */
7555 char *pDstBuf) /* Buffer to which the queued traps will be copied */
7557 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7558 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7559 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7560 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7562 unsigned int DstOff = 0;
7565 while (Trap != End) {
7567 Len = (unsigned int)*(pBuf + Trap);
7570 * Last byte containing a copy of the length will
7573 *(pDstBuf + DstOff) = (char)(Len - 1);
7574 SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
7578 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7585 /*****************************************************************************
7587 * GetTrapQueueLen - Get the length of the trap buffer
7590 * Evaluates the number of currently stored traps and the needed
7591 * buffer size to retrieve them.
7596 PNMI_STATIC void GetTrapQueueLen(
7597 SK_AC *pAC, /* Pointer to adapter context */
7598 unsigned int *pLen, /* Length in Bytes of all queued traps */
7599 unsigned int *pEntries) /* Returns number of trapes stored in queue */
7601 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7602 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7603 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7604 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7606 unsigned int Entries = 0;
7607 unsigned int TotalLen = 0;
7610 while (Trap != End) {
7612 Len = (unsigned int)*(pBuf + Trap);
7613 TotalLen += Len - 1;
7617 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7623 *pEntries = Entries;
7627 /*****************************************************************************
7629 * QueueSimpleTrap - Store a simple trap to the trap buffer
7632 * A simple trap is a trap with now additional data. It consists
7633 * simply of a trap code.
7638 PNMI_STATIC void QueueSimpleTrap(
7639 SK_AC *pAC, /* Pointer to adapter context */
7640 SK_U32 TrapId) /* Type of sensor trap */
7642 GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
7645 /*****************************************************************************
7647 * QueueSensorTrap - Stores a sensor trap in the trap buffer
7650 * Gets an entry in the trap buffer and fills it with sensor related
7656 PNMI_STATIC void QueueSensorTrap(
7657 SK_AC *pAC, /* Pointer to adapter context */
7658 SK_U32 TrapId, /* Type of sensor trap */
7659 unsigned int SensorIndex) /* Index of sensor which caused the trap */
7662 unsigned int Offset;
7663 unsigned int DescrLen;
7667 /* Get trap buffer entry */
7668 DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
7669 pBuf = GetTrapEntry(pAC, TrapId,
7670 SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
7671 Offset = SK_PNMI_TRAP_SIMPLE_LEN;
7673 /* Store additionally sensor trap related data */
7674 Val32 = OID_SKGE_SENSOR_INDEX;
7675 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7676 *(pBuf + Offset + 4) = 4;
7677 Val32 = (SK_U32)SensorIndex;
7678 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7681 Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
7682 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7683 *(pBuf + Offset + 4) = (char)DescrLen;
7684 SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
7686 Offset += DescrLen + 5;
7688 Val32 = OID_SKGE_SENSOR_TYPE;
7689 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7690 *(pBuf + Offset + 4) = 1;
7691 *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
7694 Val32 = OID_SKGE_SENSOR_VALUE;
7695 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7696 *(pBuf + Offset + 4) = 4;
7697 Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
7698 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7701 /*****************************************************************************
7703 * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
7706 * Nothing further to explain.
7711 PNMI_STATIC void QueueRlmtNewMacTrap(
7712 SK_AC *pAC, /* Pointer to adapter context */
7713 unsigned int ActiveMac) /* Index (0..n) of the currently active port */
7719 pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
7720 SK_PNMI_TRAP_RLMT_CHANGE_LEN);
7722 Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
7723 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7724 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7725 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
7728 /*****************************************************************************
7730 * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
7733 * Nothing further to explain.
7738 PNMI_STATIC void QueueRlmtPortTrap(
7739 SK_AC *pAC, /* Pointer to adapter context */
7740 SK_U32 TrapId, /* Type of RLMT port trap */
7741 unsigned int PortIndex) /* Index of the port, which changed its state */
7747 pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
7749 Val32 = OID_SKGE_RLMT_PORT_INDEX;
7750 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7751 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7752 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
7755 /*****************************************************************************
7757 * CopyMac - Copies a MAC address
7760 * Nothing further to explain.
7765 PNMI_STATIC void CopyMac(
7766 char *pDst, /* Pointer to destination buffer */
7767 SK_MAC_ADDR *pMac) /* Pointer of Source */
7772 for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
7774 *(pDst + i) = pMac->a[i];
7779 #ifdef SK_POWER_MGMT
7780 /*****************************************************************************
7782 * PowerManagement - OID handler function of PowerManagement OIDs
7785 * The code is simple. No description necessary.
7788 * SK_PNMI_ERR_OK The request was successfully performed.
7789 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7790 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7791 * the correct data (e.g. a 32bit value is
7792 * needed, but a 16 bit value was passed).
7793 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7794 * exist (e.g. port instance 3 on a two port
7798 PNMI_STATIC int PowerManagement(
7799 SK_AC *pAC, /* Pointer to adapter context */
7800 SK_IOC IoC, /* IO context handle */
7801 int Action, /* Get/PreSet/Set action */
7802 SK_U32 Id, /* Object ID that is to be processed */
7803 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
7804 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
7805 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7806 unsigned int TableIndex, /* Index to the Id table */
7807 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
7810 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7813 * Check instance. We only handle single instance variables
7815 if (Instance != (SK_U32)(-1) && Instance != 1) {
7818 return (SK_PNMI_ERR_UNKNOWN_INST);
7824 if (Action == SK_PNMI_GET) {
7831 case OID_PNP_CAPABILITIES:
7832 if (*pLen < sizeof(SK_PNP_CAPABILITIES)) {
7834 *pLen = sizeof(SK_PNP_CAPABILITIES);
7835 return (SK_PNMI_ERR_TOO_SHORT);
7839 case OID_PNP_QUERY_POWER:
7840 case OID_PNP_ENABLE_WAKE_UP:
7841 if (*pLen < sizeof(SK_U32)) {
7843 *pLen = sizeof(SK_U32);
7844 return (SK_PNMI_ERR_TOO_SHORT);
7848 case OID_PNP_SET_POWER:
7849 case OID_PNP_ADD_WAKE_UP_PATTERN:
7850 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7854 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040,
7857 return (SK_PNMI_ERR_GENERAL);
7865 case OID_PNP_CAPABILITIES:
7866 RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen);
7869 case OID_PNP_QUERY_POWER:
7870 /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
7871 the miniport to indicate whether it can transition its NIC
7872 to the low-power state.
7873 A miniport driver must always return NDIS_STATUS_SUCCESS
7874 to a query of OID_PNP_QUERY_POWER. */
7875 RetCode = SK_PNMI_ERR_OK;
7878 /* NDIS handles these OIDs as write-only.
7879 * So in case of get action the buffer with written length = 0
7882 case OID_PNP_SET_POWER:
7883 case OID_PNP_ADD_WAKE_UP_PATTERN:
7884 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7886 RetCode = SK_PNMI_ERR_OK;
7889 case OID_PNP_ENABLE_WAKE_UP:
7890 RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen);
7894 RetCode = SK_PNMI_ERR_GENERAL;
7902 * From here SET or PRESET action. Check if the passed
7903 * buffer length is plausible.
7906 case OID_PNP_SET_POWER:
7907 case OID_PNP_ENABLE_WAKE_UP:
7908 if (*pLen < sizeof(SK_U32)) {
7910 *pLen = sizeof(SK_U32);
7911 return (SK_PNMI_ERR_TOO_SHORT);
7913 if (*pLen != sizeof(SK_U32)) {
7916 return (SK_PNMI_ERR_BAD_VALUE);
7920 case OID_PNP_ADD_WAKE_UP_PATTERN:
7921 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7922 if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) {
7925 return (SK_PNMI_ERR_BAD_VALUE);
7931 return (SK_PNMI_ERR_READ_ONLY);
7935 * Perform preset or set
7938 /* POWER module does not support PRESET action */
7939 if (Action == SK_PNMI_PRESET) {
7940 return (SK_PNMI_ERR_OK);
7944 case OID_PNP_SET_POWER:
7945 RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen);
7948 case OID_PNP_ADD_WAKE_UP_PATTERN:
7949 RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen);
7952 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7953 RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen);
7956 case OID_PNP_ENABLE_WAKE_UP:
7957 RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen);
7961 RetCode = SK_PNMI_ERR_GENERAL;
7966 #endif /* SK_POWER_MGMT */
7969 /*****************************************************************************
7971 * Vct - OID handler function of OIDs
7974 * The code is simple. No description necessary.
7977 * SK_PNMI_ERR_OK The request was performed successfully.
7978 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7979 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7980 * the correct data (e.g. a 32bit value is
7981 * needed, but a 16 bit value was passed).
7982 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7983 * exist (e.g. port instance 3 on a two port
7985 * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed.
7989 PNMI_STATIC int Vct(
7990 SK_AC *pAC, /* Pointer to adapter context */
7991 SK_IOC IoC, /* IO context handle */
7992 int Action, /* Get/PreSet/Set action */
7993 SK_U32 Id, /* Object ID that is to be processed */
7994 char *pBuf, /* Buffer to which the mgmt data will be copied */
7995 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
7996 SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */
7997 unsigned int TableIndex, /* Index to the Id table */
7998 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
8001 SK_PNMI_VCT *pVctBackupData;
8004 SK_U32 PhysPortIndex;
8008 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
8014 * Calculate the port indexes from the instance.
8016 PhysPortMax = pAC->GIni.GIMacsFound;
8017 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
8019 /* Dual net mode? */
8020 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
8024 if ((Instance != (SK_U32) (-1))) {
8025 /* Check instance range. */
8026 if ((Instance < 2) || (Instance > LogPortMax)) {
8028 return (SK_PNMI_ERR_UNKNOWN_INST);
8031 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
8032 PhysPortIndex = NetIndex;
8035 PhysPortIndex = Instance - 2;
8037 Limit = PhysPortIndex + 1;
8040 * Instance == (SK_U32) (-1), get all Instances of that OID.
8042 * Not implemented yet. May be used in future releases.
8045 Limit = PhysPortMax;
8048 pPrt = &pAC->GIni.GP[PhysPortIndex];
8049 if (pPrt->PHWLinkUp) {
8059 if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
8061 return (SK_PNMI_ERR_GENERAL);
8064 /* Initialize backup data pointer. */
8065 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
8068 * Check action type.
8070 if (Action == SK_PNMI_GET) {
8076 case OID_SKGE_VCT_GET:
8077 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
8078 *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
8079 return (SK_PNMI_ERR_TOO_SHORT);
8083 case OID_SKGE_VCT_STATUS:
8084 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
8085 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
8086 return (SK_PNMI_ERR_TOO_SHORT);
8092 return (SK_PNMI_ERR_GENERAL);
8099 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8102 case OID_SKGE_VCT_GET:
8103 if ((Link == SK_FALSE) &&
8104 (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
8105 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
8107 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
8108 pAC->Pnmi.VctStatus[PhysPortIndex] |=
8109 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
8111 /* Copy results for later use to PNMI struct. */
8112 for (i = 0; i < 4; i++) {
8113 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
8114 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
8115 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
8118 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
8119 CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
8124 pVctBackupData->PMdiPairLen[i] = CableLength;
8125 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
8128 Para.Para32[0] = PhysPortIndex;
8129 Para.Para32[1] = -1;
8130 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
8131 SkEventDispatcher(pAC, IoC);
8134 ; /* VCT test is running. */
8138 /* Get all results. */
8139 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
8140 Offset += sizeof(SK_U8);
8141 *(pBuf + Offset) = pPrt->PCableLen;
8142 Offset += sizeof(SK_U8);
8143 for (i = 0; i < 4; i++) {
8144 SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
8145 Offset += sizeof(SK_U32);
8147 for (i = 0; i < 4; i++) {
8148 *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
8149 Offset += sizeof(SK_U8);
8152 RetCode = SK_PNMI_ERR_OK;
8155 case OID_SKGE_VCT_STATUS:
8156 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
8157 Offset += sizeof(SK_U8);
8158 RetCode = SK_PNMI_ERR_OK;
8163 return (SK_PNMI_ERR_GENERAL);
8169 } /* if SK_PNMI_GET */
8172 * From here SET or PRESET action. Check if the passed
8173 * buffer length is plausible.
8180 case OID_SKGE_VCT_SET:
8181 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
8182 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
8183 return (SK_PNMI_ERR_TOO_SHORT);
8189 return (SK_PNMI_ERR_GENERAL);
8193 * Perform preset or set.
8196 /* VCT does not support PRESET action. */
8197 if (Action == SK_PNMI_PRESET) {
8198 return (SK_PNMI_ERR_OK);
8202 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8204 case OID_SKGE_VCT_SET: /* Start VCT test. */
8205 if (Link == SK_FALSE) {
8206 SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
8208 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
8209 if (RetCode == 0) { /* RetCode: 0 => Start! */
8210 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
8211 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8212 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
8215 * Start VCT timer counter.
8217 SK_MEMSET((char *) &Para, 0, sizeof(Para));
8218 Para.Para32[0] = PhysPortIndex;
8219 Para.Para32[1] = -1;
8220 SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
8221 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
8222 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8223 RetCode = SK_PNMI_ERR_OK;
8225 else { /* RetCode: 2 => Running! */
8226 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8227 RetCode = SK_PNMI_ERR_OK;
8230 else { /* RetCode: 4 => Link! */
8232 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8233 RetCode = SK_PNMI_ERR_OK;
8235 Offset += sizeof(SK_U32);
8240 return (SK_PNMI_ERR_GENERAL);
8249 PNMI_STATIC void CheckVctStatus(
8254 SK_U32 PhysPortIndex)
8257 SK_PNMI_VCT *pVctData;
8259 SK_U8 LinkSpeedUsed;
8261 pPrt = &pAC->GIni.GP[PhysPortIndex];
8263 pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
8264 pVctData->VctStatus = SK_PNMI_VCT_NONE;
8266 if (!pPrt->PHWLinkUp) {
8268 /* Was a VCT test ever made before? */
8269 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8270 if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
8271 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8274 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8278 /* Check VCT test status. */
8279 RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
8280 if (RetCode == 2) { /* VCT test is running. */
8281 pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
8283 else { /* VCT data was copied to pAC here. Check PENDING state. */
8284 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
8285 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8289 if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
8290 pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
8295 /* Was a VCT test ever made before? */
8296 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8297 pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8298 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8301 /* DSP only valid in 100/1000 modes. */
8302 LinkSpeedUsed = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
8303 if (LinkSpeedUsed != SK_LSPEED_STAT_10MBPS) {
8304 pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
8308 } /* CheckVctStatus */
8310 #endif /* CONFIG_SK98 */