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