[PATCH] sk98 vendor driver update
[linux-2.6/history.git] / drivers / net / sk98lin / skgepnmi.c
blob9efd7a766ebc44bb3d33a02be23f9be91f42a67e
1 /*****************************************************************************
3 * Name: skgepnmi.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.109 $
6 * Date: $Date: 2003/07/17 14:15:24 $
7 * Purpose: Private Network Management Interface
9 ****************************************************************************/
11 /******************************************************************************
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
21 * The information in this file is provided "AS IS" without warranty.
23 ******************************************************************************/
25 /*****************************************************************************
27 * History:
29 * $Log: skgepnmi.c,v $
30 * Revision 1.109 2003/07/17 14:15:24 tschilli
31 * Bug in SkPnmiGenIoctl() fixed.
33 * Revision 1.108 2003/05/27 07:10:11 tschilli
34 * Bug in SkPnmiGenIoctl() fixed.
36 * Revision 1.107 2003/05/23 13:01:10 tschilli
37 * Code for DIAG support added (#define SK_DIAG_SUPPORT).
38 * Code for generic PNMI IOCTL support added. The new function
39 * SkPnmiGenIoctl() is used for this purpose.
40 * Handling of OID_SKGE_BOARDLEVEL added.
41 * Incorrect buffer size handling of OID_SKGE_MTU during GET action fixed.
42 * Return code handling in PowerManagement() fixed.
43 * Editorial changes.
45 * Revision 1.106 2003/04/10 14:47:31 rschmidt
46 * Fixed handling for OID_GEN_RCV_OK and OID_GEN_XMIT_OK for YUKON's GMAC
47 * in GetPhysStatVal().
48 * Replaced macro PHY_READ() with function call SkXmPhyRead().
49 * Made optimisations for readability and code size.
50 * Editorial changes.
52 * Revision 1.105 2003/04/09 12:51:32 rschmidt
53 * Fixed XMAC only handling for some events in SkPnmiEvent().
54 * Fixed return value for OID_GEN_RCV_OK (SK_PNMI_HRX) in GetPhysStatVal().
55 * Editorial changes.
57 * Revision 1.104 2003/03/27 11:18:21 tschilli
58 * BRK statements from DEBUG code removed.
59 * OID_GEN_XMIT_OK and OID_GEN_RCV_OK work with Yukon now.
60 * Copyright messages changed.
62 * Revision 1.103 2002/12/20 09:57:13 tschilli
63 * SK_PNMI_EVT_VCT_RESET event code changed.
64 * Unused variable from Vct() removed.
66 * Revision 1.102 2002/12/16 14:03:24 tschilli
67 * VCT code in Vct() changed.
69 * Revision 1.101 2002/12/16 09:04:10 tschilli
70 * Code for VCT handling added.
72 * Revision 1.100 2002/09/26 14:28:13 tschilli
73 * For XMAC the values in the SK_PNMI_PORT Port struct are copied to
74 * the new SK_PNMI_PORT BufPort struct during a MacUpdate() call.
75 * These values are used when GetPhysStatVal() is called. With this
76 * mechanism you get the best results when software corrections for
77 * counters are needed. Example: RX_LONGFRAMES.
79 * Revision 1.99 2002/09/17 12:31:19 tschilli
80 * OID_SKGE_TX_HW_ERROR_CTS, OID_SKGE_OUT_ERROR_CTS, OID_GEN_XMIT_ERROR:
81 * Double count of SK_PNMI_HTX_EXCESS_COL in function General() removed.
82 * OID_PNP_CAPABILITIES: sizeof(SK_PM_WAKE_UP_CAPABILITIES) changed to
83 * sizeof(SK_PNP_CAPABILITIES) in function PowerManagement().
85 * Revision 1.98 2002/09/10 09:00:03 rwahl
86 * Adapted boolean definitions according sktypes.
88 * Revision 1.97 2002/09/05 15:07:03 rwahl
89 * Editorial changes.
91 * Revision 1.96 2002/09/05 11:04:14 rwahl
92 * - Rx/Tx packets statistics of virtual port were zero on link down (#10750)
93 * - For GMAC the overflow IRQ for Rx longframe counter was not counted.
94 * - Incorrect calculation for oids OID_SKGE_RX_HW_ERROR_CTS,
95 * OID_SKGE_IN_ERRORS_CTS, OID_GEN_RCV_ERROR.
96 * - Moved correction for OID_SKGE_STAT_RX_TOO_LONG to GetPhysStatVal().
97 * - Editorial changes.
99 * Revision 1.95 2002/09/04 08:53:37 rwahl
100 * - Incorrect statistics for Rx_too_long counter with jumbo frame (#10751)
101 * - StatRxFrameTooLong & StatRxPMaccErr counters were not reset.
102 * - Fixed compiler warning for debug msg arg types.
104 * Revision 1.94 2002/08/09 15:42:14 rwahl
105 * - Fixed StatAddr table for GMAC.
106 * - VirtualConf(): returned indeterminated status for speed oids if no
107 * active port.
109 * Revision 1.93 2002/08/09 11:04:59 rwahl
110 * Added handler for link speed caps.
112 * Revision 1.92 2002/08/09 09:43:03 rwahl
113 * - Added handler for NDIS OID_PNP_xxx ids.
115 * Revision 1.91 2002/07/17 19:53:03 rwahl
116 * - Added StatOvrflwBit table for XMAC & GMAC.
117 * - Extended StatAddr table for GMAC. Added check of number of counters
118 * in enumeration and size of StatAddr table on init level.
119 * - Added use of GIFunc table.
120 * - ChipSet is not static anymore,
121 * - Extended SIRQ event handler for both mac types.
122 * - Fixed rx short counter bug (#10620)
123 * - Added handler for oids SKGE_SPEED_MODE & SKGE_SPEED_STATUS.
124 * - Extended GetPhysStatVal() for GMAC.
125 * - Editorial changes.
127 * Revision 1.90 2002/05/22 08:56:25 rwahl
128 * - Moved OID table to separate source file.
129 * - Fix: TX_DEFFERAL counter incremented in full-duplex mode.
130 * - Use string definitions for error msgs.
132 * Revision 1.89 2001/09/18 10:01:30 mkunz
133 * some OID's fixed for dualnetmode
135 * Revision 1.88 2001/08/02 07:58:08 rwahl
136 * - Fixed NetIndex to csum module at ResetCounter().
138 * Revision 1.87 2001/04/06 13:35:09 mkunz
139 * -Bugs fixed in handling of OID_SKGE_MTU and the VPD OID's
141 * Revision 1.86 2001/03/09 09:18:03 mkunz
142 * Changes in SK_DBG_MSG
144 * Revision 1.85 2001/03/08 09:37:31 mkunz
145 * Bugfix in ResetCounter for Pnmi.Port structure
147 * Revision 1.84 2001/03/06 09:04:55 mkunz
148 * Made some changes in instance calculation
150 * Revision 1.83 2001/02/15 09:15:32 mkunz
151 * Necessary changes for dual net mode added
153 * Revision 1.82 2001/02/07 08:24:19 mkunz
154 * -Made changes in handling of OID_SKGE_MTU
156 * Revision 1.81 2001/02/06 09:58:00 mkunz
157 * -Vpd bug fixed
158 * -OID_SKGE_MTU added
159 * -pnmi support for dual net mode. Interface function and macros extended
161 * Revision 1.80 2001/01/22 13:41:35 rassmann
162 * Supporting two nets on dual-port adapters.
164 * Revision 1.79 2000/12/05 14:57:40 cgoos
165 * SetStruct failed before first Link Up (link mode of virtual
166 * port "INDETERMINATED").
168 * Revision 1.78 2000/09/12 10:44:58 cgoos
169 * Fixed SK_PNMI_STORE_U32 calls with typecasted argument.
171 * Revision 1.77 2000/09/07 08:10:19 rwahl
172 * - Modified algorithm for 64bit NDIS statistic counters;
173 * returns 64bit or 32bit value depending on passed buffer
174 * size. Indicate capability for 64bit NDIS counter, if passed
175 * buffer size is zero. OID_GEN_XMIT_ERROR, OID_GEN_RCV_ERROR,
176 * and OID_GEN_RCV_NO_BUFFER handled as 64bit counter, too.
177 * - corrected OID_SKGE_RLMT_PORT_PREFERRED.
179 * Revision 1.76 2000/08/03 15:23:39 rwahl
180 * - Correction for FrameTooLong counter has to be moved to OID handling
181 * routines (instead of statistic counter routine).
182 * - Fix in XMAC Reset Event handling: Only offset counter for hardware
183 * statistic registers are updated.
185 * Revision 1.75 2000/08/01 16:46:05 rwahl
186 * - Added StatRxLongFrames counter and correction of FrameTooLong counter.
187 * - Added directive to control width (default = 32bit) of NDIS statistic
188 * counters (SK_NDIS_64BIT_CTR).
190 * Revision 1.74 2000/07/04 11:41:53 rwahl
191 * - Added volition connector type.
193 * Revision 1.73 2000/03/15 16:33:10 rwahl
194 * Fixed bug 10510; wrong reset of virtual port statistic counters.
196 * Revision 1.72 1999/12/06 16:15:53 rwahl
197 * Fixed problem of instance range for current and factory MAC address.
199 * Revision 1.71 1999/12/06 10:14:20 rwahl
200 * Fixed bug 10476; set operation for PHY_OPERATION_MODE.
202 * Revision 1.70 1999/11/22 13:33:34 cgoos
203 * Changed license header to GPL.
205 * Revision 1.69 1999/10/18 11:42:15 rwahl
206 * Added typecasts for checking event dependent param (debug only).
208 * Revision 1.68 1999/10/06 09:35:59 cgoos
209 * Added state check to PHY_READ call (hanged if called during startup).
211 * Revision 1.67 1999/09/22 09:53:20 rwahl
212 * - Read Broadcom register for updating FCS error counter (1000Base-T).
214 * Revision 1.66 1999/08/26 13:47:56 rwahl
215 * Added SK_DRIVER_SENDEVENT when queueing RLMT_CHANGE_THRES trap.
217 * Revision 1.65 1999/07/26 07:49:35 cgoos
218 * Added two typecasts to avoid compiler warnings.
220 * Revision 1.64 1999/05/20 09:24:12 cgoos
221 * Changes for 1000Base-T (sensors, Master/Slave).
223 * Revision 1.63 1999/04/13 15:11:58 mhaveman
224 * Moved include of rlmt.h to header skgepnmi.h because some macros
225 * are needed there.
227 * Revision 1.62 1999/04/13 15:08:07 mhaveman
228 * Replaced again SK_RLMT_CHECK_LINK with SK_PNMI_RLMT_MODE_CHK_LINK
229 * to grant unified interface by only using the PNMI header file.
230 * SK_PNMI_RLMT_MODE_CHK_LINK is defined the same as SK_RLMT_CHECK_LINK.
232 * Revision 1.61 1999/04/13 15:02:48 mhaveman
233 * Changes caused by review:
234 * -Changed some comments
235 * -Removed redundant check for OID_SKGE_PHYS_FAC_ADDR
236 * -Optimized PRESET check.
237 * -Meaning of error SK_ADDR_DUPLICATE_ADDRESS changed. Set of same
238 * address will now not cause this error. Removed corresponding check.
240 * Revision 1.60 1999/03/23 10:41:23 mhaveman
241 * Added comments.
243 * Revision 1.59 1999/02/19 08:01:28 mhaveman
244 * Fixed bug 10372 that after counter reset all ports were displayed
245 * as inactive.
247 * Revision 1.58 1999/02/16 18:04:47 mhaveman
248 * Fixed problem of twisted OIDs SENSOR_WAR_TIME and SENSOR_ERR_TIME.
250 * Revision 1.56 1999/01/27 12:29:11 mhaveman
251 * SkTimerStart was called with time value in milli seconds but needs
252 * micro seconds.
254 * Revision 1.55 1999/01/25 15:00:38 mhaveman
255 * Added support to allow multiple ports to be active. If this feature in
256 * future will be used, the Management Data Base variables PORT_ACTIVE
257 * and PORT_PREFERED should be moved to the port specific part of RLMT.
258 * Currently they return the values of the first active physical port
259 * found. A set to the virtual port will actually change all active
260 * physical ports. A get returns the melted values of all active physical
261 * ports. If the port values differ a return value INDETERMINATED will
262 * be returned. This effects especially the CONF group.
264 * Revision 1.54 1999/01/19 10:10:22 mhaveman
265 * -Fixed bug 10354: Counter values of virtual port were wrong after port
266 * switches
267 * -Added check if a switch to the same port is notified.
269 * Revision 1.53 1999/01/07 09:25:21 mhaveman
270 * Forgot to initialize a variable.
272 * Revision 1.52 1999/01/05 10:34:33 mhaveman
273 * Fixed little error in RlmtChangeEstimate calculation.
275 * Revision 1.51 1999/01/05 09:59:07 mhaveman
276 * -Moved timer start to init level 2
277 * -Redesigned port switch average calculation to avoid 64bit
278 * arithmetic.
280 * Revision 1.50 1998/12/10 15:13:59 mhaveman
281 * -Fixed: PHYS_CUR_ADDR returned wrong addresses
282 * -Fixed: RLMT_PORT_PREFERED and RLMT_CHANGE_THRES preset returned
283 * always BAD_VALUE.
284 * -Fixed: TRAP buffer seemed to sometimes suddenly empty
286 * Revision 1.49 1998/12/09 16:17:07 mhaveman
287 * Fixed: Couldnot delete VPD keys on UNIX.
289 * Revision 1.48 1998/12/09 14:11:10 mhaveman
290 * -Add: Debugmessage for XMAC_RESET supressed to minimize output.
291 * -Fixed: RlmtChangeThreshold will now be initialized.
292 * -Fixed: VPD_ENTRIES_LIST extended value with unnecessary space char.
293 * -Fixed: On VPD key creation an invalid key name could be created
294 * (e.g. A5)
295 * -Some minor changes in comments and code.
297 * Revision 1.47 1998/12/08 16:00:31 mhaveman
298 * -Fixed: For RLMT_PORT_ACTIVE will now be returned a 0 if no port
299 * is active.
300 * -Fixed: For the RLMT statistics group only the last value was
301 * returned and the rest of the buffer was filled with 0xff
302 * -Fixed: Mysteriously the preset on RLMT_MODE still returned
303 * BAD_VALUE.
304 * Revision 1.46 1998/12/08 10:04:56 mhaveman
305 * -Fixed: Preset on RLMT_MODE returned always BAD_VALUE error.
306 * -Fixed: Alignment error in GetStruct
307 * -Fixed: If for Get/Preset/SetStruct the buffer size is equal or
308 * larger than SK_PNMI_MIN_STRUCT_SIZE the return value is stored
309 * to the buffer. In this case the caller should always return
310 * ok to its upper routines. Only if the buffer size is less
311 * than SK_PNMI_MIN_STRUCT_SIZE and the return value is unequal
312 * to 0, an error should be returned by the caller.
313 * -Fixed: Wrong number of instances with RLMT statistic.
314 * -Fixed: Return now SK_LMODE_STAT_UNKNOWN if the LinkModeStatus is 0.
316 * Revision 1.45 1998/12/03 17:17:24 mhaveman
317 * -Removed for VPD create action the buffer size limitation to 4 bytes.
318 * -Pass now physical/active physical port to ADDR for CUR_ADDR set
320 * Revision 1.44 1998/12/03 15:14:35 mhaveman
321 * Another change to Vpd instance evaluation.
323 * Revision 1.43 1998/12/03 14:18:10 mhaveman
324 * -Fixed problem in PnmiSetStruct. It was impossible to set any value.
325 * -Removed VPD key evaluation for VPD_FREE_BYTES and VPD_ACTION.
327 * Revision 1.42 1998/12/03 11:31:47 mhaveman
328 * Inserted cast to satisfy lint.
330 * Revision 1.41 1998/12/03 11:28:16 mhaveman
331 * Removed SK_PNMI_CHECKPTR
333 * Revision 1.40 1998/12/03 11:19:07 mhaveman
334 * Fixed problems
335 * -A set to virtual port will now be ignored. A set with broadcast
336 * address to any port will be ignored.
337 * -GetStruct function made VPD instance calculation wrong.
338 * -Prefered port returned -1 instead of 0.
340 * Revision 1.39 1998/11/26 15:30:29 mhaveman
341 * Added sense mode to link mode.
343 * Revision 1.38 1998/11/23 15:34:00 mhaveman
344 * -Fixed bug for RX counters. On an RX overflow interrupt the high
345 * words of all RX counters were incremented.
346 * -SET operations on FLOWCTRL_MODE and LINK_MODE accept now the
347 * value 0, which has no effect. It is usefull for multiple instance
348 * SETs.
350 * Revision 1.37 1998/11/20 08:02:04 mhaveman
351 * -Fixed: Ports were compared with MAX_SENSORS
352 * -Fixed: Crash in GetTrapEntry with MEMSET macro
353 * -Fixed: Conversions between physical, logical port index and instance
355 * Revision 1.36 1998/11/16 07:48:53 mhaveman
356 * Casted SK_DRIVER_SENDEVENT with (void) to eleminate compiler warnings
357 * on Solaris.
359 * Revision 1.35 1998/11/16 07:45:34 mhaveman
360 * SkAddrOverride now returns value and will be checked.
362 * Revision 1.34 1998/11/10 13:40:37 mhaveman
363 * Needed to change interface, because NT driver needs a return value
364 * of needed buffer space on TOO_SHORT errors. Therefore all
365 * SkPnmiGet/Preset/Set functions now have a pointer to the length
366 * parameter, where the needed space on error is returned.
368 * Revision 1.33 1998/11/03 13:52:46 mhaveman
369 * Made file lint conform.
371 * Revision 1.32 1998/11/03 13:19:07 mhaveman
372 * The events SK_HWEV_SET_LMODE and SK_HWEV_SET_FLOWMODE pass now in
373 * Para32[0] the physical MAC index and in Para32[1] the new mode.
375 * Revision 1.31 1998/11/03 12:30:40 gklug
376 * fix: compiler warning memset
378 * Revision 1.30 1998/11/03 12:04:46 mhaveman
379 * Fixed problem in SENSOR_VALUE, which wrote beyond the buffer end
380 * Fixed alignment problem with CHIPSET.
382 * Revision 1.29 1998/11/02 11:23:54 mhaveman
383 * Corrected SK_ERROR_LOG to SK_ERR_LOG. Sorry.
385 * Revision 1.28 1998/11/02 10:47:16 mhaveman
386 * Added syslog messages for internal errors.
388 * Revision 1.27 1998/10/30 15:48:06 mhaveman
389 * Fixed problems after simulation of SK_PNMI_EVT_CHG_EST_TIMER and
390 * RlmtChangeThreshold calculation.
392 * Revision 1.26 1998/10/29 15:36:55 mhaveman
393 * -Fixed bug in trap buffer handling.
394 * -OID_SKGE_DRIVER_DESCR, OID_SKGE_DRIVER_VERSION, OID_SKGE_HW_DESCR,
395 * OID_SKGE_HW_VERSION, OID_SKGE_VPD_ENTRIES_LIST, OID_SKGE_VPD_KEY,
396 * OID_SKGE_VPD_VALUE, and OID_SKGE_SENSOR_DESCR return values with
397 * a leading octet before each string storing the string length.
398 * -Perform a RlmtUpdate during SK_PNMI_EVT_XMAC_RESET to minimize
399 * RlmtUpdate calls in GetStatVal.
400 * -Inserted SK_PNMI_CHECKFLAGS macro increase readability.
402 * Revision 1.25 1998/10/29 08:50:36 mhaveman
403 * Fixed problems after second event simulation.
405 * Revision 1.24 1998/10/28 08:44:37 mhaveman
406 * -Fixed alignment problem
407 * -Fixed problems during event simulation
408 * -Fixed sequence of error return code (INSTANCE -> ACCESS -> SHORT)
409 * -Changed type of parameter Instance back to SK_U32 because of VPD
410 * -Updated new VPD function calls
412 * Revision 1.23 1998/10/23 10:16:37 mhaveman
413 * Fixed bugs after buffer test simulation.
415 * Revision 1.22 1998/10/21 13:23:52 mhaveman
416 * -Call syntax of SkOsGetTime() changed to SkOsGetTime(pAc).
417 * -Changed calculation of hundrets of seconds.
419 * Revision 1.20 1998/10/20 07:30:45 mhaveman
420 * Made type changes to unsigned integer where possible.
422 * Revision 1.19 1998/10/19 10:51:30 mhaveman
423 * -Made Bug fixes after simulation run
424 * -Renamed RlmtMAC... to RlmtPort...
425 * -Marked workarounds with Errata comments
427 * Revision 1.18 1998/10/14 07:50:08 mhaveman
428 * -For OID_SKGE_LINK_STATUS the link down detection has moved from RLMT
429 * to HWACCESS.
430 * -Provided all MEMCPY/MEMSET macros with (char *) pointers, because
431 * Solaris throwed warnings when mapping to bcopy/bset.
433 * Revision 1.17 1998/10/13 07:42:01 mhaveman
434 * -Added OIDs OID_SKGE_TRAP_NUMBER and OID_SKGE_ALL_DATA
435 * -Removed old cvs history entries
436 * -Renamed MacNumber to PortNumber
438 * Revision 1.16 1998/10/07 10:52:49 mhaveman
439 * -Inserted handling of some OID_GEN_ Ids for windows
440 * -Fixed problem with 803.2 statistic.
442 * Revision 1.15 1998/10/01 09:16:29 mhaveman
443 * Added Debug messages for function call and UpdateFlag tracing.
445 * Revision 1.14 1998/09/30 13:39:09 mhaveman
446 * -Reduced namings of 'MAC' by replacing them with 'PORT'.
447 * -Completed counting of OID_SKGE_RX_HW_ERROR_CTS,
448 * OID_SKGE_TX_HW_ERROR_CTS,
449 * OID_SKGE_IN_ERRORS_CTS, and OID_SKGE_OUT_ERROR_CTS.
450 * -SET check for RlmtMode
452 * Revision 1.13 1998/09/28 13:13:08 mhaveman
453 * Hide strcmp, strlen, and strncpy behind macros SK_STRCMP, SK_STRLEN,
454 * and SK_STRNCPY. (Same reasons as for mem.. and MEM..)
456 * Revision 1.12 1998/09/16 08:18:36 cgoos
457 * Fix: XM_INxx and XM_OUTxx called with different parameter order:
458 * sometimes IoC,Mac,... sometimes Mac,IoC,... Now always first variant.
459 * Fix: inserted "Pnmi." into some pAC->pDriverDescription / Version.
460 * Change: memset, memcpy to makros SK_MEMSET, SK_MEMCPY
462 * Revision 1.11 1998/09/04 17:01:45 mhaveman
463 * Added SyncCounter as macro and OID_SKGE_.._NO_DESCR_CTS to
464 * OID_SKGE_RX_NO_BUF_CTS.
466 * Revision 1.10 1998/09/04 14:35:35 mhaveman
467 * Added macro counters, that are counted by driver.
469 ****************************************************************************/
472 #ifndef _lint
473 static const char SysKonnectFileId[] =
474 "@(#) $Id: skgepnmi.c,v 1.109 2003/07/17 14:15:24 tschilli Exp $ (C) Marvell.";
475 #endif /* !_lint */
477 #include "h/skdrv1st.h"
478 #include "h/sktypes.h"
479 #include "h/xmac_ii.h"
480 #include "h/skdebug.h"
481 #include "h/skqueue.h"
482 #include "h/skgepnmi.h"
483 #include "h/skgesirq.h"
484 #include "h/skcsum.h"
485 #include "h/skvpd.h"
486 #include "h/skgehw.h"
487 #include "h/skgeinit.h"
488 #include "h/skdrv2nd.h"
489 #include "h/skgepnm2.h"
490 #ifdef SK_POWER_MGMT
491 #include "h/skgepmgt.h"
492 #endif
493 /* defines *******************************************************************/
495 #ifndef DEBUG
496 #define PNMI_STATIC static
497 #else /* DEBUG */
498 #define PNMI_STATIC
499 #endif /* DEBUG */
502 * Public Function prototypes
504 int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level);
505 int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
506 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
507 int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
508 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
509 int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
510 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
511 int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
512 unsigned int *pLen, SK_U32 NetIndex);
513 int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
514 unsigned int *pLen, SK_U32 NetIndex);
515 int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
516 unsigned int *pLen, SK_U32 NetIndex);
517 int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
518 int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf,
519 unsigned int * pLen, SK_U32 NetIndex);
523 * Private Function prototypes
526 PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
527 PhysPortIndex);
528 PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
529 PhysPortIndex);
530 PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac);
531 PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
532 PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
533 unsigned int PhysPortIndex, unsigned int StatIndex);
534 PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
535 unsigned int StatIndex, SK_U32 NetIndex);
536 PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
537 PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
538 unsigned int *pEntries);
539 PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr,
540 unsigned int KeyArrLen, unsigned int *pKeyNo);
541 PNMI_STATIC int LookupId(SK_U32 Id);
542 PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
543 unsigned int LastMac);
544 PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
545 unsigned int *pLen, SK_U32 NetIndex);
546 PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id,
547 char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
548 PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
549 PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
550 unsigned int PortIndex);
551 PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
552 unsigned int SensorIndex);
553 PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
554 PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
555 PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
556 PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
557 PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
558 PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
559 unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
560 PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
563 * Table to correlate OID with handler function and index to
564 * hardware register stored in StatAddress if applicable.
566 #include "skgemib.c"
568 /* global variables **********************************************************/
571 * Overflow status register bit table and corresponding counter
572 * dependent on MAC type - the number relates to the size of overflow
573 * mask returned by the pFnMacOverflow function
575 PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = {
576 /* Bit0 */ { SK_PNMI_HTX, SK_PNMI_HTX_UNICAST},
577 /* Bit1 */ { SK_PNMI_HTX_OCTETHIGH, SK_PNMI_HTX_BROADCAST},
578 /* Bit2 */ { SK_PNMI_HTX_OCTETLOW, SK_PNMI_HTX_PMACC},
579 /* Bit3 */ { SK_PNMI_HTX_BROADCAST, SK_PNMI_HTX_MULTICAST},
580 /* Bit4 */ { SK_PNMI_HTX_MULTICAST, SK_PNMI_HTX_OCTETLOW},
581 /* Bit5 */ { SK_PNMI_HTX_UNICAST, SK_PNMI_HTX_OCTETHIGH},
582 /* Bit6 */ { SK_PNMI_HTX_LONGFRAMES, SK_PNMI_HTX_64},
583 /* Bit7 */ { SK_PNMI_HTX_BURST, SK_PNMI_HTX_127},
584 /* Bit8 */ { SK_PNMI_HTX_PMACC, SK_PNMI_HTX_255},
585 /* Bit9 */ { SK_PNMI_HTX_MACC, SK_PNMI_HTX_511},
586 /* Bit10 */ { SK_PNMI_HTX_SINGLE_COL, SK_PNMI_HTX_1023},
587 /* Bit11 */ { SK_PNMI_HTX_MULTI_COL, SK_PNMI_HTX_MAX},
588 /* Bit12 */ { SK_PNMI_HTX_EXCESS_COL, SK_PNMI_HTX_LONGFRAMES},
589 /* Bit13 */ { SK_PNMI_HTX_LATE_COL, SK_PNMI_HTX_RESERVED},
590 /* Bit14 */ { SK_PNMI_HTX_DEFFERAL, SK_PNMI_HTX_COL},
591 /* Bit15 */ { SK_PNMI_HTX_EXCESS_DEF, SK_PNMI_HTX_LATE_COL},
592 /* Bit16 */ { SK_PNMI_HTX_UNDERRUN, SK_PNMI_HTX_EXCESS_COL},
593 /* Bit17 */ { SK_PNMI_HTX_CARRIER, SK_PNMI_HTX_MULTI_COL},
594 /* Bit18 */ { SK_PNMI_HTX_UTILUNDER, SK_PNMI_HTX_SINGLE_COL},
595 /* Bit19 */ { SK_PNMI_HTX_UTILOVER, SK_PNMI_HTX_UNDERRUN},
596 /* Bit20 */ { SK_PNMI_HTX_64, SK_PNMI_HTX_RESERVED},
597 /* Bit21 */ { SK_PNMI_HTX_127, SK_PNMI_HTX_RESERVED},
598 /* Bit22 */ { SK_PNMI_HTX_255, SK_PNMI_HTX_RESERVED},
599 /* Bit23 */ { SK_PNMI_HTX_511, SK_PNMI_HTX_RESERVED},
600 /* Bit24 */ { SK_PNMI_HTX_1023, SK_PNMI_HTX_RESERVED},
601 /* Bit25 */ { SK_PNMI_HTX_MAX, SK_PNMI_HTX_RESERVED},
602 /* Bit26 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
603 /* Bit27 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
604 /* Bit28 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
605 /* Bit29 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
606 /* Bit30 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
607 /* Bit31 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
608 /* Bit32 */ { SK_PNMI_HRX, SK_PNMI_HRX_UNICAST},
609 /* Bit33 */ { SK_PNMI_HRX_OCTETHIGH, SK_PNMI_HRX_BROADCAST},
610 /* Bit34 */ { SK_PNMI_HRX_OCTETLOW, SK_PNMI_HRX_PMACC},
611 /* Bit35 */ { SK_PNMI_HRX_BROADCAST, SK_PNMI_HRX_MULTICAST},
612 /* Bit36 */ { SK_PNMI_HRX_MULTICAST, SK_PNMI_HRX_FCS},
613 /* Bit37 */ { SK_PNMI_HRX_UNICAST, SK_PNMI_HRX_RESERVED},
614 /* Bit38 */ { SK_PNMI_HRX_PMACC, SK_PNMI_HRX_OCTETLOW},
615 /* Bit39 */ { SK_PNMI_HRX_MACC, SK_PNMI_HRX_OCTETHIGH},
616 /* Bit40 */ { SK_PNMI_HRX_PMACC_ERR, SK_PNMI_HRX_BADOCTETLOW},
617 /* Bit41 */ { SK_PNMI_HRX_MACC_UNKWN, SK_PNMI_HRX_BADOCTETHIGH},
618 /* Bit42 */ { SK_PNMI_HRX_BURST, SK_PNMI_HRX_UNDERSIZE},
619 /* Bit43 */ { SK_PNMI_HRX_MISSED, SK_PNMI_HRX_RUNT},
620 /* Bit44 */ { SK_PNMI_HRX_FRAMING, SK_PNMI_HRX_64},
621 /* Bit45 */ { SK_PNMI_HRX_OVERFLOW, SK_PNMI_HRX_127},
622 /* Bit46 */ { SK_PNMI_HRX_JABBER, SK_PNMI_HRX_255},
623 /* Bit47 */ { SK_PNMI_HRX_CARRIER, SK_PNMI_HRX_511},
624 /* Bit48 */ { SK_PNMI_HRX_IRLENGTH, SK_PNMI_HRX_1023},
625 /* Bit49 */ { SK_PNMI_HRX_SYMBOL, SK_PNMI_HRX_MAX},
626 /* Bit50 */ { SK_PNMI_HRX_SHORTS, SK_PNMI_HRX_LONGFRAMES},
627 /* Bit51 */ { SK_PNMI_HRX_RUNT, SK_PNMI_HRX_TOO_LONG},
628 /* Bit52 */ { SK_PNMI_HRX_TOO_LONG, SK_PNMI_HRX_JABBER},
629 /* Bit53 */ { SK_PNMI_HRX_FCS, SK_PNMI_HRX_RESERVED},
630 /* Bit54 */ { SK_PNMI_HRX_RESERVED, SK_PNMI_HRX_OVERFLOW},
631 /* Bit55 */ { SK_PNMI_HRX_CEXT, SK_PNMI_HRX_RESERVED},
632 /* Bit56 */ { SK_PNMI_HRX_UTILUNDER, SK_PNMI_HRX_RESERVED},
633 /* Bit57 */ { SK_PNMI_HRX_UTILOVER, SK_PNMI_HRX_RESERVED},
634 /* Bit58 */ { SK_PNMI_HRX_64, SK_PNMI_HRX_RESERVED},
635 /* Bit59 */ { SK_PNMI_HRX_127, SK_PNMI_HRX_RESERVED},
636 /* Bit60 */ { SK_PNMI_HRX_255, SK_PNMI_HRX_RESERVED},
637 /* Bit61 */ { SK_PNMI_HRX_511, SK_PNMI_HRX_RESERVED},
638 /* Bit62 */ { SK_PNMI_HRX_1023, SK_PNMI_HRX_RESERVED},
639 /* Bit63 */ { SK_PNMI_HRX_MAX, SK_PNMI_HRX_RESERVED}
643 * Table for hardware register saving on resets and port switches
645 PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = {
646 /* SK_PNMI_HTX */
647 {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}},
648 /* SK_PNMI_HTX_OCTETHIGH */
649 {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}},
650 /* SK_PNMI_HTX_OCTETLOW */
651 {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}},
652 /* SK_PNMI_HTX_BROADCAST */
653 {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}},
654 /* SK_PNMI_HTX_MULTICAST */
655 {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}},
656 /* SK_PNMI_HTX_UNICAST */
657 {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}},
658 /* SK_PNMI_HTX_BURST */
659 {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}},
660 /* SK_PNMI_HTX_PMACC */
661 {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}},
662 /* SK_PNMI_HTX_MACC */
663 {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
664 /* SK_PNMI_HTX_COL */
665 {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}},
666 /* SK_PNMI_HTX_SINGLE_COL */
667 {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}},
668 /* SK_PNMI_HTX_MULTI_COL */
669 {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}},
670 /* SK_PNMI_HTX_EXCESS_COL */
671 {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}},
672 /* SK_PNMI_HTX_LATE_COL */
673 {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}},
674 /* SK_PNMI_HTX_DEFFERAL */
675 {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}},
676 /* SK_PNMI_HTX_EXCESS_DEF */
677 {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}},
678 /* SK_PNMI_HTX_UNDERRUN */
679 {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}},
680 /* SK_PNMI_HTX_CARRIER */
681 {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}},
682 /* SK_PNMI_HTX_UTILUNDER */
683 {{0, SK_FALSE}, {0, SK_FALSE}},
684 /* SK_PNMI_HTX_UTILOVER */
685 {{0, SK_FALSE}, {0, SK_FALSE}},
686 /* SK_PNMI_HTX_64 */
687 {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}},
688 /* SK_PNMI_HTX_127 */
689 {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}},
690 /* SK_PNMI_HTX_255 */
691 {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}},
692 /* SK_PNMI_HTX_511 */
693 {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}},
694 /* SK_PNMI_HTX_1023 */
695 {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}},
696 /* SK_PNMI_HTX_MAX */
697 {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}},
698 /* SK_PNMI_HTX_LONGFRAMES */
699 {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}},
700 /* SK_PNMI_HTX_SYNC */
701 {{0, SK_FALSE}, {0, SK_FALSE}},
702 /* SK_PNMI_HTX_SYNC_OCTET */
703 {{0, SK_FALSE}, {0, SK_FALSE}},
704 /* SK_PNMI_HTX_RESERVED */
705 {{0, SK_FALSE}, {0, SK_FALSE}},
706 /* SK_PNMI_HRX */
707 {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}},
708 /* SK_PNMI_HRX_OCTETHIGH */
709 {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}},
710 /* SK_PNMI_HRX_OCTETLOW */
711 {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}},
712 /* SK_PNMI_HRX_BADOCTETHIGH */
713 {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}},
714 /* SK_PNMI_HRX_BADOCTETLOW */
715 {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}},
716 /* SK_PNMI_HRX_BROADCAST */
717 {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}},
718 /* SK_PNMI_HRX_MULTICAST */
719 {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}},
720 /* SK_PNMI_HRX_UNICAST */
721 {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}},
722 /* SK_PNMI_HRX_PMACC */
723 {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}},
724 /* SK_PNMI_HRX_MACC */
725 {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
726 /* SK_PNMI_HRX_PMACC_ERR */
727 {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}},
728 /* SK_PNMI_HRX_MACC_UNKWN */
729 {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}},
730 /* SK_PNMI_HRX_BURST */
731 {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}},
732 /* SK_PNMI_HRX_MISSED */
733 {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}},
734 /* SK_PNMI_HRX_FRAMING */
735 {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}},
736 /* SK_PNMI_HRX_UNDERSIZE */
737 {{0, SK_FALSE}, {GM_RXF_SHT, SK_TRUE}},
738 /* SK_PNMI_HRX_OVERFLOW */
739 {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}},
740 /* SK_PNMI_HRX_JABBER */
741 {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}},
742 /* SK_PNMI_HRX_CARRIER */
743 {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}},
744 /* SK_PNMI_HRX_IRLENGTH */
745 {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}},
746 /* SK_PNMI_HRX_SYMBOL */
747 {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}},
748 /* SK_PNMI_HRX_SHORTS */
749 {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}},
750 /* SK_PNMI_HRX_RUNT */
751 {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}},
752 /* SK_PNMI_HRX_TOO_LONG */
753 {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}},
754 /* SK_PNMI_HRX_FCS */
755 {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}},
756 /* SK_PNMI_HRX_CEXT */
757 {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}},
758 /* SK_PNMI_HRX_UTILUNDER */
759 {{0, SK_FALSE}, {0, SK_FALSE}},
760 /* SK_PNMI_HRX_UTILOVER */
761 {{0, SK_FALSE}, {0, SK_FALSE}},
762 /* SK_PNMI_HRX_64 */
763 {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}},
764 /* SK_PNMI_HRX_127 */
765 {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}},
766 /* SK_PNMI_HRX_255 */
767 {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}},
768 /* SK_PNMI_HRX_511 */
769 {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}},
770 /* SK_PNMI_HRX_1023 */
771 {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}},
772 /* SK_PNMI_HRX_MAX */
773 {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}},
774 /* SK_PNMI_HRX_LONGFRAMES */
775 {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}},
776 /* SK_PNMI_HRX_RESERVED */
777 {{0, SK_FALSE}, {0, SK_FALSE}}
781 /*****************************************************************************
783 * Public functions
787 /*****************************************************************************
789 * SkPnmiInit - Init function of PNMI
791 * Description:
792 * SK_INIT_DATA: Initialises the data structures
793 * SK_INIT_IO: Resets the XMAC statistics, determines the device and
794 * connector type.
795 * SK_INIT_RUN: Starts a timer event for port switch per hour
796 * calculation.
798 * Returns:
799 * Always 0
801 int SkPnmiInit(
802 SK_AC *pAC, /* Pointer to adapter context */
803 SK_IOC IoC, /* IO context handle */
804 int Level) /* Initialization level */
806 unsigned int PortMax; /* Number of ports */
807 unsigned int PortIndex; /* Current port index in loop */
808 SK_U16 Val16; /* Multiple purpose 16 bit variable */
809 SK_U8 Val8; /* Mulitple purpose 8 bit variable */
810 SK_EVPARA EventParam; /* Event struct for timer event */
811 SK_PNMI_VCT *pVctBackupData;
814 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
815 ("PNMI: SkPnmiInit: Called, level=%d\n", Level));
817 switch (Level) {
819 case SK_INIT_DATA:
820 SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
821 pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
822 pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
823 pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
824 for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
826 pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
827 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
830 #ifdef SK_PNMI_CHECK
831 if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) {
833 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG);
835 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
836 ("CounterOffset struct size (%d) differs from"
837 "SK_PNMI_MAX_IDX (%d)\n",
838 SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
841 if (SK_PNMI_MAX_IDX !=
842 (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) {
844 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG);
846 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
847 ("StatAddr table size (%d) differs from "
848 "SK_PNMI_MAX_IDX (%d)\n",
849 (sizeof(StatAddr) /
850 (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)),
851 SK_PNMI_MAX_IDX));
853 #endif /* SK_PNMI_CHECK */
854 break;
856 case SK_INIT_IO:
858 * Reset MAC counters
860 PortMax = pAC->GIni.GIMacsFound;
862 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
864 pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
867 /* Initialize DSP variables for Vct() to 0xff => Never written! */
868 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
869 pAC->GIni.GP[PortIndex].PCableLen = 0xff;
870 pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
871 pVctBackupData->PCableLen = 0xff;
875 * Get pci bus speed
877 SK_IN16(IoC, B0_CTST, &Val16);
878 if ((Val16 & CS_BUS_CLOCK) == 0) {
880 pAC->Pnmi.PciBusSpeed = 33;
882 else {
883 pAC->Pnmi.PciBusSpeed = 66;
887 * Get pci bus width
889 SK_IN16(IoC, B0_CTST, &Val16);
890 if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
892 pAC->Pnmi.PciBusWidth = 32;
894 else {
895 pAC->Pnmi.PciBusWidth = 64;
899 * Get chipset
901 switch (pAC->GIni.GIChipId) {
902 case CHIP_ID_GENESIS:
903 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
904 break;
906 case CHIP_ID_YUKON:
907 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
908 break;
910 default:
911 break;
915 * Get PMD and DeviceType
917 SK_IN8(IoC, B2_PMD_TYP, &Val8);
918 switch (Val8) {
919 case 'S':
920 pAC->Pnmi.PMD = 3;
921 if (pAC->GIni.GIMacsFound > 1) {
923 pAC->Pnmi.DeviceType = 0x00020002;
925 else {
926 pAC->Pnmi.DeviceType = 0x00020001;
928 break;
930 case 'L':
931 pAC->Pnmi.PMD = 2;
932 if (pAC->GIni.GIMacsFound > 1) {
934 pAC->Pnmi.DeviceType = 0x00020004;
936 else {
937 pAC->Pnmi.DeviceType = 0x00020003;
939 break;
941 case 'C':
942 pAC->Pnmi.PMD = 4;
943 if (pAC->GIni.GIMacsFound > 1) {
945 pAC->Pnmi.DeviceType = 0x00020006;
947 else {
948 pAC->Pnmi.DeviceType = 0x00020005;
950 break;
952 case 'T':
953 pAC->Pnmi.PMD = 5;
954 if (pAC->GIni.GIMacsFound > 1) {
956 pAC->Pnmi.DeviceType = 0x00020008;
958 else {
959 pAC->Pnmi.DeviceType = 0x00020007;
961 break;
963 default :
964 pAC->Pnmi.PMD = 1;
965 pAC->Pnmi.DeviceType = 0;
966 break;
970 * Get connector
972 SK_IN8(IoC, B2_CONN_TYP, &Val8);
973 switch (Val8) {
974 case 'C':
975 pAC->Pnmi.Connector = 2;
976 break;
978 case 'D':
979 pAC->Pnmi.Connector = 3;
980 break;
982 case 'F':
983 pAC->Pnmi.Connector = 4;
984 break;
986 case 'J':
987 pAC->Pnmi.Connector = 5;
988 break;
990 case 'V':
991 pAC->Pnmi.Connector = 6;
992 break;
994 default:
995 pAC->Pnmi.Connector = 1;
996 break;
998 break;
1000 case SK_INIT_RUN:
1002 * Start timer for RLMT change counter
1004 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
1005 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
1006 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
1007 EventParam);
1008 break;
1010 default:
1011 break; /* Nothing todo */
1014 return (0);
1017 /*****************************************************************************
1019 * SkPnmiGetVar - Retrieves the value of a single OID
1021 * Description:
1022 * Calls a general sub-function for all this stuff. If the instance
1023 * -1 is passed, the values of all instances are returned in an
1024 * array of values.
1026 * Returns:
1027 * SK_PNMI_ERR_OK The request was successfully performed
1028 * SK_PNMI_ERR_GENERAL A general severe internal error occured
1029 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
1030 * the data.
1031 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
1032 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1033 * exist (e.g. port instance 3 on a two port
1034 * adapter.
1036 int SkPnmiGetVar(
1037 SK_AC *pAC, /* Pointer to adapter context */
1038 SK_IOC IoC, /* IO context handle */
1039 SK_U32 Id, /* Object ID that is to be processed */
1040 void *pBuf, /* Buffer to which the management data will be copied */
1041 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
1042 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
1043 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1045 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1046 ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
1047 Id, *pLen, Instance, NetIndex));
1049 return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
1050 Instance, NetIndex));
1053 /*****************************************************************************
1055 * SkPnmiPreSetVar - Presets the value of a single OID
1057 * Description:
1058 * Calls a general sub-function for all this stuff. The preset does
1059 * the same as a set, but returns just before finally setting the
1060 * new value. This is usefull to check if a set might be successfull.
1061 * If the instance -1 is passed, an array of values is supposed and
1062 * all instances of the OID will be set.
1064 * Returns:
1065 * SK_PNMI_ERR_OK The request was successfully performed.
1066 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1067 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1068 * the correct data (e.g. a 32bit value is
1069 * needed, but a 16 bit value was passed).
1070 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1071 * value range.
1072 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
1073 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
1074 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1075 * exist (e.g. port instance 3 on a two port
1076 * adapter.
1078 int SkPnmiPreSetVar(
1079 SK_AC *pAC, /* Pointer to adapter context */
1080 SK_IOC IoC, /* IO context handle */
1081 SK_U32 Id, /* Object ID that is to be processed */
1082 void *pBuf, /* Buffer to which the management data will be copied */
1083 unsigned int *pLen, /* Total length of management data */
1084 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
1085 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1087 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1088 ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
1089 Id, *pLen, Instance, NetIndex));
1092 return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
1093 Instance, NetIndex));
1096 /*****************************************************************************
1098 * SkPnmiSetVar - Sets the value of a single OID
1100 * Description:
1101 * Calls a general sub-function for all this stuff. The preset does
1102 * the same as a set, but returns just before finally setting the
1103 * new value. This is usefull to check if a set might be successfull.
1104 * If the instance -1 is passed, an array of values is supposed and
1105 * all instances of the OID will be set.
1107 * Returns:
1108 * SK_PNMI_ERR_OK The request was successfully performed.
1109 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1110 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1111 * the correct data (e.g. a 32bit value is
1112 * needed, but a 16 bit value was passed).
1113 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1114 * value range.
1115 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
1116 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
1117 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1118 * exist (e.g. port instance 3 on a two port
1119 * adapter.
1121 int SkPnmiSetVar(
1122 SK_AC *pAC, /* Pointer to adapter context */
1123 SK_IOC IoC, /* IO context handle */
1124 SK_U32 Id, /* Object ID that is to be processed */
1125 void *pBuf, /* Buffer to which the management data will be copied */
1126 unsigned int *pLen, /* Total length of management data */
1127 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
1128 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1130 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1131 ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
1132 Id, *pLen, Instance, NetIndex));
1134 return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
1135 Instance, NetIndex));
1138 /*****************************************************************************
1140 * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA
1142 * Description:
1143 * Runs through the IdTable, queries the single OIDs and stores the
1144 * returned data into the management database structure
1145 * SK_PNMI_STRUCT_DATA. The offset of the OID in the structure
1146 * is stored in the IdTable. The return value of the function will also
1147 * be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
1148 * minimum size of SK_PNMI_MIN_STRUCT_SIZE.
1150 * Returns:
1151 * SK_PNMI_ERR_OK The request was successfully performed
1152 * SK_PNMI_ERR_GENERAL A general severe internal error occured
1153 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
1154 * the data.
1155 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
1157 int SkPnmiGetStruct(
1158 SK_AC *pAC, /* Pointer to adapter context */
1159 SK_IOC IoC, /* IO context handle */
1160 void *pBuf, /* Buffer to which the management data will be copied. */
1161 unsigned int *pLen, /* Length of buffer */
1162 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1164 int Ret;
1165 unsigned int TableIndex;
1166 unsigned int DstOffset;
1167 unsigned int InstanceNo;
1168 unsigned int InstanceCnt;
1169 SK_U32 Instance;
1170 unsigned int TmpLen;
1171 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
1174 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1175 ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
1176 *pLen, NetIndex));
1178 if (*pLen < SK_PNMI_STRUCT_SIZE) {
1180 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
1182 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
1183 (SK_U32)(-1));
1186 *pLen = SK_PNMI_STRUCT_SIZE;
1187 return (SK_PNMI_ERR_TOO_SHORT);
1191 * Check NetIndex
1193 if (NetIndex >= pAC->Rlmt.NumNets) {
1194 return (SK_PNMI_ERR_UNKNOWN_NET);
1197 /* Update statistic */
1198 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
1200 if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
1201 SK_PNMI_ERR_OK) {
1203 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1204 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1205 return (Ret);
1208 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
1210 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1211 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1212 return (Ret);
1215 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
1217 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1218 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1219 return (Ret);
1223 * Increment semaphores to indicate that an update was
1224 * already done
1226 pAC->Pnmi.MacUpdatedFlag ++;
1227 pAC->Pnmi.RlmtUpdatedFlag ++;
1228 pAC->Pnmi.SirqUpdatedFlag ++;
1230 /* Get vpd keys for instance calculation */
1231 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
1232 if (Ret != SK_PNMI_ERR_OK) {
1234 pAC->Pnmi.MacUpdatedFlag --;
1235 pAC->Pnmi.RlmtUpdatedFlag --;
1236 pAC->Pnmi.SirqUpdatedFlag --;
1238 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
1239 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1240 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1241 return (SK_PNMI_ERR_GENERAL);
1244 /* Retrieve values */
1245 SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
1246 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
1248 InstanceNo = IdTable[TableIndex].InstanceNo;
1249 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
1250 InstanceCnt ++) {
1252 DstOffset = IdTable[TableIndex].Offset +
1253 (InstanceCnt - 1) *
1254 IdTable[TableIndex].StructSize;
1257 * For the VPD the instance is not an index number
1258 * but the key itself. Determin with the instance
1259 * counter the VPD key to be used.
1261 if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
1262 IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
1263 IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
1264 IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
1266 SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
1268 else {
1269 Instance = (SK_U32)InstanceCnt;
1272 TmpLen = *pLen - DstOffset;
1273 Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
1274 IdTable[TableIndex].Id, (char *)pBuf +
1275 DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
1278 * An unknown instance error means that we reached
1279 * the last instance of that variable. Proceed with
1280 * the next OID in the table and ignore the return
1281 * code.
1283 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
1285 break;
1288 if (Ret != SK_PNMI_ERR_OK) {
1290 pAC->Pnmi.MacUpdatedFlag --;
1291 pAC->Pnmi.RlmtUpdatedFlag --;
1292 pAC->Pnmi.SirqUpdatedFlag --;
1294 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
1295 SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
1296 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1297 return (Ret);
1302 pAC->Pnmi.MacUpdatedFlag --;
1303 pAC->Pnmi.RlmtUpdatedFlag --;
1304 pAC->Pnmi.SirqUpdatedFlag --;
1306 *pLen = SK_PNMI_STRUCT_SIZE;
1307 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
1308 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
1309 return (SK_PNMI_ERR_OK);
1312 /*****************************************************************************
1314 * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
1316 * Description:
1317 * Calls a general sub-function for all this set stuff. The preset does
1318 * the same as a set, but returns just before finally setting the
1319 * new value. This is usefull to check if a set might be successfull.
1320 * The sub-function runs through the IdTable, checks which OIDs are able
1321 * to set, and calls the handler function of the OID to perform the
1322 * preset. The return value of the function will also be stored in
1323 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
1324 * SK_PNMI_MIN_STRUCT_SIZE.
1326 * Returns:
1327 * SK_PNMI_ERR_OK The request was successfully performed.
1328 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1329 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1330 * the correct data (e.g. a 32bit value is
1331 * needed, but a 16 bit value was passed).
1332 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1333 * value range.
1335 int SkPnmiPreSetStruct(
1336 SK_AC *pAC, /* Pointer to adapter context */
1337 SK_IOC IoC, /* IO context handle */
1338 void *pBuf, /* Buffer which contains the data to be set */
1339 unsigned int *pLen, /* Length of buffer */
1340 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1342 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1343 ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
1344 *pLen, NetIndex));
1346 return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf,
1347 pLen, NetIndex));
1350 /*****************************************************************************
1352 * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA
1354 * Description:
1355 * Calls a general sub-function for all this set stuff. The return value
1356 * of the function will also be stored in SK_PNMI_STRUCT_DATA if the
1357 * passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE.
1358 * The sub-function runs through the IdTable, checks which OIDs are able
1359 * to set, and calls the handler function of the OID to perform the
1360 * set. The return value of the function will also be stored in
1361 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
1362 * SK_PNMI_MIN_STRUCT_SIZE.
1364 * Returns:
1365 * SK_PNMI_ERR_OK The request was successfully performed.
1366 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1367 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1368 * the correct data (e.g. a 32bit value is
1369 * needed, but a 16 bit value was passed).
1370 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1371 * value range.
1373 int SkPnmiSetStruct(
1374 SK_AC *pAC, /* Pointer to adapter context */
1375 SK_IOC IoC, /* IO context handle */
1376 void *pBuf, /* Buffer which contains the data to be set */
1377 unsigned int *pLen, /* Length of buffer */
1378 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1380 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1381 ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
1382 *pLen, NetIndex));
1384 return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf,
1385 pLen, NetIndex));
1388 /*****************************************************************************
1390 * SkPnmiEvent - Event handler
1392 * Description:
1393 * Handles the following events:
1394 * SK_PNMI_EVT_SIRQ_OVERFLOW When a hardware counter overflows an
1395 * interrupt will be generated which is
1396 * first handled by SIRQ which generates a
1397 * this event. The event increments the
1398 * upper 32 bit of the 64 bit counter.
1399 * SK_PNMI_EVT_SEN_XXX The event is generated by the I2C module
1400 * when a sensor reports a warning or
1401 * error. The event will store a trap
1402 * message in the trap buffer.
1403 * SK_PNMI_EVT_CHG_EST_TIMER The timer event was initiated by this
1404 * module and is used to calculate the
1405 * port switches per hour.
1406 * SK_PNMI_EVT_CLEAR_COUNTER The event clears all counters and
1407 * timestamps.
1408 * SK_PNMI_EVT_XMAC_RESET The event is generated by the driver
1409 * before a hard reset of the XMAC is
1410 * performed. All counters will be saved
1411 * and added to the hardware counter
1412 * values after reset to grant continuous
1413 * counter values.
1414 * SK_PNMI_EVT_RLMT_PORT_UP Generated by RLMT to notify that a port
1415 * went logically up. A trap message will
1416 * be stored to the trap buffer.
1417 * SK_PNMI_EVT_RLMT_PORT_DOWN Generated by RLMT to notify that a port
1418 * went logically down. A trap message will
1419 * be stored to the trap buffer.
1420 * SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
1421 * spanning tree root bridges were
1422 * detected. A trap message will be stored
1423 * to the trap buffer.
1424 * SK_PNMI_EVT_RLMT_ACTIVE_DOWN Notifies PNMI that an active port went
1425 * down. PNMI will not further add the
1426 * statistic values to the virtual port.
1427 * SK_PNMI_EVT_RLMT_ACTIVE_UP Notifies PNMI that a port went up and
1428 * is now an active port. PNMI will now
1429 * add the statistic data of this port to
1430 * the virtual port.
1431 * SK_PNMI_EVT_RLMT_SET_NETS Notifies PNMI about the net mode. The first parameter
1432 * contains the number of nets. 1 means single net, 2 means
1433 * dual net. The second parameter is -1
1435 * Returns:
1436 * Always 0
1438 int SkPnmiEvent(
1439 SK_AC *pAC, /* Pointer to adapter context */
1440 SK_IOC IoC, /* IO context handle */
1441 SK_U32 Event, /* Event-Id */
1442 SK_EVPARA Param) /* Event dependent parameter */
1444 unsigned int PhysPortIndex;
1445 unsigned int MaxNetNumber;
1446 int CounterIndex;
1447 int Ret;
1448 SK_U16 MacStatus;
1449 SK_U64 OverflowStatus;
1450 SK_U64 Mask;
1451 int MacType;
1452 SK_U64 Value;
1453 SK_U32 Val32;
1454 SK_U16 Register;
1455 SK_EVPARA EventParam;
1456 SK_U64 NewestValue;
1457 SK_U64 OldestValue;
1458 SK_U64 Delta;
1459 SK_PNMI_ESTIMATE *pEst;
1460 SK_U32 NetIndex;
1461 SK_GEPORT *pPrt;
1462 SK_PNMI_VCT *pVctBackupData;
1463 SK_U32 RetCode;
1464 int i;
1465 SK_U32 CableLength;
1468 #ifdef DEBUG
1469 if (Event != SK_PNMI_EVT_XMAC_RESET) {
1471 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1472 ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n",
1473 (unsigned int)Event, (unsigned int)Param.Para64));
1475 #endif /* DEBUG */
1476 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call");
1478 MacType = pAC->GIni.GIMacType;
1480 switch (Event) {
1482 case SK_PNMI_EVT_SIRQ_OVERFLOW:
1483 PhysPortIndex = (int)Param.Para32[0];
1484 MacStatus = (SK_U16)Param.Para32[1];
1485 #ifdef DEBUG
1486 if (PhysPortIndex >= SK_MAX_MACS) {
1488 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1489 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter"
1490 " wrong, PhysPortIndex=0x%x\n",
1491 PhysPortIndex));
1492 return (0);
1494 #endif /* DEBUG */
1495 OverflowStatus = 0;
1498 * Check which source caused an overflow interrupt.
1500 if ((pAC->GIni.GIFunc.pFnMacOverflow(pAC, IoC, PhysPortIndex,
1501 MacStatus, &OverflowStatus) != 0) ||
1502 (OverflowStatus == 0)) {
1504 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1505 return (0);
1509 * Check the overflow status register and increment
1510 * the upper dword of corresponding counter.
1512 for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8;
1513 CounterIndex ++) {
1515 Mask = (SK_U64)1 << CounterIndex;
1516 if ((OverflowStatus & Mask) == 0) {
1518 continue;
1521 switch (StatOvrflwBit[CounterIndex][MacType]) {
1523 case SK_PNMI_HTX_UTILUNDER:
1524 case SK_PNMI_HTX_UTILOVER:
1525 if (MacType == SK_MAC_XMAC) {
1526 XM_IN16(IoC, PhysPortIndex, XM_TX_CMD, &Register);
1527 Register |= XM_TX_SAM_LINE;
1528 XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD, Register);
1530 break;
1532 case SK_PNMI_HRX_UTILUNDER:
1533 case SK_PNMI_HRX_UTILOVER:
1534 if (MacType == SK_MAC_XMAC) {
1535 XM_IN16(IoC, PhysPortIndex, XM_RX_CMD, &Register);
1536 Register |= XM_RX_SAM_LINE;
1537 XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD, Register);
1539 break;
1541 case SK_PNMI_HTX_OCTETHIGH:
1542 case SK_PNMI_HTX_OCTETLOW:
1543 case SK_PNMI_HTX_RESERVED:
1544 case SK_PNMI_HRX_OCTETHIGH:
1545 case SK_PNMI_HRX_OCTETLOW:
1546 case SK_PNMI_HRX_IRLENGTH:
1547 case SK_PNMI_HRX_RESERVED:
1550 * the following counters aren't be handled (id > 63)
1552 case SK_PNMI_HTX_SYNC:
1553 case SK_PNMI_HTX_SYNC_OCTET:
1554 break;
1556 case SK_PNMI_HRX_LONGFRAMES:
1557 if (MacType == SK_MAC_GMAC) {
1558 pAC->Pnmi.Port[PhysPortIndex].
1559 CounterHigh[CounterIndex] ++;
1561 break;
1563 default:
1564 pAC->Pnmi.Port[PhysPortIndex].
1565 CounterHigh[CounterIndex] ++;
1568 break;
1570 case SK_PNMI_EVT_SEN_WAR_LOW:
1571 #ifdef DEBUG
1572 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1574 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1575 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n",
1576 (unsigned int)Param.Para64));
1577 return (0);
1579 #endif /* DEBUG */
1582 * Store a trap message in the trap buffer and generate
1583 * an event for user space applications with the
1584 * SK_DRIVER_SENDEVENT macro.
1586 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW,
1587 (unsigned int)Param.Para64);
1588 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1589 break;
1591 case SK_PNMI_EVT_SEN_WAR_UPP:
1592 #ifdef DEBUG
1593 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1595 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1596 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n",
1597 (unsigned int)Param.Para64));
1598 return (0);
1600 #endif /* DEBUG */
1603 * Store a trap message in the trap buffer and generate
1604 * an event for user space applications with the
1605 * SK_DRIVER_SENDEVENT macro.
1607 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP,
1608 (unsigned int)Param.Para64);
1609 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1610 break;
1612 case SK_PNMI_EVT_SEN_ERR_LOW:
1613 #ifdef DEBUG
1614 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1616 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1617 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n",
1618 (unsigned int)Param.Para64));
1619 return (0);
1621 #endif /* DEBUG */
1624 * Store a trap message in the trap buffer and generate
1625 * an event for user space applications with the
1626 * SK_DRIVER_SENDEVENT macro.
1628 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW,
1629 (unsigned int)Param.Para64);
1630 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1631 break;
1633 case SK_PNMI_EVT_SEN_ERR_UPP:
1634 #ifdef DEBUG
1635 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1637 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1638 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
1639 (unsigned int)Param.Para64));
1640 return (0);
1642 #endif /* DEBUG */
1645 * Store a trap message in the trap buffer and generate
1646 * an event for user space applications with the
1647 * SK_DRIVER_SENDEVENT macro.
1649 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP,
1650 (unsigned int)Param.Para64);
1651 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1652 break;
1654 case SK_PNMI_EVT_CHG_EST_TIMER:
1656 * Calculate port switch average on a per hour basis
1657 * Time interval for check : 28125 ms
1658 * Number of values for average : 8
1660 * Be careful in changing these values, on change check
1661 * - typedef of SK_PNMI_ESTIMATE (Size of EstValue
1662 * array one less than value number)
1663 * - Timer initialization SkTimerStart() in SkPnmiInit
1664 * - Delta value below must be multiplicated with
1665 * power of 2
1668 pEst = &pAC->Pnmi.RlmtChangeEstimate;
1669 CounterIndex = pEst->EstValueIndex + 1;
1670 if (CounterIndex == 7) {
1672 CounterIndex = 0;
1674 pEst->EstValueIndex = CounterIndex;
1676 NewestValue = pAC->Pnmi.RlmtChangeCts;
1677 OldestValue = pEst->EstValue[CounterIndex];
1678 pEst->EstValue[CounterIndex] = NewestValue;
1681 * Calculate average. Delta stores the number of
1682 * port switches per 28125 * 8 = 225000 ms
1684 if (NewestValue >= OldestValue) {
1686 Delta = NewestValue - OldestValue;
1688 else {
1689 /* Overflow situation */
1690 Delta = (SK_U64)(0 - OldestValue) + NewestValue;
1694 * Extrapolate delta to port switches per hour.
1695 * Estimate = Delta * (3600000 / 225000)
1696 * = Delta * 16
1697 * = Delta << 4
1699 pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4;
1702 * Check if threshold is exceeded. If the threshold is
1703 * permanently exceeded every 28125 ms an event will be
1704 * generated to remind the user of this condition.
1706 if ((pAC->Pnmi.RlmtChangeThreshold != 0) &&
1707 (pAC->Pnmi.RlmtChangeEstimate.Estimate >=
1708 pAC->Pnmi.RlmtChangeThreshold)) {
1710 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES);
1711 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1714 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
1715 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
1716 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
1717 EventParam);
1718 break;
1720 case SK_PNMI_EVT_CLEAR_COUNTER:
1722 * Param.Para32[0] contains the NetIndex (0 ..1).
1723 * Param.Para32[1] is reserved, contains -1.
1725 NetIndex = (SK_U32)Param.Para32[0];
1727 #ifdef DEBUG
1728 if (NetIndex >= pAC->Rlmt.NumNets) {
1730 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1731 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
1732 NetIndex));
1734 return (0);
1736 #endif /* DEBUG */
1739 * Set all counters and timestamps to zero.
1740 * The according NetIndex is required as a
1741 * parameter of the event.
1743 ResetCounter(pAC, IoC, NetIndex);
1744 break;
1746 case SK_PNMI_EVT_XMAC_RESET:
1748 * To grant continuous counter values store the current
1749 * XMAC statistic values to the entries 1..n of the
1750 * CounterOffset array. XMAC Errata #2
1752 #ifdef DEBUG
1753 if ((unsigned int)Param.Para64 >= SK_MAX_MACS) {
1755 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1756 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n",
1757 (unsigned int)Param.Para64));
1758 return (0);
1760 #endif
1761 PhysPortIndex = (unsigned int)Param.Para64;
1764 * Update XMAC statistic to get fresh values
1766 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
1767 if (Ret != SK_PNMI_ERR_OK) {
1769 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1770 return (0);
1773 * Increment semaphore to indicate that an update was
1774 * already done
1776 pAC->Pnmi.MacUpdatedFlag ++;
1778 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1779 CounterIndex ++) {
1781 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1783 continue;
1786 pAC->Pnmi.Port[PhysPortIndex].CounterOffset[CounterIndex] =
1787 GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1789 pAC->Pnmi.Port[PhysPortIndex].CounterHigh[CounterIndex] = 0;
1792 pAC->Pnmi.MacUpdatedFlag --;
1793 break;
1795 case SK_PNMI_EVT_RLMT_PORT_UP:
1796 PhysPortIndex = (unsigned int)Param.Para32[0];
1797 #ifdef DEBUG
1798 if (PhysPortIndex >= SK_MAX_MACS) {
1800 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1801 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter"
1802 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1804 return (0);
1806 #endif /* DEBUG */
1809 * Store a trap message in the trap buffer and generate an event for
1810 * user space applications with the SK_DRIVER_SENDEVENT macro.
1812 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
1813 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1815 /* Bugfix for XMAC errata (#10620)*/
1816 if (MacType == SK_MAC_XMAC) {
1817 /* Add incremental difference to offset (#10620)*/
1818 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1819 XM_RXE_SHT_ERR, &Val32);
1821 Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1822 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1823 pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
1824 Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
1827 /* Tell VctStatus() that a link was up meanwhile. */
1828 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK;
1829 break;
1831 case SK_PNMI_EVT_RLMT_PORT_DOWN:
1832 PhysPortIndex = (unsigned int)Param.Para32[0];
1834 #ifdef DEBUG
1835 if (PhysPortIndex >= SK_MAX_MACS) {
1837 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1838 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter"
1839 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1841 return (0);
1843 #endif /* DEBUG */
1846 * Store a trap message in the trap buffer and generate an event for
1847 * user space applications with the SK_DRIVER_SENDEVENT macro.
1849 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
1850 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1852 /* Bugfix #10620 - get zero level for incremental difference */
1853 if (MacType == SK_MAC_XMAC) {
1855 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1856 XM_RXE_SHT_ERR, &Val32);
1858 pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark =
1859 (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1860 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1862 break;
1864 case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
1865 PhysPortIndex = (unsigned int)Param.Para32[0];
1866 NetIndex = (SK_U32)Param.Para32[1];
1868 #ifdef DEBUG
1869 if (PhysPortIndex >= SK_MAX_MACS) {
1871 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1872 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
1873 PhysPortIndex));
1876 if (NetIndex >= pAC->Rlmt.NumNets) {
1878 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1879 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
1880 NetIndex));
1882 #endif /* DEBUG */
1885 * For now, ignore event if NetIndex != 0.
1887 if (Param.Para32[1] != 0) {
1889 return (0);
1893 * Nothing to do if port is already inactive
1895 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1897 return (0);
1901 * Update statistic counters to calculate new offset for the virtual
1902 * port and increment semaphore to indicate that an update was already
1903 * done.
1905 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1906 SK_PNMI_ERR_OK) {
1908 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1909 return (0);
1911 pAC->Pnmi.MacUpdatedFlag ++;
1914 * Calculate new counter offset for virtual port to grant continous
1915 * counting on port switches. The virtual port consists of all currently
1916 * active ports. The port down event indicates that a port is removed
1917 * from the virtual port. Therefore add the counter value of the removed
1918 * port to the CounterOffset for the virtual port to grant the same
1919 * counter value.
1921 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1922 CounterIndex ++) {
1924 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1926 continue;
1929 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1931 pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
1935 * Set port to inactive
1937 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
1939 pAC->Pnmi.MacUpdatedFlag --;
1940 break;
1942 case SK_PNMI_EVT_RLMT_ACTIVE_UP:
1943 PhysPortIndex = (unsigned int)Param.Para32[0];
1944 NetIndex = (SK_U32)Param.Para32[1];
1946 #ifdef DEBUG
1947 if (PhysPortIndex >= SK_MAX_MACS) {
1949 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1950 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
1951 PhysPortIndex));
1954 if (NetIndex >= pAC->Rlmt.NumNets) {
1956 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1957 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
1958 NetIndex));
1960 #endif /* DEBUG */
1963 * For now, ignore event if NetIndex != 0.
1965 if (Param.Para32[1] != 0) {
1967 return (0);
1971 * Nothing to do if port is already active
1973 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1975 return (0);
1979 * Statistic maintenance
1981 pAC->Pnmi.RlmtChangeCts ++;
1982 pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
1985 * Store a trap message in the trap buffer and generate an event for
1986 * user space applications with the SK_DRIVER_SENDEVENT macro.
1988 QueueRlmtNewMacTrap(pAC, PhysPortIndex);
1989 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1992 * Update statistic counters to calculate new offset for the virtual
1993 * port and increment semaphore to indicate that an update was
1994 * already done.
1996 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1997 SK_PNMI_ERR_OK) {
1999 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
2000 return (0);
2002 pAC->Pnmi.MacUpdatedFlag ++;
2005 * Calculate new counter offset for virtual port to grant continous
2006 * counting on port switches. A new port is added to the virtual port.
2007 * Therefore substract the counter value of the new port from the
2008 * CounterOffset for the virtual port to grant the same value.
2010 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
2011 CounterIndex ++) {
2013 if (!StatAddr[CounterIndex][MacType].GetOffset) {
2015 continue;
2018 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
2020 pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
2023 /* Set port to active */
2024 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
2026 pAC->Pnmi.MacUpdatedFlag --;
2027 break;
2029 case SK_PNMI_EVT_RLMT_SEGMENTATION:
2031 * Para.Para32[0] contains the NetIndex.
2035 * Store a trap message in the trap buffer and generate an event for
2036 * user space applications with the SK_DRIVER_SENDEVENT macro.
2038 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
2039 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
2040 break;
2042 case SK_PNMI_EVT_RLMT_SET_NETS:
2044 * Param.Para32[0] contains the number of Nets.
2045 * Param.Para32[1] is reserved, contains -1.
2048 * Check number of nets
2050 MaxNetNumber = pAC->GIni.GIMacsFound;
2051 if (((unsigned int)Param.Para32[0] < 1)
2052 || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
2053 return (SK_PNMI_ERR_UNKNOWN_NET);
2056 if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
2057 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
2059 else { /* dual net mode */
2060 pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
2062 break;
2064 case SK_PNMI_EVT_VCT_RESET:
2065 PhysPortIndex = Param.Para32[0];
2066 pPrt = &pAC->GIni.GP[PhysPortIndex];
2067 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
2069 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
2070 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
2071 if (RetCode == 2) {
2073 * VCT test is still running.
2074 * Start VCT timer counter again.
2076 SK_MEMSET((char *) &Param, 0, sizeof(Param));
2077 Param.Para32[0] = PhysPortIndex;
2078 Param.Para32[1] = -1;
2079 SkTimerStart(pAC, IoC,
2080 &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
2081 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
2082 break;
2084 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
2085 pAC->Pnmi.VctStatus[PhysPortIndex] |=
2086 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
2088 /* Copy results for later use to PNMI struct. */
2089 for (i = 0; i < 4; i++) {
2090 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
2091 if ((pPrt->PMdiPairLen[i] > 35) &&
2092 (pPrt->PMdiPairLen[i] < 0xff)) {
2093 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
2096 if ((pPrt->PMdiPairLen[i] > 35) &&
2097 (pPrt->PMdiPairLen[i] != 0xff)) {
2098 CableLength = 1000 *
2099 (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
2101 else {
2102 CableLength = 0;
2104 pVctBackupData->PMdiPairLen[i] = CableLength;
2105 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
2108 Param.Para32[0] = PhysPortIndex;
2109 Param.Para32[1] = -1;
2110 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
2111 SkEventDispatcher(pAC, IoC);
2114 break;
2116 default:
2117 break;
2120 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
2121 return (0);
2125 /******************************************************************************
2127 * Private functions
2131 /*****************************************************************************
2133 * PnmiVar - Gets, presets, and sets single OIDs
2135 * Description:
2136 * Looks up the requested OID, calls the corresponding handler
2137 * function, and passes the parameters with the get, preset, or
2138 * set command. The function is called by SkGePnmiGetVar,
2139 * SkGePnmiPreSetVar, or SkGePnmiSetVar.
2141 * Returns:
2142 * SK_PNMI_ERR_XXX. For details have a look at the description of the
2143 * calling functions.
2144 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
2146 PNMI_STATIC int PnmiVar(
2147 SK_AC *pAC, /* Pointer to adapter context */
2148 SK_IOC IoC, /* IO context handle */
2149 int Action, /* GET/PRESET/SET action */
2150 SK_U32 Id, /* Object ID that is to be processed */
2151 char *pBuf, /* Buffer used for the management data transfer */
2152 unsigned int *pLen, /* Total length of pBuf management data */
2153 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
2154 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2156 unsigned int TableIndex;
2157 int Ret;
2160 if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
2162 *pLen = 0;
2163 return (SK_PNMI_ERR_UNKNOWN_OID);
2166 /* Check NetIndex */
2167 if (NetIndex >= pAC->Rlmt.NumNets) {
2168 return (SK_PNMI_ERR_UNKNOWN_NET);
2171 SK_PNMI_CHECKFLAGS("PnmiVar: On call");
2173 Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
2174 Instance, TableIndex, NetIndex);
2176 SK_PNMI_CHECKFLAGS("PnmiVar: On return");
2178 return (Ret);
2181 /*****************************************************************************
2183 * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA
2185 * Description:
2186 * The return value of the function will also be stored in
2187 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
2188 * SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable,
2189 * checks which OIDs are able to set, and calls the handler function of
2190 * the OID to perform the set. The return value of the function will
2191 * also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
2192 * minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called
2193 * by SkGePnmiPreSetStruct and SkGePnmiSetStruct.
2195 * Returns:
2196 * SK_PNMI_ERR_XXX. The codes are described in the calling functions.
2197 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
2199 PNMI_STATIC int PnmiStruct(
2200 SK_AC *pAC, /* Pointer to adapter context */
2201 SK_IOC IoC, /* IO context handle */
2202 int Action, /* PRESET/SET action to be performed */
2203 char *pBuf, /* Buffer used for the management data transfer */
2204 unsigned int *pLen, /* Length of pBuf management data buffer */
2205 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2207 int Ret;
2208 unsigned int TableIndex;
2209 unsigned int DstOffset;
2210 unsigned int Len;
2211 unsigned int InstanceNo;
2212 unsigned int InstanceCnt;
2213 SK_U32 Instance;
2214 SK_U32 Id;
2217 /* Check if the passed buffer has the right size */
2218 if (*pLen < SK_PNMI_STRUCT_SIZE) {
2220 /* Check if we can return the error within the buffer */
2221 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
2223 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
2224 (SK_U32)(-1));
2227 *pLen = SK_PNMI_STRUCT_SIZE;
2228 return (SK_PNMI_ERR_TOO_SHORT);
2231 /* Check NetIndex */
2232 if (NetIndex >= pAC->Rlmt.NumNets) {
2233 return (SK_PNMI_ERR_UNKNOWN_NET);
2236 SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
2239 * Update the values of RLMT and SIRQ and increment semaphores to
2240 * indicate that an update was already done.
2242 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
2244 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
2245 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2246 return (Ret);
2249 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
2251 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
2252 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2253 return (Ret);
2256 pAC->Pnmi.RlmtUpdatedFlag ++;
2257 pAC->Pnmi.SirqUpdatedFlag ++;
2259 /* Preset/Set values */
2260 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
2262 if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
2263 (IdTable[TableIndex].Access != SK_PNMI_WO)) {
2265 continue;
2268 InstanceNo = IdTable[TableIndex].InstanceNo;
2269 Id = IdTable[TableIndex].Id;
2271 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
2272 InstanceCnt ++) {
2274 DstOffset = IdTable[TableIndex].Offset +
2275 (InstanceCnt - 1) *
2276 IdTable[TableIndex].StructSize;
2279 * Because VPD multiple instance variables are
2280 * not setable we do not need to evaluate VPD
2281 * instances. Have a look to VPD instance
2282 * calculation in SkPnmiGetStruct().
2284 Instance = (SK_U32)InstanceCnt;
2287 * Evaluate needed buffer length
2289 Len = 0;
2290 Ret = IdTable[TableIndex].Func(pAC, IoC,
2291 SK_PNMI_GET, IdTable[TableIndex].Id,
2292 NULL, &Len, Instance, TableIndex, NetIndex);
2294 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
2296 break;
2298 if (Ret != SK_PNMI_ERR_TOO_SHORT) {
2300 pAC->Pnmi.RlmtUpdatedFlag --;
2301 pAC->Pnmi.SirqUpdatedFlag --;
2303 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
2304 SK_PNMI_SET_STAT(pBuf,
2305 SK_PNMI_ERR_GENERAL, DstOffset);
2306 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2307 return (SK_PNMI_ERR_GENERAL);
2309 if (Id == OID_SKGE_VPD_ACTION) {
2311 switch (*(pBuf + DstOffset)) {
2313 case SK_PNMI_VPD_CREATE:
2314 Len = 3 + *(pBuf + DstOffset + 3);
2315 break;
2317 case SK_PNMI_VPD_DELETE:
2318 Len = 3;
2319 break;
2321 default:
2322 Len = 1;
2323 break;
2327 /* Call the OID handler function */
2328 Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
2329 IdTable[TableIndex].Id, pBuf + DstOffset,
2330 &Len, Instance, TableIndex, NetIndex);
2332 if (Ret != SK_PNMI_ERR_OK) {
2334 pAC->Pnmi.RlmtUpdatedFlag --;
2335 pAC->Pnmi.SirqUpdatedFlag --;
2337 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
2338 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
2339 DstOffset);
2340 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2341 return (SK_PNMI_ERR_BAD_VALUE);
2346 pAC->Pnmi.RlmtUpdatedFlag --;
2347 pAC->Pnmi.SirqUpdatedFlag --;
2349 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
2350 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
2351 return (SK_PNMI_ERR_OK);
2354 /*****************************************************************************
2356 * LookupId - Lookup an OID in the IdTable
2358 * Description:
2359 * Scans the IdTable to find the table entry of an OID.
2361 * Returns:
2362 * The table index or -1 if not found.
2364 PNMI_STATIC int LookupId(
2365 SK_U32 Id) /* Object identifier to be searched */
2367 int i;
2369 for (i = 0; i < ID_TABLE_SIZE; i++) {
2371 if (IdTable[i].Id == Id) {
2373 return i;
2377 return (-1);
2380 /*****************************************************************************
2382 * OidStruct - Handler of OID_SKGE_ALL_DATA
2384 * Description:
2385 * This OID performs a Get/Preset/SetStruct call and returns all data
2386 * in a SK_PNMI_STRUCT_DATA structure.
2388 * Returns:
2389 * SK_PNMI_ERR_OK The request was successfully performed.
2390 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2391 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2392 * the correct data (e.g. a 32bit value is
2393 * needed, but a 16 bit value was passed).
2394 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2395 * value range.
2396 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2397 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2398 * exist (e.g. port instance 3 on a two port
2399 * adapter.
2401 PNMI_STATIC int OidStruct(
2402 SK_AC *pAC, /* Pointer to adapter context */
2403 SK_IOC IoC, /* IO context handle */
2404 int Action, /* GET/PRESET/SET action */
2405 SK_U32 Id, /* Object ID that is to be processed */
2406 char *pBuf, /* Buffer used for the management data transfer */
2407 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2408 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2409 unsigned int TableIndex, /* Index to the Id table */
2410 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2412 if (Id != OID_SKGE_ALL_DATA) {
2414 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
2415 SK_PNMI_ERR003MSG);
2417 *pLen = 0;
2418 return (SK_PNMI_ERR_GENERAL);
2422 * Check instance. We only handle single instance variables
2424 if (Instance != (SK_U32)(-1) && Instance != 1) {
2426 *pLen = 0;
2427 return (SK_PNMI_ERR_UNKNOWN_INST);
2430 switch (Action) {
2432 case SK_PNMI_GET:
2433 return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
2435 case SK_PNMI_PRESET:
2436 return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
2438 case SK_PNMI_SET:
2439 return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
2442 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
2444 *pLen = 0;
2445 return (SK_PNMI_ERR_GENERAL);
2448 /*****************************************************************************
2450 * Perform - OID handler of OID_SKGE_ACTION
2452 * Description:
2453 * None.
2455 * Returns:
2456 * SK_PNMI_ERR_OK The request was successfully performed.
2457 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2458 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2459 * the correct data (e.g. a 32bit value is
2460 * needed, but a 16 bit value was passed).
2461 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2462 * value range.
2463 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2464 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2465 * exist (e.g. port instance 3 on a two port
2466 * adapter.
2468 PNMI_STATIC int Perform(
2469 SK_AC *pAC, /* Pointer to adapter context */
2470 SK_IOC IoC, /* IO context handle */
2471 int Action, /* GET/PRESET/SET action */
2472 SK_U32 Id, /* Object ID that is to be processed */
2473 char *pBuf, /* Buffer used for the management data transfer */
2474 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2475 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2476 unsigned int TableIndex, /* Index to the Id table */
2477 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2479 int Ret;
2480 SK_U32 ActionOp;
2484 * Check instance. We only handle single instance variables
2486 if (Instance != (SK_U32)(-1) && Instance != 1) {
2488 *pLen = 0;
2489 return (SK_PNMI_ERR_UNKNOWN_INST);
2492 if (*pLen < sizeof(SK_U32)) {
2494 *pLen = sizeof(SK_U32);
2495 return (SK_PNMI_ERR_TOO_SHORT);
2498 /* Check if a get should be performed */
2499 if (Action == SK_PNMI_GET) {
2501 /* A get is easy. We always return the same value */
2502 ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
2503 SK_PNMI_STORE_U32(pBuf, ActionOp);
2504 *pLen = sizeof(SK_U32);
2506 return (SK_PNMI_ERR_OK);
2509 /* Continue with PRESET/SET action */
2510 if (*pLen > sizeof(SK_U32)) {
2512 return (SK_PNMI_ERR_BAD_VALUE);
2515 /* Check if the command is a known one */
2516 SK_PNMI_READ_U32(pBuf, ActionOp);
2517 if (*pLen > sizeof(SK_U32) ||
2518 (ActionOp != SK_PNMI_ACT_IDLE &&
2519 ActionOp != SK_PNMI_ACT_RESET &&
2520 ActionOp != SK_PNMI_ACT_SELFTEST &&
2521 ActionOp != SK_PNMI_ACT_RESETCNT)) {
2523 *pLen = 0;
2524 return (SK_PNMI_ERR_BAD_VALUE);
2527 /* A preset ends here */
2528 if (Action == SK_PNMI_PRESET) {
2530 return (SK_PNMI_ERR_OK);
2533 switch (ActionOp) {
2535 case SK_PNMI_ACT_IDLE:
2536 /* Nothing to do */
2537 break;
2539 case SK_PNMI_ACT_RESET:
2541 * Perform a driver reset or something that comes near
2542 * to this.
2544 Ret = SK_DRIVER_RESET(pAC, IoC);
2545 if (Ret != 0) {
2547 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
2548 SK_PNMI_ERR005MSG);
2550 return (SK_PNMI_ERR_GENERAL);
2552 break;
2554 case SK_PNMI_ACT_SELFTEST:
2556 * Perform a driver selftest or something similar to this.
2557 * Currently this feature is not used and will probably
2558 * implemented in another way.
2560 Ret = SK_DRIVER_SELFTEST(pAC, IoC);
2561 pAC->Pnmi.TestResult = Ret;
2562 break;
2564 case SK_PNMI_ACT_RESETCNT:
2565 /* Set all counters and timestamps to zero */
2566 ResetCounter(pAC, IoC, NetIndex);
2567 break;
2569 default:
2570 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
2571 SK_PNMI_ERR006MSG);
2573 return (SK_PNMI_ERR_GENERAL);
2576 return (SK_PNMI_ERR_OK);
2579 /*****************************************************************************
2581 * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX
2583 * Description:
2584 * Retrieves the statistic values of the virtual port (logical
2585 * index 0). Only special OIDs of NDIS are handled which consist
2586 * of a 32 bit instead of a 64 bit value. The OIDs are public
2587 * because perhaps some other platform can use them too.
2589 * Returns:
2590 * SK_PNMI_ERR_OK The request was successfully performed.
2591 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2592 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2593 * the correct data (e.g. a 32bit value is
2594 * needed, but a 16 bit value was passed).
2595 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2596 * exist (e.g. port instance 3 on a two port
2597 * adapter.
2599 PNMI_STATIC int Mac8023Stat(
2600 SK_AC *pAC, /* Pointer to adapter context */
2601 SK_IOC IoC, /* IO context handle */
2602 int Action, /* GET/PRESET/SET action */
2603 SK_U32 Id, /* Object ID that is to be processed */
2604 char *pBuf, /* Buffer used for the management data transfer */
2605 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2606 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2607 unsigned int TableIndex, /* Index to the Id table */
2608 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2610 int Ret;
2611 SK_U64 StatVal;
2612 SK_U32 StatVal32;
2613 SK_BOOL Is64BitReq = SK_FALSE;
2616 * Only the active Mac is returned
2618 if (Instance != (SK_U32)(-1) && Instance != 1) {
2620 *pLen = 0;
2621 return (SK_PNMI_ERR_UNKNOWN_INST);
2625 * Check action type
2627 if (Action != SK_PNMI_GET) {
2629 *pLen = 0;
2630 return (SK_PNMI_ERR_READ_ONLY);
2633 /* Check length */
2634 switch (Id) {
2636 case OID_802_3_PERMANENT_ADDRESS:
2637 case OID_802_3_CURRENT_ADDRESS:
2638 if (*pLen < sizeof(SK_MAC_ADDR)) {
2640 *pLen = sizeof(SK_MAC_ADDR);
2641 return (SK_PNMI_ERR_TOO_SHORT);
2643 break;
2645 default:
2646 #ifndef SK_NDIS_64BIT_CTR
2647 if (*pLen < sizeof(SK_U32)) {
2648 *pLen = sizeof(SK_U32);
2649 return (SK_PNMI_ERR_TOO_SHORT);
2652 #else /* SK_NDIS_64BIT_CTR */
2654 /* for compatibility, at least 32bit are required for OID */
2655 if (*pLen < sizeof(SK_U32)) {
2657 * but indicate handling for 64bit values,
2658 * if insufficient space is provided
2660 *pLen = sizeof(SK_U64);
2661 return (SK_PNMI_ERR_TOO_SHORT);
2664 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
2665 #endif /* SK_NDIS_64BIT_CTR */
2666 break;
2670 * Update all statistics, because we retrieve virtual MAC, which
2671 * consists of multiple physical statistics and increment semaphore
2672 * to indicate that an update was already done.
2674 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2675 if ( Ret != SK_PNMI_ERR_OK) {
2677 *pLen = 0;
2678 return (Ret);
2680 pAC->Pnmi.MacUpdatedFlag ++;
2683 * Get value (MAC Index 0 identifies the virtual MAC)
2685 switch (Id) {
2687 case OID_802_3_PERMANENT_ADDRESS:
2688 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2689 *pLen = sizeof(SK_MAC_ADDR);
2690 break;
2692 case OID_802_3_CURRENT_ADDRESS:
2693 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2694 *pLen = sizeof(SK_MAC_ADDR);
2695 break;
2697 default:
2698 StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
2700 /* by default 32bit values are evaluated */
2701 if (!Is64BitReq) {
2702 StatVal32 = (SK_U32)StatVal;
2703 SK_PNMI_STORE_U32(pBuf, StatVal32);
2704 *pLen = sizeof(SK_U32);
2706 else {
2707 SK_PNMI_STORE_U64(pBuf, StatVal);
2708 *pLen = sizeof(SK_U64);
2710 break;
2713 pAC->Pnmi.MacUpdatedFlag --;
2715 return (SK_PNMI_ERR_OK);
2718 /*****************************************************************************
2720 * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX
2722 * Description:
2723 * Retrieves the MAC statistic data.
2725 * Returns:
2726 * SK_PNMI_ERR_OK The request was successfully performed.
2727 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2728 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2729 * the correct data (e.g. a 32bit value is
2730 * needed, but a 16 bit value was passed).
2731 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2732 * exist (e.g. port instance 3 on a two port
2733 * adapter.
2735 PNMI_STATIC int MacPrivateStat(
2736 SK_AC *pAC, /* Pointer to adapter context */
2737 SK_IOC IoC, /* IO context handle */
2738 int Action, /* GET/PRESET/SET action */
2739 SK_U32 Id, /* Object ID that is to be processed */
2740 char *pBuf, /* Buffer used for the management data transfer */
2741 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2742 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2743 unsigned int TableIndex, /* Index to the Id table */
2744 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2746 unsigned int LogPortMax;
2747 unsigned int LogPortIndex;
2748 unsigned int PhysPortMax;
2749 unsigned int Limit;
2750 unsigned int Offset;
2751 int MacType;
2752 int Ret;
2753 SK_U64 StatVal;
2757 /* Calculate instance if wished. MAC index 0 is the virtual MAC */
2758 PhysPortMax = pAC->GIni.GIMacsFound;
2759 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2761 MacType = pAC->GIni.GIMacType;
2763 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2764 LogPortMax--;
2767 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2768 /* Check instance range */
2769 if ((Instance < 1) || (Instance > LogPortMax)) {
2771 *pLen = 0;
2772 return (SK_PNMI_ERR_UNKNOWN_INST);
2774 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2775 Limit = LogPortIndex + 1;
2778 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2780 LogPortIndex = 0;
2781 Limit = LogPortMax;
2784 /* Check action */
2785 if (Action != SK_PNMI_GET) {
2787 *pLen = 0;
2788 return (SK_PNMI_ERR_READ_ONLY);
2791 /* Check length */
2792 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
2794 *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
2795 return (SK_PNMI_ERR_TOO_SHORT);
2799 * Update MAC statistic and increment semaphore to indicate that
2800 * an update was already done.
2802 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2803 if (Ret != SK_PNMI_ERR_OK) {
2805 *pLen = 0;
2806 return (Ret);
2808 pAC->Pnmi.MacUpdatedFlag ++;
2810 /* Get value */
2811 Offset = 0;
2812 for (; LogPortIndex < Limit; LogPortIndex ++) {
2814 switch (Id) {
2816 /* XXX not yet implemented due to XMAC problems
2817 case OID_SKGE_STAT_TX_UTIL:
2818 return (SK_PNMI_ERR_GENERAL);
2820 /* XXX not yet implemented due to XMAC problems
2821 case OID_SKGE_STAT_RX_UTIL:
2822 return (SK_PNMI_ERR_GENERAL);
2824 case OID_SKGE_STAT_RX:
2825 if (MacType == SK_MAC_GMAC) {
2826 StatVal =
2827 GetStatVal(pAC, IoC, LogPortIndex,
2828 SK_PNMI_HRX_BROADCAST, NetIndex) +
2829 GetStatVal(pAC, IoC, LogPortIndex,
2830 SK_PNMI_HRX_MULTICAST, NetIndex) +
2831 GetStatVal(pAC, IoC, LogPortIndex,
2832 SK_PNMI_HRX_UNICAST, NetIndex) +
2833 GetStatVal(pAC, IoC, LogPortIndex,
2834 SK_PNMI_HRX_UNDERSIZE, NetIndex);
2836 else {
2837 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2838 IdTable[TableIndex].Param, NetIndex);
2840 break;
2842 case OID_SKGE_STAT_TX:
2843 if (MacType == SK_MAC_GMAC) {
2844 StatVal =
2845 GetStatVal(pAC, IoC, LogPortIndex,
2846 SK_PNMI_HTX_BROADCAST, NetIndex) +
2847 GetStatVal(pAC, IoC, LogPortIndex,
2848 SK_PNMI_HTX_MULTICAST, NetIndex) +
2849 GetStatVal(pAC, IoC, LogPortIndex,
2850 SK_PNMI_HTX_UNICAST, NetIndex);
2852 else {
2853 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2854 IdTable[TableIndex].Param, NetIndex);
2856 break;
2858 default:
2859 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2860 IdTable[TableIndex].Param, NetIndex);
2862 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2864 Offset += sizeof(SK_U64);
2866 *pLen = Offset;
2868 pAC->Pnmi.MacUpdatedFlag --;
2870 return (SK_PNMI_ERR_OK);
2873 /*****************************************************************************
2875 * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR
2877 * Description:
2878 * Get/Presets/Sets the current and factory MAC address. The MAC
2879 * address of the virtual port, which is reported to the OS, may
2880 * not be changed, but the physical ones. A set to the virtual port
2881 * will be ignored. No error should be reported because otherwise
2882 * a multiple instance set (-1) would always fail.
2884 * Returns:
2885 * SK_PNMI_ERR_OK The request was successfully performed.
2886 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2887 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2888 * the correct data (e.g. a 32bit value is
2889 * needed, but a 16 bit value was passed).
2890 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2891 * value range.
2892 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2893 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2894 * exist (e.g. port instance 3 on a two port
2895 * adapter.
2897 PNMI_STATIC int Addr(
2898 SK_AC *pAC, /* Pointer to adapter context */
2899 SK_IOC IoC, /* IO context handle */
2900 int Action, /* GET/PRESET/SET action */
2901 SK_U32 Id, /* Object ID that is to be processed */
2902 char *pBuf, /* Buffer used for the management data transfer */
2903 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2904 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2905 unsigned int TableIndex, /* Index to the Id table */
2906 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2908 int Ret;
2909 unsigned int LogPortMax;
2910 unsigned int PhysPortMax;
2911 unsigned int LogPortIndex;
2912 unsigned int PhysPortIndex;
2913 unsigned int Limit;
2914 unsigned int Offset = 0;
2917 * Calculate instance if wished. MAC index 0 is the virtual
2918 * MAC.
2920 PhysPortMax = pAC->GIni.GIMacsFound;
2921 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2923 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2924 LogPortMax--;
2927 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2928 /* Check instance range */
2929 if ((Instance < 1) || (Instance > LogPortMax)) {
2931 *pLen = 0;
2932 return (SK_PNMI_ERR_UNKNOWN_INST);
2934 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2935 Limit = LogPortIndex + 1;
2937 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2939 LogPortIndex = 0;
2940 Limit = LogPortMax;
2944 * Perform Action
2946 if (Action == SK_PNMI_GET) {
2948 /* Check length */
2949 if (*pLen < (Limit - LogPortIndex) * 6) {
2951 *pLen = (Limit - LogPortIndex) * 6;
2952 return (SK_PNMI_ERR_TOO_SHORT);
2956 * Get value
2958 for (; LogPortIndex < Limit; LogPortIndex ++) {
2960 switch (Id) {
2962 case OID_SKGE_PHYS_CUR_ADDR:
2963 if (LogPortIndex == 0) {
2964 CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2966 else {
2967 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
2969 CopyMac(pBuf + Offset,
2970 &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
2972 Offset += 6;
2973 break;
2975 case OID_SKGE_PHYS_FAC_ADDR:
2976 if (LogPortIndex == 0) {
2977 CopyMac(pBuf + Offset,
2978 &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2980 else {
2981 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
2982 pAC, LogPortIndex);
2984 CopyMac(pBuf + Offset,
2985 &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
2987 Offset += 6;
2988 break;
2990 default:
2991 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
2992 SK_PNMI_ERR008MSG);
2994 *pLen = 0;
2995 return (SK_PNMI_ERR_GENERAL);
2999 *pLen = Offset;
3001 else {
3003 * The logical MAC address may not be changed only
3004 * the physical ones
3006 if (Id == OID_SKGE_PHYS_FAC_ADDR) {
3008 *pLen = 0;
3009 return (SK_PNMI_ERR_READ_ONLY);
3013 * Only the current address may be changed
3015 if (Id != OID_SKGE_PHYS_CUR_ADDR) {
3017 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
3018 SK_PNMI_ERR009MSG);
3020 *pLen = 0;
3021 return (SK_PNMI_ERR_GENERAL);
3024 /* Check length */
3025 if (*pLen < (Limit - LogPortIndex) * 6) {
3027 *pLen = (Limit - LogPortIndex) * 6;
3028 return (SK_PNMI_ERR_TOO_SHORT);
3030 if (*pLen > (Limit - LogPortIndex) * 6) {
3032 *pLen = 0;
3033 return (SK_PNMI_ERR_BAD_VALUE);
3037 * Check Action
3039 if (Action == SK_PNMI_PRESET) {
3041 *pLen = 0;
3042 return (SK_PNMI_ERR_OK);
3046 * Set OID_SKGE_MAC_CUR_ADDR
3048 for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
3051 * A set to virtual port and set of broadcast
3052 * address will be ignored
3054 if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
3055 "\xff\xff\xff\xff\xff\xff", 6) == 0) {
3057 continue;
3060 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
3061 LogPortIndex);
3063 Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
3064 (SK_MAC_ADDR *)(pBuf + Offset),
3065 (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
3066 SK_ADDR_PHYSICAL_ADDRESS));
3067 if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {
3069 return (SK_PNMI_ERR_GENERAL);
3072 *pLen = Offset;
3075 return (SK_PNMI_ERR_OK);
3078 /*****************************************************************************
3080 * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
3082 * Description:
3083 * Retrieves the statistic values of the CSUM module. The CSUM data
3084 * structure must be available in the SK_AC even if the CSUM module
3085 * is not included, because PNMI reads the statistic data from the
3086 * CSUM part of SK_AC directly.
3088 * Returns:
3089 * SK_PNMI_ERR_OK The request was successfully performed.
3090 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3091 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3092 * the correct data (e.g. a 32bit value is
3093 * needed, but a 16 bit value was passed).
3094 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3095 * exist (e.g. port instance 3 on a two port
3096 * adapter.
3098 PNMI_STATIC int CsumStat(
3099 SK_AC *pAC, /* Pointer to adapter context */
3100 SK_IOC IoC, /* IO context handle */
3101 int Action, /* GET/PRESET/SET action */
3102 SK_U32 Id, /* Object ID that is to be processed */
3103 char *pBuf, /* Buffer used for the management data transfer */
3104 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
3105 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3106 unsigned int TableIndex, /* Index to the Id table */
3107 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
3109 unsigned int Index;
3110 unsigned int Limit;
3111 unsigned int Offset = 0;
3112 SK_U64 StatVal;
3116 * Calculate instance if wished
3118 if (Instance != (SK_U32)(-1)) {
3120 if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
3122 *pLen = 0;
3123 return (SK_PNMI_ERR_UNKNOWN_INST);
3125 Index = (unsigned int)Instance - 1;
3126 Limit = Index + 1;
3128 else {
3129 Index = 0;
3130 Limit = SKCS_NUM_PROTOCOLS;
3134 * Check action
3136 if (Action != SK_PNMI_GET) {
3138 *pLen = 0;
3139 return (SK_PNMI_ERR_READ_ONLY);
3142 /* Check length */
3143 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
3145 *pLen = (Limit - Index) * sizeof(SK_U64);
3146 return (SK_PNMI_ERR_TOO_SHORT);
3150 * Get value
3152 for (; Index < Limit; Index ++) {
3154 switch (Id) {
3156 case OID_SKGE_CHKSM_RX_OK_CTS:
3157 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
3158 break;
3160 case OID_SKGE_CHKSM_RX_UNABLE_CTS:
3161 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
3162 break;
3164 case OID_SKGE_CHKSM_RX_ERR_CTS:
3165 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
3166 break;
3168 case OID_SKGE_CHKSM_TX_OK_CTS:
3169 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
3170 break;
3172 case OID_SKGE_CHKSM_TX_UNABLE_CTS:
3173 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
3174 break;
3176 default:
3177 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
3178 SK_PNMI_ERR010MSG);
3180 *pLen = 0;
3181 return (SK_PNMI_ERR_GENERAL);
3184 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
3185 Offset += sizeof(SK_U64);
3189 * Store used buffer space
3191 *pLen = Offset;
3193 return (SK_PNMI_ERR_OK);
3196 /*****************************************************************************
3198 * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
3200 * Description:
3201 * Retrieves the statistic values of the I2C module, which handles
3202 * the temperature and voltage sensors.
3204 * Returns:
3205 * SK_PNMI_ERR_OK The request was successfully performed.
3206 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3207 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3208 * the correct data (e.g. a 32bit value is
3209 * needed, but a 16 bit value was passed).
3210 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3211 * exist (e.g. port instance 3 on a two port
3212 * adapter.
3214 PNMI_STATIC int SensorStat(
3215 SK_AC *pAC, /* Pointer to adapter context */
3216 SK_IOC IoC, /* IO context handle */
3217 int Action, /* GET/PRESET/SET action */
3218 SK_U32 Id, /* Object ID that is to be processed */
3219 char *pBuf, /* Buffer used for the management data transfer */
3220 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
3221 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3222 unsigned int TableIndex, /* Index to the Id table */
3223 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
3225 unsigned int i;
3226 unsigned int Index;
3227 unsigned int Limit;
3228 unsigned int Offset;
3229 unsigned int Len;
3230 SK_U32 Val32;
3231 SK_U64 Val64;
3235 * Calculate instance if wished
3237 if ((Instance != (SK_U32)(-1))) {
3239 if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
3241 *pLen = 0;
3242 return (SK_PNMI_ERR_UNKNOWN_INST);
3245 Index = (unsigned int)Instance -1;
3246 Limit = (unsigned int)Instance;
3248 else {
3249 Index = 0;
3250 Limit = (unsigned int) pAC->I2c.MaxSens;
3254 * Check action
3256 if (Action != SK_PNMI_GET) {
3258 *pLen = 0;
3259 return (SK_PNMI_ERR_READ_ONLY);
3262 /* Check length */
3263 switch (Id) {
3265 case OID_SKGE_SENSOR_VALUE:
3266 case OID_SKGE_SENSOR_WAR_THRES_LOW:
3267 case OID_SKGE_SENSOR_WAR_THRES_UPP:
3268 case OID_SKGE_SENSOR_ERR_THRES_LOW:
3269 case OID_SKGE_SENSOR_ERR_THRES_UPP:
3270 if (*pLen < (Limit - Index) * sizeof(SK_U32)) {
3272 *pLen = (Limit - Index) * sizeof(SK_U32);
3273 return (SK_PNMI_ERR_TOO_SHORT);
3275 break;
3277 case OID_SKGE_SENSOR_DESCR:
3278 for (Offset = 0, i = Index; i < Limit; i ++) {
3280 Len = (unsigned int)
3281 SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1;
3282 if (Len >= SK_PNMI_STRINGLEN2) {
3284 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011,
3285 SK_PNMI_ERR011MSG);
3287 *pLen = 0;
3288 return (SK_PNMI_ERR_GENERAL);
3290 Offset += Len;
3292 if (*pLen < Offset) {
3294 *pLen = Offset;
3295 return (SK_PNMI_ERR_TOO_SHORT);
3297 break;
3299 case OID_SKGE_SENSOR_INDEX:
3300 case OID_SKGE_SENSOR_TYPE:
3301 case OID_SKGE_SENSOR_STATUS:
3302 if (*pLen < Limit - Index) {
3304 *pLen = Limit - Index;
3305 return (SK_PNMI_ERR_TOO_SHORT);
3307 break;
3309 case OID_SKGE_SENSOR_WAR_CTS:
3310 case OID_SKGE_SENSOR_WAR_TIME:
3311 case OID_SKGE_SENSOR_ERR_CTS:
3312 case OID_SKGE_SENSOR_ERR_TIME:
3313 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
3315 *pLen = (Limit - Index) * sizeof(SK_U64);
3316 return (SK_PNMI_ERR_TOO_SHORT);
3318 break;
3320 default:
3321 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
3322 SK_PNMI_ERR012MSG);
3324 *pLen = 0;
3325 return (SK_PNMI_ERR_GENERAL);
3330 * Get value
3332 for (Offset = 0; Index < Limit; Index ++) {
3334 switch (Id) {
3336 case OID_SKGE_SENSOR_INDEX:
3337 *(pBuf + Offset) = (char)Index;
3338 Offset += sizeof(char);
3339 break;
3341 case OID_SKGE_SENSOR_DESCR:
3342 Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
3343 SK_MEMCPY(pBuf + Offset + 1,
3344 pAC->I2c.SenTable[Index].SenDesc, Len);
3345 *(pBuf + Offset) = (char)Len;
3346 Offset += Len + 1;
3347 break;
3349 case OID_SKGE_SENSOR_TYPE:
3350 *(pBuf + Offset) =
3351 (char)pAC->I2c.SenTable[Index].SenType;
3352 Offset += sizeof(char);
3353 break;
3355 case OID_SKGE_SENSOR_VALUE:
3356 Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
3357 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3358 Offset += sizeof(SK_U32);
3359 break;
3361 case OID_SKGE_SENSOR_WAR_THRES_LOW:
3362 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
3363 SenThreWarnLow;
3364 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3365 Offset += sizeof(SK_U32);
3366 break;
3368 case OID_SKGE_SENSOR_WAR_THRES_UPP:
3369 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
3370 SenThreWarnHigh;
3371 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3372 Offset += sizeof(SK_U32);
3373 break;
3375 case OID_SKGE_SENSOR_ERR_THRES_LOW:
3376 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
3377 SenThreErrLow;
3378 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3379 Offset += sizeof(SK_U32);
3380 break;
3382 case OID_SKGE_SENSOR_ERR_THRES_UPP:
3383 Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
3384 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3385 Offset += sizeof(SK_U32);
3386 break;
3388 case OID_SKGE_SENSOR_STATUS:
3389 *(pBuf + Offset) =
3390 (char)pAC->I2c.SenTable[Index].SenErrFlag;
3391 Offset += sizeof(char);
3392 break;
3394 case OID_SKGE_SENSOR_WAR_CTS:
3395 Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
3396 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3397 Offset += sizeof(SK_U64);
3398 break;
3400 case OID_SKGE_SENSOR_ERR_CTS:
3401 Val64 = pAC->I2c.SenTable[Index].SenErrCts;
3402 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3403 Offset += sizeof(SK_U64);
3404 break;
3406 case OID_SKGE_SENSOR_WAR_TIME:
3407 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
3408 SenBegWarnTS);
3409 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3410 Offset += sizeof(SK_U64);
3411 break;
3413 case OID_SKGE_SENSOR_ERR_TIME:
3414 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
3415 SenBegErrTS);
3416 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3417 Offset += sizeof(SK_U64);
3418 break;
3420 default:
3421 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
3422 ("SensorStat: Unknown OID should be handled before"));
3424 return (SK_PNMI_ERR_GENERAL);
3429 * Store used buffer space
3431 *pLen = Offset;
3433 return (SK_PNMI_ERR_OK);
3436 /*****************************************************************************
3438 * Vpd - OID handler function of OID_SKGE_VPD_XXX
3440 * Description:
3441 * Get/preset/set of VPD data. As instance the name of a VPD key
3442 * can be passed. The Instance parameter is a SK_U32 and can be
3443 * used as a string buffer for the VPD key, because their maximum
3444 * length is 4 byte.
3446 * Returns:
3447 * SK_PNMI_ERR_OK The request was successfully performed.
3448 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3449 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3450 * the correct data (e.g. a 32bit value is
3451 * needed, but a 16 bit value was passed).
3452 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
3453 * value range.
3454 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
3455 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3456 * exist (e.g. port instance 3 on a two port
3457 * adapter.
3459 PNMI_STATIC int Vpd(
3460 SK_AC *pAC, /* Pointer to adapter context */
3461 SK_IOC IoC, /* IO context handle */
3462 int Action, /* GET/PRESET/SET action */
3463 SK_U32 Id, /* Object ID that is to be processed */
3464 char *pBuf, /* Buffer used for the management data transfer */
3465 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
3466 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3467 unsigned int TableIndex, /* Index to the Id table */
3468 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
3470 SK_VPD_STATUS *pVpdStatus;
3471 unsigned int BufLen;
3472 char Buf[256];
3473 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
3474 char KeyStr[SK_PNMI_VPD_KEY_SIZE];
3475 unsigned int KeyNo;
3476 unsigned int Offset;
3477 unsigned int Index;
3478 unsigned int FirstIndex;
3479 unsigned int LastIndex;
3480 unsigned int Len;
3481 int Ret;
3482 SK_U32 Val32;
3485 * Get array of all currently stored VPD keys
3487 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &KeyNo);
3488 if (Ret != SK_PNMI_ERR_OK) {
3489 *pLen = 0;
3490 return (Ret);
3494 * If instance is not -1, try to find the requested VPD key for
3495 * the multiple instance variables. The other OIDs as for example
3496 * OID VPD_ACTION are single instance variables and must be
3497 * handled separatly.
3499 FirstIndex = 0;
3500 LastIndex = KeyNo;
3502 if ((Instance != (SK_U32)(-1))) {
3504 if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
3505 Id == OID_SKGE_VPD_ACCESS) {
3507 SK_STRNCPY(KeyStr, (char *)&Instance, 4);
3508 KeyStr[4] = 0;
3510 for (Index = 0; Index < KeyNo; Index ++) {
3512 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3513 FirstIndex = Index;
3514 LastIndex = Index+1;
3515 break;
3518 if (Index == KeyNo) {
3520 *pLen = 0;
3521 return (SK_PNMI_ERR_UNKNOWN_INST);
3524 else if (Instance != 1) {
3526 *pLen = 0;
3527 return (SK_PNMI_ERR_UNKNOWN_INST);
3532 * Get value, if a query should be performed
3534 if (Action == SK_PNMI_GET) {
3536 switch (Id) {
3538 case OID_SKGE_VPD_FREE_BYTES:
3539 /* Check length of buffer */
3540 if (*pLen < sizeof(SK_U32)) {
3542 *pLen = sizeof(SK_U32);
3543 return (SK_PNMI_ERR_TOO_SHORT);
3545 /* Get number of free bytes */
3546 pVpdStatus = VpdStat(pAC, IoC);
3547 if (pVpdStatus == NULL) {
3549 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
3550 SK_PNMI_ERR017MSG);
3552 *pLen = 0;
3553 return (SK_PNMI_ERR_GENERAL);
3555 if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
3557 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
3558 SK_PNMI_ERR018MSG);
3560 *pLen = 0;
3561 return (SK_PNMI_ERR_GENERAL);
3564 Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
3565 SK_PNMI_STORE_U32(pBuf, Val32);
3566 *pLen = sizeof(SK_U32);
3567 break;
3569 case OID_SKGE_VPD_ENTRIES_LIST:
3570 /* Check length */
3571 for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
3573 Len += SK_STRLEN(KeyArr[Index]) + 1;
3575 if (*pLen < Len) {
3577 *pLen = Len;
3578 return (SK_PNMI_ERR_TOO_SHORT);
3581 /* Get value */
3582 *(pBuf) = (char)Len - 1;
3583 for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
3585 Len = SK_STRLEN(KeyArr[Index]);
3586 SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
3588 Offset += Len;
3590 if (Index < KeyNo - 1) {
3592 *(pBuf + Offset) = ' ';
3593 Offset ++;
3596 *pLen = Offset;
3597 break;
3599 case OID_SKGE_VPD_ENTRIES_NUMBER:
3600 /* Check length */
3601 if (*pLen < sizeof(SK_U32)) {
3603 *pLen = sizeof(SK_U32);
3604 return (SK_PNMI_ERR_TOO_SHORT);
3607 Val32 = (SK_U32)KeyNo;
3608 SK_PNMI_STORE_U32(pBuf, Val32);
3609 *pLen = sizeof(SK_U32);
3610 break;
3612 case OID_SKGE_VPD_KEY:
3613 /* Check buffer length, if it is large enough */
3614 for (Len = 0, Index = FirstIndex;
3615 Index < LastIndex; Index ++) {
3617 Len += SK_STRLEN(KeyArr[Index]) + 1;
3619 if (*pLen < Len) {
3621 *pLen = Len;
3622 return (SK_PNMI_ERR_TOO_SHORT);
3626 * Get the key to an intermediate buffer, because
3627 * we have to prepend a length byte.
3629 for (Offset = 0, Index = FirstIndex;
3630 Index < LastIndex; Index ++) {
3632 Len = SK_STRLEN(KeyArr[Index]);
3634 *(pBuf + Offset) = (char)Len;
3635 SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
3636 Len);
3637 Offset += Len + 1;
3639 *pLen = Offset;
3640 break;
3642 case OID_SKGE_VPD_VALUE:
3643 /* Check the buffer length if it is large enough */
3644 for (Offset = 0, Index = FirstIndex;
3645 Index < LastIndex; Index ++) {
3647 BufLen = 256;
3648 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3649 (int *)&BufLen) > 0 ||
3650 BufLen >= SK_PNMI_VPD_DATALEN) {
3652 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3653 SK_PNMI_ERR021,
3654 SK_PNMI_ERR021MSG);
3656 return (SK_PNMI_ERR_GENERAL);
3658 Offset += BufLen + 1;
3660 if (*pLen < Offset) {
3662 *pLen = Offset;
3663 return (SK_PNMI_ERR_TOO_SHORT);
3667 * Get the value to an intermediate buffer, because
3668 * we have to prepend a length byte.
3670 for (Offset = 0, Index = FirstIndex;
3671 Index < LastIndex; Index ++) {
3673 BufLen = 256;
3674 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3675 (int *)&BufLen) > 0 ||
3676 BufLen >= SK_PNMI_VPD_DATALEN) {
3678 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3679 SK_PNMI_ERR022,
3680 SK_PNMI_ERR022MSG);
3682 *pLen = 0;
3683 return (SK_PNMI_ERR_GENERAL);
3686 *(pBuf + Offset) = (char)BufLen;
3687 SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
3688 Offset += BufLen + 1;
3690 *pLen = Offset;
3691 break;
3693 case OID_SKGE_VPD_ACCESS:
3694 if (*pLen < LastIndex - FirstIndex) {
3696 *pLen = LastIndex - FirstIndex;
3697 return (SK_PNMI_ERR_TOO_SHORT);
3700 for (Offset = 0, Index = FirstIndex;
3701 Index < LastIndex; Index ++) {
3703 if (VpdMayWrite(KeyArr[Index])) {
3705 *(pBuf + Offset) = SK_PNMI_VPD_RW;
3707 else {
3708 *(pBuf + Offset) = SK_PNMI_VPD_RO;
3710 Offset ++;
3712 *pLen = Offset;
3713 break;
3715 case OID_SKGE_VPD_ACTION:
3716 Offset = LastIndex - FirstIndex;
3717 if (*pLen < Offset) {
3719 *pLen = Offset;
3720 return (SK_PNMI_ERR_TOO_SHORT);
3722 SK_MEMSET(pBuf, 0, Offset);
3723 *pLen = Offset;
3724 break;
3726 default:
3727 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
3728 SK_PNMI_ERR023MSG);
3730 *pLen = 0;
3731 return (SK_PNMI_ERR_GENERAL);
3734 else {
3735 /* The only OID which can be set is VPD_ACTION */
3736 if (Id != OID_SKGE_VPD_ACTION) {
3738 if (Id == OID_SKGE_VPD_FREE_BYTES ||
3739 Id == OID_SKGE_VPD_ENTRIES_LIST ||
3740 Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
3741 Id == OID_SKGE_VPD_KEY ||
3742 Id == OID_SKGE_VPD_VALUE ||
3743 Id == OID_SKGE_VPD_ACCESS) {
3745 *pLen = 0;
3746 return (SK_PNMI_ERR_READ_ONLY);
3749 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
3750 SK_PNMI_ERR024MSG);
3752 *pLen = 0;
3753 return (SK_PNMI_ERR_GENERAL);
3757 * From this point we handle VPD_ACTION. Check the buffer
3758 * length. It should at least have the size of one byte.
3760 if (*pLen < 1) {
3762 *pLen = 1;
3763 return (SK_PNMI_ERR_TOO_SHORT);
3767 * The first byte contains the VPD action type we should
3768 * perform.
3770 switch (*pBuf) {
3772 case SK_PNMI_VPD_IGNORE:
3773 /* Nothing to do */
3774 break;
3776 case SK_PNMI_VPD_CREATE:
3778 * We have to create a new VPD entry or we modify
3779 * an existing one. Check first the buffer length.
3781 if (*pLen < 4) {
3783 *pLen = 4;
3784 return (SK_PNMI_ERR_TOO_SHORT);
3786 KeyStr[0] = pBuf[1];
3787 KeyStr[1] = pBuf[2];
3788 KeyStr[2] = 0;
3791 * Is the entry writable or does it belong to the
3792 * read-only area?
3794 if (!VpdMayWrite(KeyStr)) {
3796 *pLen = 0;
3797 return (SK_PNMI_ERR_BAD_VALUE);
3800 Offset = (int)pBuf[3] & 0xFF;
3802 SK_MEMCPY(Buf, pBuf + 4, Offset);
3803 Buf[Offset] = 0;
3805 /* A preset ends here */
3806 if (Action == SK_PNMI_PRESET) {
3808 return (SK_PNMI_ERR_OK);
3811 /* Write the new entry or modify an existing one */
3812 Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
3813 if (Ret == SK_PNMI_VPD_NOWRITE ) {
3815 *pLen = 0;
3816 return (SK_PNMI_ERR_BAD_VALUE);
3818 else if (Ret != SK_PNMI_VPD_OK) {
3820 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
3821 SK_PNMI_ERR025MSG);
3823 *pLen = 0;
3824 return (SK_PNMI_ERR_GENERAL);
3828 * Perform an update of the VPD data. This is
3829 * not mandantory, but just to be sure.
3831 Ret = VpdUpdate(pAC, IoC);
3832 if (Ret != SK_PNMI_VPD_OK) {
3834 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
3835 SK_PNMI_ERR026MSG);
3837 *pLen = 0;
3838 return (SK_PNMI_ERR_GENERAL);
3840 break;
3842 case SK_PNMI_VPD_DELETE:
3843 /* Check if the buffer size is plausible */
3844 if (*pLen < 3) {
3846 *pLen = 3;
3847 return (SK_PNMI_ERR_TOO_SHORT);
3849 if (*pLen > 3) {
3851 *pLen = 0;
3852 return (SK_PNMI_ERR_BAD_VALUE);
3854 KeyStr[0] = pBuf[1];
3855 KeyStr[1] = pBuf[2];
3856 KeyStr[2] = 0;
3858 /* Find the passed key in the array */
3859 for (Index = 0; Index < KeyNo; Index ++) {
3861 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3863 break;
3867 * If we cannot find the key it is wrong, so we
3868 * return an appropriate error value.
3870 if (Index == KeyNo) {
3872 *pLen = 0;
3873 return (SK_PNMI_ERR_BAD_VALUE);
3876 if (Action == SK_PNMI_PRESET) {
3878 return (SK_PNMI_ERR_OK);
3881 /* Ok, you wanted it and you will get it */
3882 Ret = VpdDelete(pAC, IoC, KeyStr);
3883 if (Ret != SK_PNMI_VPD_OK) {
3885 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
3886 SK_PNMI_ERR027MSG);
3888 *pLen = 0;
3889 return (SK_PNMI_ERR_GENERAL);
3893 * Perform an update of the VPD data. This is
3894 * not mandantory, but just to be sure.
3896 Ret = VpdUpdate(pAC, IoC);
3897 if (Ret != SK_PNMI_VPD_OK) {
3899 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
3900 SK_PNMI_ERR028MSG);
3902 *pLen = 0;
3903 return (SK_PNMI_ERR_GENERAL);
3905 break;
3907 default:
3908 *pLen = 0;
3909 return (SK_PNMI_ERR_BAD_VALUE);
3913 return (SK_PNMI_ERR_OK);
3916 /*****************************************************************************
3918 * General - OID handler function of various single instance OIDs
3920 * Description:
3921 * The code is simple. No description necessary.
3923 * Returns:
3924 * SK_PNMI_ERR_OK The request was successfully performed.
3925 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3926 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3927 * the correct data (e.g. a 32bit value is
3928 * needed, but a 16 bit value was passed).
3929 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3930 * exist (e.g. port instance 3 on a two port
3931 * adapter.
3933 PNMI_STATIC int General(
3934 SK_AC *pAC, /* Pointer to adapter context */
3935 SK_IOC IoC, /* IO context handle */
3936 int Action, /* GET/PRESET/SET action */
3937 SK_U32 Id, /* Object ID that is to be processed */
3938 char *pBuf, /* Buffer used for the management data transfer */
3939 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3940 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3941 unsigned int TableIndex, /* Index to the Id table */
3942 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
3944 int Ret;
3945 unsigned int Index;
3946 unsigned int Len;
3947 unsigned int Offset;
3948 unsigned int Val;
3949 SK_U8 Val8;
3950 SK_U16 Val16;
3951 SK_U32 Val32;
3952 SK_U64 Val64;
3953 SK_U64 Val64RxHwErrs = 0;
3954 SK_U64 Val64TxHwErrs = 0;
3955 SK_BOOL Is64BitReq = SK_FALSE;
3956 char Buf[256];
3957 int MacType;
3960 * Check instance. We only handle single instance variables.
3962 if (Instance != (SK_U32)(-1) && Instance != 1) {
3964 *pLen = 0;
3965 return (SK_PNMI_ERR_UNKNOWN_INST);
3969 * Check action. We only allow get requests.
3971 if (Action != SK_PNMI_GET) {
3973 *pLen = 0;
3974 return (SK_PNMI_ERR_READ_ONLY);
3977 MacType = pAC->GIni.GIMacType;
3980 * Check length for the various supported OIDs
3982 switch (Id) {
3984 case OID_GEN_XMIT_ERROR:
3985 case OID_GEN_RCV_ERROR:
3986 case OID_GEN_RCV_NO_BUFFER:
3987 #ifndef SK_NDIS_64BIT_CTR
3988 if (*pLen < sizeof(SK_U32)) {
3989 *pLen = sizeof(SK_U32);
3990 return (SK_PNMI_ERR_TOO_SHORT);
3993 #else /* SK_NDIS_64BIT_CTR */
3996 * for compatibility, at least 32bit are required for oid
3998 if (*pLen < sizeof(SK_U32)) {
4000 * but indicate handling for 64bit values,
4001 * if insufficient space is provided
4003 *pLen = sizeof(SK_U64);
4004 return (SK_PNMI_ERR_TOO_SHORT);
4007 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
4008 #endif /* SK_NDIS_64BIT_CTR */
4009 break;
4011 case OID_SKGE_BOARDLEVEL:
4012 if (*pLen < sizeof(SK_U32)) {
4014 *pLen = sizeof(SK_U32);
4015 return (SK_PNMI_ERR_TOO_SHORT);
4017 break;
4019 case OID_SKGE_PORT_NUMBER:
4020 case OID_SKGE_DEVICE_TYPE:
4021 case OID_SKGE_RESULT:
4022 case OID_SKGE_RLMT_MONITOR_NUMBER:
4023 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
4024 case OID_SKGE_TRAP_NUMBER:
4025 case OID_SKGE_MDB_VERSION:
4026 if (*pLen < sizeof(SK_U32)) {
4028 *pLen = sizeof(SK_U32);
4029 return (SK_PNMI_ERR_TOO_SHORT);
4031 break;
4033 case OID_SKGE_CHIPSET:
4034 if (*pLen < sizeof(SK_U16)) {
4036 *pLen = sizeof(SK_U16);
4037 return (SK_PNMI_ERR_TOO_SHORT);
4039 break;
4041 case OID_SKGE_BUS_TYPE:
4042 case OID_SKGE_BUS_SPEED:
4043 case OID_SKGE_BUS_WIDTH:
4044 case OID_SKGE_SENSOR_NUMBER:
4045 case OID_SKGE_CHKSM_NUMBER:
4046 if (*pLen < sizeof(SK_U8)) {
4048 *pLen = sizeof(SK_U8);
4049 return (SK_PNMI_ERR_TOO_SHORT);
4051 break;
4053 case OID_SKGE_TX_SW_QUEUE_LEN:
4054 case OID_SKGE_TX_SW_QUEUE_MAX:
4055 case OID_SKGE_TX_RETRY:
4056 case OID_SKGE_RX_INTR_CTS:
4057 case OID_SKGE_TX_INTR_CTS:
4058 case OID_SKGE_RX_NO_BUF_CTS:
4059 case OID_SKGE_TX_NO_BUF_CTS:
4060 case OID_SKGE_TX_USED_DESCR_NO:
4061 case OID_SKGE_RX_DELIVERED_CTS:
4062 case OID_SKGE_RX_OCTETS_DELIV_CTS:
4063 case OID_SKGE_RX_HW_ERROR_CTS:
4064 case OID_SKGE_TX_HW_ERROR_CTS:
4065 case OID_SKGE_IN_ERRORS_CTS:
4066 case OID_SKGE_OUT_ERROR_CTS:
4067 case OID_SKGE_ERR_RECOVERY_CTS:
4068 case OID_SKGE_SYSUPTIME:
4069 if (*pLen < sizeof(SK_U64)) {
4071 *pLen = sizeof(SK_U64);
4072 return (SK_PNMI_ERR_TOO_SHORT);
4074 break;
4076 default:
4077 /* Checked later */
4078 break;
4081 /* Update statistic */
4082 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
4083 Id == OID_SKGE_TX_HW_ERROR_CTS ||
4084 Id == OID_SKGE_IN_ERRORS_CTS ||
4085 Id == OID_SKGE_OUT_ERROR_CTS ||
4086 Id == OID_GEN_XMIT_ERROR ||
4087 Id == OID_GEN_RCV_ERROR) {
4089 /* Force the XMAC to update its statistic counters and
4090 * Increment semaphore to indicate that an update was
4091 * already done.
4093 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
4094 if (Ret != SK_PNMI_ERR_OK) {
4096 *pLen = 0;
4097 return (Ret);
4099 pAC->Pnmi.MacUpdatedFlag ++;
4102 * Some OIDs consist of multiple hardware counters. Those
4103 * values which are contained in all of them will be added
4104 * now.
4106 switch (Id) {
4108 case OID_SKGE_RX_HW_ERROR_CTS:
4109 case OID_SKGE_IN_ERRORS_CTS:
4110 case OID_GEN_RCV_ERROR:
4111 Val64RxHwErrs =
4112 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
4113 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
4114 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex) +
4115 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
4116 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
4117 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex) +
4118 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
4119 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
4120 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
4121 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
4122 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
4123 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
4124 break;
4126 case OID_SKGE_TX_HW_ERROR_CTS:
4127 case OID_SKGE_OUT_ERROR_CTS:
4128 case OID_GEN_XMIT_ERROR:
4129 Val64TxHwErrs =
4130 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
4131 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex) +
4132 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex) +
4133 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex);
4134 break;
4139 * Retrieve value
4141 switch (Id) {
4143 case OID_SKGE_SUPPORTED_LIST:
4144 Len = ID_TABLE_SIZE * sizeof(SK_U32);
4145 if (*pLen < Len) {
4147 *pLen = Len;
4148 return (SK_PNMI_ERR_TOO_SHORT);
4150 for (Offset = 0, Index = 0; Offset < Len;
4151 Offset += sizeof(SK_U32), Index ++) {
4153 Val32 = (SK_U32)IdTable[Index].Id;
4154 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4156 *pLen = Len;
4157 break;
4159 case OID_SKGE_BOARDLEVEL:
4160 Val32 = (SK_U32)pAC->GIni.GILevel;
4161 SK_PNMI_STORE_U32(pBuf, Val32);
4162 *pLen = sizeof(SK_U32);
4163 break;
4165 case OID_SKGE_PORT_NUMBER:
4166 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
4167 SK_PNMI_STORE_U32(pBuf, Val32);
4168 *pLen = sizeof(SK_U32);
4169 break;
4171 case OID_SKGE_DEVICE_TYPE:
4172 Val32 = (SK_U32)pAC->Pnmi.DeviceType;
4173 SK_PNMI_STORE_U32(pBuf, Val32);
4174 *pLen = sizeof(SK_U32);
4175 break;
4177 case OID_SKGE_DRIVER_DESCR:
4178 if (pAC->Pnmi.pDriverDescription == NULL) {
4180 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
4181 SK_PNMI_ERR007MSG);
4183 *pLen = 0;
4184 return (SK_PNMI_ERR_GENERAL);
4187 Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
4188 if (Len > SK_PNMI_STRINGLEN1) {
4190 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
4191 SK_PNMI_ERR029MSG);
4193 *pLen = 0;
4194 return (SK_PNMI_ERR_GENERAL);
4197 if (*pLen < Len) {
4199 *pLen = Len;
4200 return (SK_PNMI_ERR_TOO_SHORT);
4202 *pBuf = (char)(Len - 1);
4203 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
4204 *pLen = Len;
4205 break;
4207 case OID_SKGE_DRIVER_VERSION:
4208 if (pAC->Pnmi.pDriverVersion == NULL) {
4210 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
4211 SK_PNMI_ERR030MSG);
4213 *pLen = 0;
4214 return (SK_PNMI_ERR_GENERAL);
4217 Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
4218 if (Len > SK_PNMI_STRINGLEN1) {
4220 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
4221 SK_PNMI_ERR031MSG);
4223 *pLen = 0;
4224 return (SK_PNMI_ERR_GENERAL);
4227 if (*pLen < Len) {
4229 *pLen = Len;
4230 return (SK_PNMI_ERR_TOO_SHORT);
4232 *pBuf = (char)(Len - 1);
4233 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
4234 *pLen = Len;
4235 break;
4237 case OID_SKGE_HW_DESCR:
4239 * The hardware description is located in the VPD. This
4240 * query may move to the initialisation routine. But
4241 * the VPD data is cached and therefore a call here
4242 * will not make much difference.
4244 Len = 256;
4245 if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
4247 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
4248 SK_PNMI_ERR032MSG);
4250 *pLen = 0;
4251 return (SK_PNMI_ERR_GENERAL);
4253 Len ++;
4254 if (Len > SK_PNMI_STRINGLEN1) {
4256 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
4257 SK_PNMI_ERR033MSG);
4259 *pLen = 0;
4260 return (SK_PNMI_ERR_GENERAL);
4262 if (*pLen < Len) {
4264 *pLen = Len;
4265 return (SK_PNMI_ERR_TOO_SHORT);
4267 *pBuf = (char)(Len - 1);
4268 SK_MEMCPY(pBuf + 1, Buf, Len - 1);
4269 *pLen = Len;
4270 break;
4272 case OID_SKGE_HW_VERSION:
4273 /* Oh, I love to do some string manipulation */
4274 if (*pLen < 5) {
4276 *pLen = 5;
4277 return (SK_PNMI_ERR_TOO_SHORT);
4279 Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
4280 pBuf[0] = 4;
4281 pBuf[1] = 'v';
4282 pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
4283 pBuf[3] = '.';
4284 pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
4285 *pLen = 5;
4286 break;
4288 case OID_SKGE_CHIPSET:
4289 Val16 = pAC->Pnmi.Chipset;
4290 SK_PNMI_STORE_U16(pBuf, Val16);
4291 *pLen = sizeof(SK_U16);
4292 break;
4294 case OID_SKGE_BUS_TYPE:
4295 *pBuf = (char)SK_PNMI_BUS_PCI;
4296 *pLen = sizeof(char);
4297 break;
4299 case OID_SKGE_BUS_SPEED:
4300 *pBuf = pAC->Pnmi.PciBusSpeed;
4301 *pLen = sizeof(char);
4302 break;
4304 case OID_SKGE_BUS_WIDTH:
4305 *pBuf = pAC->Pnmi.PciBusWidth;
4306 *pLen = sizeof(char);
4307 break;
4309 case OID_SKGE_RESULT:
4310 Val32 = pAC->Pnmi.TestResult;
4311 SK_PNMI_STORE_U32(pBuf, Val32);
4312 *pLen = sizeof(SK_U32);
4313 break;
4315 case OID_SKGE_SENSOR_NUMBER:
4316 *pBuf = (char)pAC->I2c.MaxSens;
4317 *pLen = sizeof(char);
4318 break;
4320 case OID_SKGE_CHKSM_NUMBER:
4321 *pBuf = SKCS_NUM_PROTOCOLS;
4322 *pLen = sizeof(char);
4323 break;
4325 case OID_SKGE_TRAP_NUMBER:
4326 GetTrapQueueLen(pAC, &Len, &Val);
4327 Val32 = (SK_U32)Val;
4328 SK_PNMI_STORE_U32(pBuf, Val32);
4329 *pLen = sizeof(SK_U32);
4330 break;
4332 case OID_SKGE_TRAP:
4333 GetTrapQueueLen(pAC, &Len, &Val);
4334 if (*pLen < Len) {
4336 *pLen = Len;
4337 return (SK_PNMI_ERR_TOO_SHORT);
4339 CopyTrapQueue(pAC, pBuf);
4340 *pLen = Len;
4341 break;
4343 case OID_SKGE_RLMT_MONITOR_NUMBER:
4344 /* XXX Not yet implemented by RLMT therefore we return zero elements */
4345 Val32 = 0;
4346 SK_PNMI_STORE_U32(pBuf, Val32);
4347 *pLen = sizeof(SK_U32);
4348 break;
4350 case OID_SKGE_TX_SW_QUEUE_LEN:
4351 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4352 if (MacType == SK_MAC_XMAC) {
4353 /* Dual net mode */
4354 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4355 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
4357 /* Single net mode */
4358 else {
4359 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
4360 pAC->Pnmi.BufPort[1].TxSwQueueLen;
4363 else {
4364 /* Dual net mode */
4365 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4366 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
4368 /* Single net mode */
4369 else {
4370 Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
4371 pAC->Pnmi.Port[1].TxSwQueueLen;
4374 SK_PNMI_STORE_U64(pBuf, Val64);
4375 *pLen = sizeof(SK_U64);
4376 break;
4379 case OID_SKGE_TX_SW_QUEUE_MAX:
4380 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4381 if (MacType == SK_MAC_XMAC) {
4382 /* Dual net mode */
4383 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4384 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
4386 /* Single net mode */
4387 else {
4388 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
4389 pAC->Pnmi.BufPort[1].TxSwQueueMax;
4392 else {
4393 /* Dual net mode */
4394 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4395 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
4397 /* Single net mode */
4398 else {
4399 Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
4400 pAC->Pnmi.Port[1].TxSwQueueMax;
4403 SK_PNMI_STORE_U64(pBuf, Val64);
4404 *pLen = sizeof(SK_U64);
4405 break;
4407 case OID_SKGE_TX_RETRY:
4408 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4409 if (MacType == SK_MAC_XMAC) {
4410 /* Dual net mode */
4411 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4412 Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
4414 /* Single net mode */
4415 else {
4416 Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
4417 pAC->Pnmi.BufPort[1].TxRetryCts;
4420 else {
4421 /* Dual net mode */
4422 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4423 Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
4425 /* Single net mode */
4426 else {
4427 Val64 = pAC->Pnmi.Port[0].TxRetryCts +
4428 pAC->Pnmi.Port[1].TxRetryCts;
4431 SK_PNMI_STORE_U64(pBuf, Val64);
4432 *pLen = sizeof(SK_U64);
4433 break;
4435 case OID_SKGE_RX_INTR_CTS:
4436 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4437 if (MacType == SK_MAC_XMAC) {
4438 /* Dual net mode */
4439 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4440 Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
4442 /* Single net mode */
4443 else {
4444 Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
4445 pAC->Pnmi.BufPort[1].RxIntrCts;
4448 else {
4449 /* Dual net mode */
4450 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4451 Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
4453 /* Single net mode */
4454 else {
4455 Val64 = pAC->Pnmi.Port[0].RxIntrCts +
4456 pAC->Pnmi.Port[1].RxIntrCts;
4459 SK_PNMI_STORE_U64(pBuf, Val64);
4460 *pLen = sizeof(SK_U64);
4461 break;
4463 case OID_SKGE_TX_INTR_CTS:
4464 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4465 if (MacType == SK_MAC_XMAC) {
4466 /* Dual net mode */
4467 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4468 Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
4470 /* Single net mode */
4471 else {
4472 Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
4473 pAC->Pnmi.BufPort[1].TxIntrCts;
4476 else {
4477 /* Dual net mode */
4478 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4479 Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
4481 /* Single net mode */
4482 else {
4483 Val64 = pAC->Pnmi.Port[0].TxIntrCts +
4484 pAC->Pnmi.Port[1].TxIntrCts;
4487 SK_PNMI_STORE_U64(pBuf, Val64);
4488 *pLen = sizeof(SK_U64);
4489 break;
4491 case OID_SKGE_RX_NO_BUF_CTS:
4492 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4493 if (MacType == SK_MAC_XMAC) {
4494 /* Dual net mode */
4495 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4496 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4498 /* Single net mode */
4499 else {
4500 Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
4501 pAC->Pnmi.BufPort[1].RxNoBufCts;
4504 else {
4505 /* Dual net mode */
4506 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4507 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4509 /* Single net mode */
4510 else {
4511 Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
4512 pAC->Pnmi.Port[1].RxNoBufCts;
4515 SK_PNMI_STORE_U64(pBuf, Val64);
4516 *pLen = sizeof(SK_U64);
4517 break;
4519 case OID_SKGE_TX_NO_BUF_CTS:
4520 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4521 if (MacType == SK_MAC_XMAC) {
4522 /* Dual net mode */
4523 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4524 Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4526 /* Single net mode */
4527 else {
4528 Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
4529 pAC->Pnmi.BufPort[1].TxNoBufCts;
4532 else {
4533 /* Dual net mode */
4534 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4535 Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4537 /* Single net mode */
4538 else {
4539 Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
4540 pAC->Pnmi.Port[1].TxNoBufCts;
4543 SK_PNMI_STORE_U64(pBuf, Val64);
4544 *pLen = sizeof(SK_U64);
4545 break;
4547 case OID_SKGE_TX_USED_DESCR_NO:
4548 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4549 if (MacType == SK_MAC_XMAC) {
4550 /* Dual net mode */
4551 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4552 Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
4554 /* Single net mode */
4555 else {
4556 Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
4557 pAC->Pnmi.BufPort[1].TxUsedDescrNo;
4560 else {
4561 /* Dual net mode */
4562 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4563 Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
4565 /* Single net mode */
4566 else {
4567 Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
4568 pAC->Pnmi.Port[1].TxUsedDescrNo;
4571 SK_PNMI_STORE_U64(pBuf, Val64);
4572 *pLen = sizeof(SK_U64);
4573 break;
4575 case OID_SKGE_RX_DELIVERED_CTS:
4576 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4577 if (MacType == SK_MAC_XMAC) {
4578 /* Dual net mode */
4579 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4580 Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
4582 /* Single net mode */
4583 else {
4584 Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
4585 pAC->Pnmi.BufPort[1].RxDeliveredCts;
4588 else {
4589 /* Dual net mode */
4590 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4591 Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
4593 /* Single net mode */
4594 else {
4595 Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
4596 pAC->Pnmi.Port[1].RxDeliveredCts;
4599 SK_PNMI_STORE_U64(pBuf, Val64);
4600 *pLen = sizeof(SK_U64);
4601 break;
4603 case OID_SKGE_RX_OCTETS_DELIV_CTS:
4604 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4605 if (MacType == SK_MAC_XMAC) {
4606 /* Dual net mode */
4607 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4608 Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
4610 /* Single net mode */
4611 else {
4612 Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
4613 pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
4616 else {
4617 /* Dual net mode */
4618 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4619 Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
4621 /* Single net mode */
4622 else {
4623 Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
4624 pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
4627 SK_PNMI_STORE_U64(pBuf, Val64);
4628 *pLen = sizeof(SK_U64);
4629 break;
4631 case OID_SKGE_RX_HW_ERROR_CTS:
4632 SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
4633 *pLen = sizeof(SK_U64);
4634 break;
4636 case OID_SKGE_TX_HW_ERROR_CTS:
4637 SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
4638 *pLen = sizeof(SK_U64);
4639 break;
4641 case OID_SKGE_IN_ERRORS_CTS:
4642 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4643 if (MacType == SK_MAC_XMAC) {
4644 /* Dual net mode */
4645 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4646 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4648 /* Single net mode */
4649 else {
4650 Val64 = Val64RxHwErrs +
4651 pAC->Pnmi.BufPort[0].RxNoBufCts +
4652 pAC->Pnmi.BufPort[1].RxNoBufCts;
4655 else {
4656 /* Dual net mode */
4657 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4658 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4660 /* Single net mode */
4661 else {
4662 Val64 = Val64RxHwErrs +
4663 pAC->Pnmi.Port[0].RxNoBufCts +
4664 pAC->Pnmi.Port[1].RxNoBufCts;
4667 SK_PNMI_STORE_U64(pBuf, Val64);
4668 *pLen = sizeof(SK_U64);
4669 break;
4671 case OID_SKGE_OUT_ERROR_CTS:
4672 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4673 if (MacType == SK_MAC_XMAC) {
4674 /* Dual net mode */
4675 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4676 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4678 /* Single net mode */
4679 else {
4680 Val64 = Val64TxHwErrs +
4681 pAC->Pnmi.BufPort[0].TxNoBufCts +
4682 pAC->Pnmi.BufPort[1].TxNoBufCts;
4685 else {
4686 /* Dual net mode */
4687 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4688 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4690 /* Single net mode */
4691 else {
4692 Val64 = Val64TxHwErrs +
4693 pAC->Pnmi.Port[0].TxNoBufCts +
4694 pAC->Pnmi.Port[1].TxNoBufCts;
4697 SK_PNMI_STORE_U64(pBuf, Val64);
4698 *pLen = sizeof(SK_U64);
4699 break;
4701 case OID_SKGE_ERR_RECOVERY_CTS:
4702 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4703 if (MacType == SK_MAC_XMAC) {
4704 /* Dual net mode */
4705 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4706 Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
4708 /* Single net mode */
4709 else {
4710 Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
4711 pAC->Pnmi.BufPort[1].ErrRecoveryCts;
4714 else {
4715 /* Dual net mode */
4716 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4717 Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
4719 /* Single net mode */
4720 else {
4721 Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
4722 pAC->Pnmi.Port[1].ErrRecoveryCts;
4725 SK_PNMI_STORE_U64(pBuf, Val64);
4726 *pLen = sizeof(SK_U64);
4727 break;
4729 case OID_SKGE_SYSUPTIME:
4730 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
4731 Val64 -= pAC->Pnmi.StartUpTime;
4732 SK_PNMI_STORE_U64(pBuf, Val64);
4733 *pLen = sizeof(SK_U64);
4734 break;
4736 case OID_SKGE_MDB_VERSION:
4737 Val32 = SK_PNMI_MDB_VERSION;
4738 SK_PNMI_STORE_U32(pBuf, Val32);
4739 *pLen = sizeof(SK_U32);
4740 break;
4742 case OID_GEN_RCV_ERROR:
4743 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4744 if (MacType == SK_MAC_XMAC) {
4745 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4747 else {
4748 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4752 * by default 32bit values are evaluated
4754 if (!Is64BitReq) {
4755 Val32 = (SK_U32)Val64;
4756 SK_PNMI_STORE_U32(pBuf, Val32);
4757 *pLen = sizeof(SK_U32);
4759 else {
4760 SK_PNMI_STORE_U64(pBuf, Val64);
4761 *pLen = sizeof(SK_U64);
4763 break;
4765 case OID_GEN_XMIT_ERROR:
4766 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4767 if (MacType == SK_MAC_XMAC) {
4768 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4770 else {
4771 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4775 * by default 32bit values are evaluated
4777 if (!Is64BitReq) {
4778 Val32 = (SK_U32)Val64;
4779 SK_PNMI_STORE_U32(pBuf, Val32);
4780 *pLen = sizeof(SK_U32);
4782 else {
4783 SK_PNMI_STORE_U64(pBuf, Val64);
4784 *pLen = sizeof(SK_U64);
4786 break;
4788 case OID_GEN_RCV_NO_BUFFER:
4789 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4790 if (MacType == SK_MAC_XMAC) {
4791 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4793 else {
4794 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4798 * by default 32bit values are evaluated
4800 if (!Is64BitReq) {
4801 Val32 = (SK_U32)Val64;
4802 SK_PNMI_STORE_U32(pBuf, Val32);
4803 *pLen = sizeof(SK_U32);
4805 else {
4806 SK_PNMI_STORE_U64(pBuf, Val64);
4807 *pLen = sizeof(SK_U64);
4809 break;
4811 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
4812 Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
4813 SK_PNMI_STORE_U32(pBuf, Val32);
4814 *pLen = sizeof(SK_U32);
4815 break;
4817 default:
4818 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
4819 SK_PNMI_ERR034MSG);
4821 *pLen = 0;
4822 return (SK_PNMI_ERR_GENERAL);
4825 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
4826 Id == OID_SKGE_TX_HW_ERROR_CTS ||
4827 Id == OID_SKGE_IN_ERRORS_CTS ||
4828 Id == OID_SKGE_OUT_ERROR_CTS ||
4829 Id == OID_GEN_XMIT_ERROR ||
4830 Id == OID_GEN_RCV_ERROR) {
4832 pAC->Pnmi.MacUpdatedFlag --;
4835 return (SK_PNMI_ERR_OK);
4838 /*****************************************************************************
4840 * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
4842 * Description:
4843 * Get/Presets/Sets the RLMT OIDs.
4845 * Returns:
4846 * SK_PNMI_ERR_OK The request was successfully performed.
4847 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4848 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4849 * the correct data (e.g. a 32bit value is
4850 * needed, but a 16 bit value was passed).
4851 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
4852 * value range.
4853 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
4854 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4855 * exist (e.g. port instance 3 on a two port
4856 * adapter.
4858 PNMI_STATIC int Rlmt(
4859 SK_AC *pAC, /* Pointer to adapter context */
4860 SK_IOC IoC, /* IO context handle */
4861 int Action, /* GET/PRESET/SET action */
4862 SK_U32 Id, /* Object ID that is to be processed */
4863 char *pBuf, /* Buffer used for the management data transfer */
4864 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4865 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4866 unsigned int TableIndex, /* Index to the Id table */
4867 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
4869 int Ret;
4870 unsigned int PhysPortIndex;
4871 unsigned int PhysPortMax;
4872 SK_EVPARA EventParam;
4873 SK_U32 Val32;
4874 SK_U64 Val64;
4878 * Check instance. Only single instance OIDs are allowed here.
4880 if (Instance != (SK_U32)(-1) && Instance != 1) {
4882 *pLen = 0;
4883 return (SK_PNMI_ERR_UNKNOWN_INST);
4887 * Perform the requested action.
4889 if (Action == SK_PNMI_GET) {
4892 * Check if the buffer length is large enough.
4895 switch (Id) {
4897 case OID_SKGE_RLMT_MODE:
4898 case OID_SKGE_RLMT_PORT_ACTIVE:
4899 case OID_SKGE_RLMT_PORT_PREFERRED:
4900 if (*pLen < sizeof(SK_U8)) {
4902 *pLen = sizeof(SK_U8);
4903 return (SK_PNMI_ERR_TOO_SHORT);
4905 break;
4907 case OID_SKGE_RLMT_PORT_NUMBER:
4908 if (*pLen < sizeof(SK_U32)) {
4910 *pLen = sizeof(SK_U32);
4911 return (SK_PNMI_ERR_TOO_SHORT);
4913 break;
4915 case OID_SKGE_RLMT_CHANGE_CTS:
4916 case OID_SKGE_RLMT_CHANGE_TIME:
4917 case OID_SKGE_RLMT_CHANGE_ESTIM:
4918 case OID_SKGE_RLMT_CHANGE_THRES:
4919 if (*pLen < sizeof(SK_U64)) {
4921 *pLen = sizeof(SK_U64);
4922 return (SK_PNMI_ERR_TOO_SHORT);
4924 break;
4926 default:
4927 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
4928 SK_PNMI_ERR035MSG);
4930 *pLen = 0;
4931 return (SK_PNMI_ERR_GENERAL);
4935 * Update RLMT statistic and increment semaphores to indicate
4936 * that an update was already done. Maybe RLMT will hold its
4937 * statistic always up to date some time. Then we can
4938 * remove this type of call.
4940 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4942 *pLen = 0;
4943 return (Ret);
4945 pAC->Pnmi.RlmtUpdatedFlag ++;
4948 * Retrieve Value
4950 switch (Id) {
4952 case OID_SKGE_RLMT_MODE:
4953 *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
4954 *pLen = sizeof(char);
4955 break;
4957 case OID_SKGE_RLMT_PORT_NUMBER:
4958 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
4959 SK_PNMI_STORE_U32(pBuf, Val32);
4960 *pLen = sizeof(SK_U32);
4961 break;
4963 case OID_SKGE_RLMT_PORT_ACTIVE:
4964 *pBuf = 0;
4966 * If multiple ports may become active this OID
4967 * doesn't make sense any more. A new variable in
4968 * the port structure should be created. However,
4969 * for this variable the first active port is
4970 * returned.
4972 PhysPortMax = pAC->GIni.GIMacsFound;
4974 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
4975 PhysPortIndex ++) {
4977 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4979 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
4980 break;
4983 *pLen = sizeof(char);
4984 break;
4986 case OID_SKGE_RLMT_PORT_PREFERRED:
4987 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
4988 *pLen = sizeof(char);
4989 break;
4991 case OID_SKGE_RLMT_CHANGE_CTS:
4992 Val64 = pAC->Pnmi.RlmtChangeCts;
4993 SK_PNMI_STORE_U64(pBuf, Val64);
4994 *pLen = sizeof(SK_U64);
4995 break;
4997 case OID_SKGE_RLMT_CHANGE_TIME:
4998 Val64 = pAC->Pnmi.RlmtChangeTime;
4999 SK_PNMI_STORE_U64(pBuf, Val64);
5000 *pLen = sizeof(SK_U64);
5001 break;
5003 case OID_SKGE_RLMT_CHANGE_ESTIM:
5004 Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
5005 SK_PNMI_STORE_U64(pBuf, Val64);
5006 *pLen = sizeof(SK_U64);
5007 break;
5009 case OID_SKGE_RLMT_CHANGE_THRES:
5010 Val64 = pAC->Pnmi.RlmtChangeThreshold;
5011 SK_PNMI_STORE_U64(pBuf, Val64);
5012 *pLen = sizeof(SK_U64);
5013 break;
5015 default:
5016 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5017 ("Rlmt: Unknown OID should be handled before"));
5019 pAC->Pnmi.RlmtUpdatedFlag --;
5020 *pLen = 0;
5021 return (SK_PNMI_ERR_GENERAL);
5024 pAC->Pnmi.RlmtUpdatedFlag --;
5026 else {
5027 /* Perform a preset or set */
5028 switch (Id) {
5030 case OID_SKGE_RLMT_MODE:
5031 /* Check if the buffer length is plausible */
5032 if (*pLen < sizeof(char)) {
5034 *pLen = sizeof(char);
5035 return (SK_PNMI_ERR_TOO_SHORT);
5037 /* Check if the value range is correct */
5038 if (*pLen != sizeof(char) ||
5039 (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
5040 *(SK_U8 *)pBuf > 15) {
5042 *pLen = 0;
5043 return (SK_PNMI_ERR_BAD_VALUE);
5045 /* The preset ends here */
5046 if (Action == SK_PNMI_PRESET) {
5048 *pLen = 0;
5049 return (SK_PNMI_ERR_OK);
5051 /* Send an event to RLMT to change the mode */
5052 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
5053 EventParam.Para32[0] |= (SK_U32)(*pBuf);
5054 EventParam.Para32[1] = 0;
5055 if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
5056 EventParam) > 0) {
5058 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
5059 SK_PNMI_ERR037MSG);
5061 *pLen = 0;
5062 return (SK_PNMI_ERR_GENERAL);
5064 break;
5066 case OID_SKGE_RLMT_PORT_PREFERRED:
5067 /* Check if the buffer length is plausible */
5068 if (*pLen < sizeof(char)) {
5070 *pLen = sizeof(char);
5071 return (SK_PNMI_ERR_TOO_SHORT);
5073 /* Check if the value range is correct */
5074 if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
5075 (SK_U8)pAC->GIni.GIMacsFound) {
5077 *pLen = 0;
5078 return (SK_PNMI_ERR_BAD_VALUE);
5080 /* The preset ends here */
5081 if (Action == SK_PNMI_PRESET) {
5083 *pLen = 0;
5084 return (SK_PNMI_ERR_OK);
5088 * Send an event to RLMT change the preferred port.
5089 * A param of -1 means automatic mode. RLMT will
5090 * make the decision which is the preferred port.
5092 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
5093 EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
5094 EventParam.Para32[1] = NetIndex;
5095 if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
5096 EventParam) > 0) {
5098 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
5099 SK_PNMI_ERR038MSG);
5101 *pLen = 0;
5102 return (SK_PNMI_ERR_GENERAL);
5104 break;
5106 case OID_SKGE_RLMT_CHANGE_THRES:
5107 /* Check if the buffer length is plausible */
5108 if (*pLen < sizeof(SK_U64)) {
5110 *pLen = sizeof(SK_U64);
5111 return (SK_PNMI_ERR_TOO_SHORT);
5114 * There are not many restrictions to the
5115 * value range.
5117 if (*pLen != sizeof(SK_U64)) {
5119 *pLen = 0;
5120 return (SK_PNMI_ERR_BAD_VALUE);
5122 /* A preset ends here */
5123 if (Action == SK_PNMI_PRESET) {
5125 *pLen = 0;
5126 return (SK_PNMI_ERR_OK);
5129 * Store the new threshold, which will be taken
5130 * on the next timer event.
5132 SK_PNMI_READ_U64(pBuf, Val64);
5133 pAC->Pnmi.RlmtChangeThreshold = Val64;
5134 break;
5136 default:
5137 /* The other OIDs are not be able for set */
5138 *pLen = 0;
5139 return (SK_PNMI_ERR_READ_ONLY);
5143 return (SK_PNMI_ERR_OK);
5146 /*****************************************************************************
5148 * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
5150 * Description:
5151 * Performs get requests on multiple instance variables.
5153 * Returns:
5154 * SK_PNMI_ERR_OK The request was successfully performed.
5155 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
5156 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
5157 * the correct data (e.g. a 32bit value is
5158 * needed, but a 16 bit value was passed).
5159 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
5160 * exist (e.g. port instance 3 on a two port
5161 * adapter.
5163 PNMI_STATIC int RlmtStat(
5164 SK_AC *pAC, /* Pointer to adapter context */
5165 SK_IOC IoC, /* IO context handle */
5166 int Action, /* GET/PRESET/SET action */
5167 SK_U32 Id, /* Object ID that is to be processed */
5168 char *pBuf, /* Buffer used for the management data transfer */
5169 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
5170 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5171 unsigned int TableIndex, /* Index to the Id table */
5172 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
5174 unsigned int PhysPortMax;
5175 unsigned int PhysPortIndex;
5176 unsigned int Limit;
5177 unsigned int Offset;
5178 int Ret;
5179 SK_U32 Val32;
5180 SK_U64 Val64;
5183 * Calculate the port indexes from the instance.
5185 PhysPortMax = pAC->GIni.GIMacsFound;
5187 if ((Instance != (SK_U32)(-1))) {
5188 /* Check instance range */
5189 if ((Instance < 1) || (Instance > PhysPortMax)) {
5191 *pLen = 0;
5192 return (SK_PNMI_ERR_UNKNOWN_INST);
5195 /* Single net mode */
5196 PhysPortIndex = Instance - 1;
5198 /* Dual net mode */
5199 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
5200 PhysPortIndex = NetIndex;
5203 /* Both net modes */
5204 Limit = PhysPortIndex + 1;
5206 else {
5207 /* Single net mode */
5208 PhysPortIndex = 0;
5209 Limit = PhysPortMax;
5211 /* Dual net mode */
5212 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
5213 PhysPortIndex = NetIndex;
5214 Limit = PhysPortIndex + 1;
5219 * Currently only get requests are allowed.
5221 if (Action != SK_PNMI_GET) {
5223 *pLen = 0;
5224 return (SK_PNMI_ERR_READ_ONLY);
5228 * Check if the buffer length is large enough.
5230 switch (Id) {
5232 case OID_SKGE_RLMT_PORT_INDEX:
5233 case OID_SKGE_RLMT_STATUS:
5234 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
5236 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
5237 return (SK_PNMI_ERR_TOO_SHORT);
5239 break;
5241 case OID_SKGE_RLMT_TX_HELLO_CTS:
5242 case OID_SKGE_RLMT_RX_HELLO_CTS:
5243 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
5244 case OID_SKGE_RLMT_RX_SP_CTS:
5245 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
5247 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
5248 return (SK_PNMI_ERR_TOO_SHORT);
5250 break;
5252 default:
5253 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
5254 SK_PNMI_ERR039MSG);
5256 *pLen = 0;
5257 return (SK_PNMI_ERR_GENERAL);
5262 * Update statistic and increment semaphores to indicate that
5263 * an update was already done.
5265 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
5267 *pLen = 0;
5268 return (Ret);
5270 pAC->Pnmi.RlmtUpdatedFlag ++;
5273 * Get value
5275 Offset = 0;
5276 for (; PhysPortIndex < Limit; PhysPortIndex ++) {
5278 switch (Id) {
5280 case OID_SKGE_RLMT_PORT_INDEX:
5281 Val32 = PhysPortIndex;
5282 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
5283 Offset += sizeof(SK_U32);
5284 break;
5286 case OID_SKGE_RLMT_STATUS:
5287 if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
5288 SK_RLMT_PS_INIT ||
5289 pAC->Rlmt.Port[PhysPortIndex].PortState ==
5290 SK_RLMT_PS_DOWN) {
5292 Val32 = SK_PNMI_RLMT_STATUS_ERROR;
5294 else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
5296 Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
5298 else {
5299 Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
5301 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
5302 Offset += sizeof(SK_U32);
5303 break;
5305 case OID_SKGE_RLMT_TX_HELLO_CTS:
5306 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
5307 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5308 Offset += sizeof(SK_U64);
5309 break;
5311 case OID_SKGE_RLMT_RX_HELLO_CTS:
5312 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
5313 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5314 Offset += sizeof(SK_U64);
5315 break;
5317 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
5318 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
5319 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5320 Offset += sizeof(SK_U64);
5321 break;
5323 case OID_SKGE_RLMT_RX_SP_CTS:
5324 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
5325 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5326 Offset += sizeof(SK_U64);
5327 break;
5329 default:
5330 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5331 ("RlmtStat: Unknown OID should be errored before"));
5333 pAC->Pnmi.RlmtUpdatedFlag --;
5334 *pLen = 0;
5335 return (SK_PNMI_ERR_GENERAL);
5338 *pLen = Offset;
5340 pAC->Pnmi.RlmtUpdatedFlag --;
5342 return (SK_PNMI_ERR_OK);
5345 /*****************************************************************************
5347 * MacPrivateConf - OID handler function of OIDs concerning the configuration
5349 * Description:
5350 * Get/Presets/Sets the OIDs concerning the configuration.
5352 * Returns:
5353 * SK_PNMI_ERR_OK The request was successfully performed.
5354 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
5355 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
5356 * the correct data (e.g. a 32bit value is
5357 * needed, but a 16 bit value was passed).
5358 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
5359 * value range.
5360 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
5361 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
5362 * exist (e.g. port instance 3 on a two port
5363 * adapter.
5365 PNMI_STATIC int MacPrivateConf(
5366 SK_AC *pAC, /* Pointer to adapter context */
5367 SK_IOC IoC, /* IO context handle */
5368 int Action, /* GET/PRESET/SET action */
5369 SK_U32 Id, /* Object ID that is to be processed */
5370 char *pBuf, /* Buffer used for the management data transfer */
5371 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
5372 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5373 unsigned int TableIndex, /* Index to the Id table */
5374 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
5376 unsigned int PhysPortMax;
5377 unsigned int PhysPortIndex;
5378 unsigned int LogPortMax;
5379 unsigned int LogPortIndex;
5380 unsigned int Limit;
5381 unsigned int Offset;
5382 char Val8;
5383 char *pBufPtr;
5384 int Ret;
5385 SK_EVPARA EventParam;
5386 SK_U32 Val32;
5389 * Calculate instance if wished. MAC index 0 is the virtual MAC.
5391 PhysPortMax = pAC->GIni.GIMacsFound;
5392 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
5394 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
5395 LogPortMax--;
5398 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
5399 /* Check instance range */
5400 if ((Instance < 1) || (Instance > LogPortMax)) {
5402 *pLen = 0;
5403 return (SK_PNMI_ERR_UNKNOWN_INST);
5405 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
5406 Limit = LogPortIndex + 1;
5409 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
5411 LogPortIndex = 0;
5412 Limit = LogPortMax;
5416 * Perform action
5418 if (Action == SK_PNMI_GET) {
5420 /* Check length */
5421 switch (Id) {
5423 case OID_SKGE_PMD:
5424 case OID_SKGE_CONNECTOR:
5425 case OID_SKGE_LINK_CAP:
5426 case OID_SKGE_LINK_MODE:
5427 case OID_SKGE_LINK_MODE_STATUS:
5428 case OID_SKGE_LINK_STATUS:
5429 case OID_SKGE_FLOWCTRL_CAP:
5430 case OID_SKGE_FLOWCTRL_MODE:
5431 case OID_SKGE_FLOWCTRL_STATUS:
5432 case OID_SKGE_PHY_OPERATION_CAP:
5433 case OID_SKGE_PHY_OPERATION_MODE:
5434 case OID_SKGE_PHY_OPERATION_STATUS:
5435 case OID_SKGE_SPEED_CAP:
5436 case OID_SKGE_SPEED_MODE:
5437 case OID_SKGE_SPEED_STATUS:
5438 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
5440 *pLen = (Limit - LogPortIndex) * sizeof(SK_U8);
5441 return (SK_PNMI_ERR_TOO_SHORT);
5443 break;
5445 case OID_SKGE_MTU:
5446 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) {
5448 *pLen = (Limit - LogPortIndex) * sizeof(SK_U32);
5449 return (SK_PNMI_ERR_TOO_SHORT);
5451 break;
5453 default:
5454 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
5455 SK_PNMI_ERR041MSG);
5456 *pLen = 0;
5457 return (SK_PNMI_ERR_GENERAL);
5461 * Update statistic and increment semaphore to indicate
5462 * that an update was already done.
5464 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
5466 *pLen = 0;
5467 return (Ret);
5469 pAC->Pnmi.SirqUpdatedFlag ++;
5472 * Get value
5474 Offset = 0;
5475 for (; LogPortIndex < Limit; LogPortIndex ++) {
5477 pBufPtr = pBuf + Offset;
5479 switch (Id) {
5481 case OID_SKGE_PMD:
5482 *pBufPtr = pAC->Pnmi.PMD;
5483 Offset += sizeof(char);
5484 break;
5486 case OID_SKGE_CONNECTOR:
5487 *pBufPtr = pAC->Pnmi.Connector;
5488 Offset += sizeof(char);
5489 break;
5491 case OID_SKGE_LINK_CAP:
5492 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5493 if (LogPortIndex == 0) {
5494 /* Get value for virtual port */
5495 VirtualConf(pAC, IoC, Id, pBufPtr);
5497 else {
5498 /* Get value for physical ports */
5499 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5500 pAC, LogPortIndex);
5502 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkCap;
5505 else { /* DualNetMode */
5507 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap;
5509 Offset += sizeof(char);
5510 break;
5512 case OID_SKGE_LINK_MODE:
5513 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5514 if (LogPortIndex == 0) {
5515 /* Get value for virtual port */
5516 VirtualConf(pAC, IoC, Id, pBufPtr);
5518 else {
5519 /* Get value for physical ports */
5520 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5521 pAC, LogPortIndex);
5523 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
5526 else { /* DualNetMode */
5528 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf;
5530 Offset += sizeof(char);
5531 break;
5533 case OID_SKGE_LINK_MODE_STATUS:
5534 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5535 if (LogPortIndex == 0) {
5536 /* Get value for virtual port */
5537 VirtualConf(pAC, IoC, Id, pBufPtr);
5539 else {
5540 /* Get value for physical port */
5541 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5542 pAC, LogPortIndex);
5544 *pBufPtr =
5545 CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
5548 else { /* DualNetMode */
5550 *pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex);
5552 Offset += sizeof(char);
5553 break;
5555 case OID_SKGE_LINK_STATUS:
5556 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5557 if (LogPortIndex == 0) {
5558 /* Get value for virtual port */
5559 VirtualConf(pAC, IoC, Id, pBufPtr);
5561 else {
5562 /* Get value for physical ports */
5563 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5564 pAC, LogPortIndex);
5566 *pBufPtr = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
5569 else { /* DualNetMode */
5571 *pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex);
5573 Offset += sizeof(char);
5574 break;
5576 case OID_SKGE_FLOWCTRL_CAP:
5577 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5578 if (LogPortIndex == 0) {
5579 /* Get value for virtual port */
5580 VirtualConf(pAC, IoC, Id, pBufPtr);
5582 else {
5583 /* Get value for physical ports */
5584 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5585 pAC, LogPortIndex);
5587 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
5590 else { /* DualNetMode */
5592 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
5594 Offset += sizeof(char);
5595 break;
5597 case OID_SKGE_FLOWCTRL_MODE:
5598 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5599 if (LogPortIndex == 0) {
5600 /* Get value for virtual port */
5601 VirtualConf(pAC, IoC, Id, pBufPtr);
5603 else {
5604 /* Get value for physical port */
5605 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5606 pAC, LogPortIndex);
5608 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
5611 else { /* DualNetMode */
5613 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
5615 Offset += sizeof(char);
5616 break;
5618 case OID_SKGE_FLOWCTRL_STATUS:
5619 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5620 if (LogPortIndex == 0) {
5621 /* Get value for virtual port */
5622 VirtualConf(pAC, IoC, Id, pBufPtr);
5624 else {
5625 /* Get value for physical port */
5626 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5627 pAC, LogPortIndex);
5629 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
5632 else { /* DualNetMode */
5634 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
5636 Offset += sizeof(char);
5637 break;
5639 case OID_SKGE_PHY_OPERATION_CAP:
5640 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5641 if (LogPortIndex == 0) {
5642 /* Get value for virtual port */
5643 VirtualConf(pAC, IoC, Id, pBufPtr);
5645 else {
5646 /* Get value for physical ports */
5647 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5648 pAC, LogPortIndex);
5650 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSCap;
5653 else { /* DualNetMode */
5655 *pBufPtr = pAC->GIni.GP[NetIndex].PMSCap;
5657 Offset += sizeof(char);
5658 break;
5660 case OID_SKGE_PHY_OPERATION_MODE:
5661 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5662 if (LogPortIndex == 0) {
5663 /* Get value for virtual port */
5664 VirtualConf(pAC, IoC, Id, pBufPtr);
5666 else {
5667 /* Get value for physical port */
5668 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5669 pAC, LogPortIndex);
5671 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSMode;
5674 else { /* DualNetMode */
5676 *pBufPtr = pAC->GIni.GP[NetIndex].PMSMode;
5678 Offset += sizeof(char);
5679 break;
5681 case OID_SKGE_PHY_OPERATION_STATUS:
5682 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5683 if (LogPortIndex == 0) {
5684 /* Get value for virtual port */
5685 VirtualConf(pAC, IoC, Id, pBufPtr);
5687 else {
5688 /* Get value for physical port */
5689 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5690 pAC, LogPortIndex);
5692 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSStatus;
5695 else {
5697 *pBufPtr = pAC->GIni.GP[NetIndex].PMSStatus;
5699 Offset += sizeof(char);
5700 break;
5702 case OID_SKGE_SPEED_CAP:
5703 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5704 if (LogPortIndex == 0) {
5705 /* Get value for virtual port */
5706 VirtualConf(pAC, IoC, Id, pBufPtr);
5708 else {
5709 /* Get value for physical ports */
5710 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5711 pAC, LogPortIndex);
5713 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedCap;
5716 else { /* DualNetMode */
5718 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
5720 Offset += sizeof(char);
5721 break;
5723 case OID_SKGE_SPEED_MODE:
5724 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5725 if (LogPortIndex == 0) {
5726 /* Get value for virtual port */
5727 VirtualConf(pAC, IoC, Id, pBufPtr);
5729 else {
5730 /* Get value for physical port */
5731 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5732 pAC, LogPortIndex);
5734 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
5737 else { /* DualNetMode */
5739 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed;
5741 Offset += sizeof(char);
5742 break;
5744 case OID_SKGE_SPEED_STATUS:
5745 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5746 if (LogPortIndex == 0) {
5747 /* Get value for virtual port */
5748 VirtualConf(pAC, IoC, Id, pBufPtr);
5750 else {
5751 /* Get value for physical port */
5752 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5753 pAC, LogPortIndex);
5755 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
5758 else { /* DualNetMode */
5760 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
5762 Offset += sizeof(char);
5763 break;
5765 case OID_SKGE_MTU:
5766 Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
5767 SK_PNMI_STORE_U32(pBufPtr, Val32);
5768 Offset += sizeof(SK_U32);
5769 break;
5771 default:
5772 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5773 ("MacPrivateConf: Unknown OID should be handled before"));
5775 pAC->Pnmi.SirqUpdatedFlag --;
5776 return (SK_PNMI_ERR_GENERAL);
5779 *pLen = Offset;
5780 pAC->Pnmi.SirqUpdatedFlag --;
5782 return (SK_PNMI_ERR_OK);
5786 * From here SET or PRESET action. Check if the passed
5787 * buffer length is plausible.
5789 switch (Id) {
5791 case OID_SKGE_LINK_MODE:
5792 case OID_SKGE_FLOWCTRL_MODE:
5793 case OID_SKGE_PHY_OPERATION_MODE:
5794 case OID_SKGE_SPEED_MODE:
5795 if (*pLen < Limit - LogPortIndex) {
5797 *pLen = Limit - LogPortIndex;
5798 return (SK_PNMI_ERR_TOO_SHORT);
5800 if (*pLen != Limit - LogPortIndex) {
5802 *pLen = 0;
5803 return (SK_PNMI_ERR_BAD_VALUE);
5805 break;
5807 case OID_SKGE_MTU:
5808 if (*pLen < sizeof(SK_U32)) {
5810 *pLen = sizeof(SK_U32);
5811 return (SK_PNMI_ERR_TOO_SHORT);
5813 if (*pLen != sizeof(SK_U32)) {
5815 *pLen = 0;
5816 return (SK_PNMI_ERR_BAD_VALUE);
5818 break;
5820 default:
5821 *pLen = 0;
5822 return (SK_PNMI_ERR_READ_ONLY);
5826 * Perform preset or set
5828 Offset = 0;
5829 for (; LogPortIndex < Limit; LogPortIndex ++) {
5831 switch (Id) {
5833 case OID_SKGE_LINK_MODE:
5834 /* Check the value range */
5835 Val8 = *(pBuf + Offset);
5836 if (Val8 == 0) {
5838 Offset += sizeof(char);
5839 break;
5841 if (Val8 < SK_LMODE_HALF ||
5842 (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
5843 (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
5845 *pLen = 0;
5846 return (SK_PNMI_ERR_BAD_VALUE);
5849 /* The preset ends here */
5850 if (Action == SK_PNMI_PRESET) {
5852 return (SK_PNMI_ERR_OK);
5855 if (LogPortIndex == 0) {
5858 * The virtual port consists of all currently
5859 * active ports. Find them and send an event
5860 * with the new link mode to SIRQ.
5862 for (PhysPortIndex = 0;
5863 PhysPortIndex < PhysPortMax;
5864 PhysPortIndex ++) {
5866 if (!pAC->Pnmi.Port[PhysPortIndex].
5867 ActiveFlag) {
5869 continue;
5872 EventParam.Para32[0] = PhysPortIndex;
5873 EventParam.Para32[1] = (SK_U32)Val8;
5874 if (SkGeSirqEvent(pAC, IoC,
5875 SK_HWEV_SET_LMODE,
5876 EventParam) > 0) {
5878 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5879 SK_PNMI_ERR043,
5880 SK_PNMI_ERR043MSG);
5882 *pLen = 0;
5883 return (SK_PNMI_ERR_GENERAL);
5887 else {
5889 * Send an event with the new link mode to
5890 * the SIRQ module.
5892 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5893 pAC, LogPortIndex);
5894 EventParam.Para32[1] = (SK_U32)Val8;
5895 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
5896 EventParam) > 0) {
5898 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5899 SK_PNMI_ERR043,
5900 SK_PNMI_ERR043MSG);
5902 *pLen = 0;
5903 return (SK_PNMI_ERR_GENERAL);
5906 Offset += sizeof(char);
5907 break;
5909 case OID_SKGE_FLOWCTRL_MODE:
5910 /* Check the value range */
5911 Val8 = *(pBuf + Offset);
5912 if (Val8 == 0) {
5914 Offset += sizeof(char);
5915 break;
5917 if (Val8 < SK_FLOW_MODE_NONE ||
5918 (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
5919 (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
5921 *pLen = 0;
5922 return (SK_PNMI_ERR_BAD_VALUE);
5925 /* The preset ends here */
5926 if (Action == SK_PNMI_PRESET) {
5928 return (SK_PNMI_ERR_OK);
5931 if (LogPortIndex == 0) {
5934 * The virtual port consists of all currently
5935 * active ports. Find them and send an event
5936 * with the new flow control mode to SIRQ.
5938 for (PhysPortIndex = 0;
5939 PhysPortIndex < PhysPortMax;
5940 PhysPortIndex ++) {
5942 if (!pAC->Pnmi.Port[PhysPortIndex].
5943 ActiveFlag) {
5945 continue;
5948 EventParam.Para32[0] = PhysPortIndex;
5949 EventParam.Para32[1] = (SK_U32)Val8;
5950 if (SkGeSirqEvent(pAC, IoC,
5951 SK_HWEV_SET_FLOWMODE,
5952 EventParam) > 0) {
5954 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5955 SK_PNMI_ERR044,
5956 SK_PNMI_ERR044MSG);
5958 *pLen = 0;
5959 return (SK_PNMI_ERR_GENERAL);
5963 else {
5965 * Send an event with the new flow control
5966 * mode to the SIRQ module.
5968 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5969 pAC, LogPortIndex);
5970 EventParam.Para32[1] = (SK_U32)Val8;
5971 if (SkGeSirqEvent(pAC, IoC,
5972 SK_HWEV_SET_FLOWMODE, EventParam)
5973 > 0) {
5975 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5976 SK_PNMI_ERR044,
5977 SK_PNMI_ERR044MSG);
5979 *pLen = 0;
5980 return (SK_PNMI_ERR_GENERAL);
5983 Offset += sizeof(char);
5984 break;
5986 case OID_SKGE_PHY_OPERATION_MODE :
5987 /* Check the value range */
5988 Val8 = *(pBuf + Offset);
5989 if (Val8 == 0) {
5990 /* mode of this port remains unchanged */
5991 Offset += sizeof(char);
5992 break;
5994 if (Val8 < SK_MS_MODE_AUTO ||
5995 (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
5996 (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
5998 *pLen = 0;
5999 return (SK_PNMI_ERR_BAD_VALUE);
6002 /* The preset ends here */
6003 if (Action == SK_PNMI_PRESET) {
6005 return (SK_PNMI_ERR_OK);
6008 if (LogPortIndex == 0) {
6011 * The virtual port consists of all currently
6012 * active ports. Find them and send an event
6013 * with new master/slave (role) mode to SIRQ.
6015 for (PhysPortIndex = 0;
6016 PhysPortIndex < PhysPortMax;
6017 PhysPortIndex ++) {
6019 if (!pAC->Pnmi.Port[PhysPortIndex].
6020 ActiveFlag) {
6022 continue;
6025 EventParam.Para32[0] = PhysPortIndex;
6026 EventParam.Para32[1] = (SK_U32)Val8;
6027 if (SkGeSirqEvent(pAC, IoC,
6028 SK_HWEV_SET_ROLE,
6029 EventParam) > 0) {
6031 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6032 SK_PNMI_ERR042,
6033 SK_PNMI_ERR042MSG);
6035 *pLen = 0;
6036 return (SK_PNMI_ERR_GENERAL);
6040 else {
6042 * Send an event with the new master/slave
6043 * (role) mode to the SIRQ module.
6045 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
6046 pAC, LogPortIndex);
6047 EventParam.Para32[1] = (SK_U32)Val8;
6048 if (SkGeSirqEvent(pAC, IoC,
6049 SK_HWEV_SET_ROLE, EventParam) > 0) {
6051 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6052 SK_PNMI_ERR042,
6053 SK_PNMI_ERR042MSG);
6055 *pLen = 0;
6056 return (SK_PNMI_ERR_GENERAL);
6060 Offset += sizeof(char);
6061 break;
6063 case OID_SKGE_SPEED_MODE:
6064 /* Check the value range */
6065 Val8 = *(pBuf + Offset);
6066 if (Val8 == 0) {
6068 Offset += sizeof(char);
6069 break;
6071 if (Val8 < (SK_LSPEED_AUTO) ||
6072 (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) ||
6073 (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) {
6075 *pLen = 0;
6076 return (SK_PNMI_ERR_BAD_VALUE);
6079 /* The preset ends here */
6080 if (Action == SK_PNMI_PRESET) {
6082 return (SK_PNMI_ERR_OK);
6085 if (LogPortIndex == 0) {
6088 * The virtual port consists of all currently
6089 * active ports. Find them and send an event
6090 * with the new flow control mode to SIRQ.
6092 for (PhysPortIndex = 0;
6093 PhysPortIndex < PhysPortMax;
6094 PhysPortIndex ++) {
6096 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6098 continue;
6101 EventParam.Para32[0] = PhysPortIndex;
6102 EventParam.Para32[1] = (SK_U32)Val8;
6103 if (SkGeSirqEvent(pAC, IoC,
6104 SK_HWEV_SET_SPEED,
6105 EventParam) > 0) {
6107 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6108 SK_PNMI_ERR045,
6109 SK_PNMI_ERR045MSG);
6111 *pLen = 0;
6112 return (SK_PNMI_ERR_GENERAL);
6116 else {
6118 * Send an event with the new flow control
6119 * mode to the SIRQ module.
6121 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
6122 pAC, LogPortIndex);
6123 EventParam.Para32[1] = (SK_U32)Val8;
6124 if (SkGeSirqEvent(pAC, IoC,
6125 SK_HWEV_SET_SPEED,
6126 EventParam) > 0) {
6128 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6129 SK_PNMI_ERR045,
6130 SK_PNMI_ERR045MSG);
6132 *pLen = 0;
6133 return (SK_PNMI_ERR_GENERAL);
6136 Offset += sizeof(char);
6137 break;
6139 case OID_SKGE_MTU :
6140 /* Check the value range */
6141 Val32 = *(SK_U32*)(pBuf + Offset);
6142 if (Val32 == 0) {
6143 /* mtu of this port remains unchanged */
6144 Offset += sizeof(SK_U32);
6145 break;
6147 if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
6148 *pLen = 0;
6149 return (SK_PNMI_ERR_BAD_VALUE);
6152 /* The preset ends here */
6153 if (Action == SK_PNMI_PRESET) {
6154 return (SK_PNMI_ERR_OK);
6157 if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
6158 return (SK_PNMI_ERR_GENERAL);
6161 Offset += sizeof(SK_U32);
6162 break;
6164 default:
6165 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
6166 ("MacPrivateConf: Unknown OID should be handled before set"));
6168 *pLen = 0;
6169 return (SK_PNMI_ERR_GENERAL);
6173 return (SK_PNMI_ERR_OK);
6176 /*****************************************************************************
6178 * Monitor - OID handler function for RLMT_MONITOR_XXX
6180 * Description:
6181 * Because RLMT currently does not support the monitoring of
6182 * remote adapter cards, we return always an empty table.
6184 * Returns:
6185 * SK_PNMI_ERR_OK The request was successfully performed.
6186 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
6187 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
6188 * the correct data (e.g. a 32bit value is
6189 * needed, but a 16 bit value was passed).
6190 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
6191 * value range.
6192 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
6193 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
6194 * exist (e.g. port instance 3 on a two port
6195 * adapter.
6197 PNMI_STATIC int Monitor(
6198 SK_AC *pAC, /* Pointer to adapter context */
6199 SK_IOC IoC, /* IO context handle */
6200 int Action, /* GET/PRESET/SET action */
6201 SK_U32 Id, /* Object ID that is to be processed */
6202 char *pBuf, /* Buffer used for the management data transfer */
6203 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
6204 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
6205 unsigned int TableIndex, /* Index to the Id table */
6206 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
6208 unsigned int Index;
6209 unsigned int Limit;
6210 unsigned int Offset;
6211 unsigned int Entries;
6215 * Calculate instance if wished.
6217 /* XXX Not yet implemented. Return always an empty table. */
6218 Entries = 0;
6220 if ((Instance != (SK_U32)(-1))) {
6222 if ((Instance < 1) || (Instance > Entries)) {
6224 *pLen = 0;
6225 return (SK_PNMI_ERR_UNKNOWN_INST);
6228 Index = (unsigned int)Instance - 1;
6229 Limit = (unsigned int)Instance;
6231 else {
6232 Index = 0;
6233 Limit = Entries;
6237 * Get/Set value
6239 if (Action == SK_PNMI_GET) {
6241 for (Offset=0; Index < Limit; Index ++) {
6243 switch (Id) {
6245 case OID_SKGE_RLMT_MONITOR_INDEX:
6246 case OID_SKGE_RLMT_MONITOR_ADDR:
6247 case OID_SKGE_RLMT_MONITOR_ERRS:
6248 case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
6249 case OID_SKGE_RLMT_MONITOR_ADMIN:
6250 break;
6252 default:
6253 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
6254 SK_PNMI_ERR046MSG);
6256 *pLen = 0;
6257 return (SK_PNMI_ERR_GENERAL);
6260 *pLen = Offset;
6262 else {
6263 /* Only MONITOR_ADMIN can be set */
6264 if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
6266 *pLen = 0;
6267 return (SK_PNMI_ERR_READ_ONLY);
6270 /* Check if the length is plausible */
6271 if (*pLen < (Limit - Index)) {
6273 return (SK_PNMI_ERR_TOO_SHORT);
6275 /* Okay, we have a wide value range */
6276 if (*pLen != (Limit - Index)) {
6278 *pLen = 0;
6279 return (SK_PNMI_ERR_BAD_VALUE);
6282 for (Offset=0; Index < Limit; Index ++) {
6286 * XXX Not yet implemented. Return always BAD_VALUE, because the table
6287 * is empty.
6289 *pLen = 0;
6290 return (SK_PNMI_ERR_BAD_VALUE);
6293 return (SK_PNMI_ERR_OK);
6296 /*****************************************************************************
6298 * VirtualConf - Calculates the values of configuration OIDs for virtual port
6300 * Description:
6301 * We handle here the get of the configuration group OIDs, which are
6302 * a little bit complicated. The virtual port consists of all currently
6303 * active physical ports. If multiple ports are active and configured
6304 * differently we get in some trouble to return a single value. So we
6305 * get the value of the first active port and compare it with that of
6306 * the other active ports. If they are not the same, we return a value
6307 * that indicates that the state is indeterminated.
6309 * Returns:
6310 * Nothing
6312 PNMI_STATIC void VirtualConf(
6313 SK_AC *pAC, /* Pointer to adapter context */
6314 SK_IOC IoC, /* IO context handle */
6315 SK_U32 Id, /* Object ID that is to be processed */
6316 char *pBuf) /* Buffer used for the management data transfer */
6318 unsigned int PhysPortMax;
6319 unsigned int PhysPortIndex;
6320 SK_U8 Val8;
6321 SK_BOOL PortActiveFlag;
6322 SK_GEPORT *pPrt;
6324 *pBuf = 0;
6325 PortActiveFlag = SK_FALSE;
6326 PhysPortMax = pAC->GIni.GIMacsFound;
6328 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
6329 PhysPortIndex ++) {
6331 pPrt = &pAC->GIni.GP[PhysPortIndex];
6333 /* Check if the physical port is active */
6334 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6336 continue;
6339 PortActiveFlag = SK_TRUE;
6341 switch (Id) {
6343 case OID_SKGE_LINK_CAP:
6346 * Different capabilities should not happen, but
6347 * in the case of the cases OR them all together.
6348 * From a curious point of view the virtual port
6349 * is capable of all found capabilities.
6351 *pBuf |= pPrt->PLinkCap;
6352 break;
6354 case OID_SKGE_LINK_MODE:
6355 /* Check if it is the first active port */
6356 if (*pBuf == 0) {
6358 *pBuf = pPrt->PLinkModeConf;
6359 continue;
6363 * If we find an active port with a different link
6364 * mode than the first one we return a value that
6365 * indicates that the link mode is indeterminated.
6367 if (*pBuf != pPrt->PLinkModeConf) {
6369 *pBuf = SK_LMODE_INDETERMINATED;
6371 break;
6373 case OID_SKGE_LINK_MODE_STATUS:
6374 /* Get the link mode of the physical port */
6375 Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
6377 /* Check if it is the first active port */
6378 if (*pBuf == 0) {
6380 *pBuf = Val8;
6381 continue;
6385 * If we find an active port with a different link
6386 * mode status than the first one we return a value
6387 * that indicates that the link mode status is
6388 * indeterminated.
6390 if (*pBuf != Val8) {
6392 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6394 break;
6396 case OID_SKGE_LINK_STATUS:
6397 /* Get the link status of the physical port */
6398 Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
6400 /* Check if it is the first active port */
6401 if (*pBuf == 0) {
6403 *pBuf = Val8;
6404 continue;
6408 * If we find an active port with a different link
6409 * status than the first one, we return a value
6410 * that indicates that the link status is
6411 * indeterminated.
6413 if (*pBuf != Val8) {
6415 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6417 break;
6419 case OID_SKGE_FLOWCTRL_CAP:
6420 /* Check if it is the first active port */
6421 if (*pBuf == 0) {
6423 *pBuf = pPrt->PFlowCtrlCap;
6424 continue;
6428 * From a curious point of view the virtual port
6429 * is capable of all found capabilities.
6431 *pBuf |= pPrt->PFlowCtrlCap;
6432 break;
6434 case OID_SKGE_FLOWCTRL_MODE:
6435 /* Check if it is the first active port */
6436 if (*pBuf == 0) {
6438 *pBuf = pPrt->PFlowCtrlMode;
6439 continue;
6443 * If we find an active port with a different flow
6444 * control mode than the first one, we return a value
6445 * that indicates that the mode is indeterminated.
6447 if (*pBuf != pPrt->PFlowCtrlMode) {
6449 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6451 break;
6453 case OID_SKGE_FLOWCTRL_STATUS:
6454 /* Check if it is the first active port */
6455 if (*pBuf == 0) {
6457 *pBuf = pPrt->PFlowCtrlStatus;
6458 continue;
6462 * If we find an active port with a different flow
6463 * control status than the first one, we return a
6464 * value that indicates that the status is
6465 * indeterminated.
6467 if (*pBuf != pPrt->PFlowCtrlStatus) {
6469 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6471 break;
6473 case OID_SKGE_PHY_OPERATION_CAP:
6474 /* Check if it is the first active port */
6475 if (*pBuf == 0) {
6477 *pBuf = pPrt->PMSCap;
6478 continue;
6482 * From a curious point of view the virtual port
6483 * is capable of all found capabilities.
6485 *pBuf |= pPrt->PMSCap;
6486 break;
6488 case OID_SKGE_PHY_OPERATION_MODE:
6489 /* Check if it is the first active port */
6490 if (*pBuf == 0) {
6492 *pBuf = pPrt->PMSMode;
6493 continue;
6497 * If we find an active port with a different master/
6498 * slave mode than the first one, we return a value
6499 * that indicates that the mode is indeterminated.
6501 if (*pBuf != pPrt->PMSMode) {
6503 *pBuf = SK_MS_MODE_INDETERMINATED;
6505 break;
6507 case OID_SKGE_PHY_OPERATION_STATUS:
6508 /* Check if it is the first active port */
6509 if (*pBuf == 0) {
6511 *pBuf = pPrt->PMSStatus;
6512 continue;
6516 * If we find an active port with a different master/
6517 * slave status than the first one, we return a
6518 * value that indicates that the status is
6519 * indeterminated.
6521 if (*pBuf != pPrt->PMSStatus) {
6523 *pBuf = SK_MS_STAT_INDETERMINATED;
6525 break;
6527 case OID_SKGE_SPEED_MODE:
6528 /* Check if it is the first active port */
6529 if (*pBuf == 0) {
6531 *pBuf = pPrt->PLinkSpeed;
6532 continue;
6536 * If we find an active port with a different flow
6537 * control mode than the first one, we return a value
6538 * that indicates that the mode is indeterminated.
6540 if (*pBuf != pPrt->PLinkSpeed) {
6542 *pBuf = SK_LSPEED_INDETERMINATED;
6544 break;
6546 case OID_SKGE_SPEED_STATUS:
6547 /* Check if it is the first active port */
6548 if (*pBuf == 0) {
6550 *pBuf = pPrt->PLinkSpeedUsed;
6551 continue;
6555 * If we find an active port with a different flow
6556 * control status than the first one, we return a
6557 * value that indicates that the status is
6558 * indeterminated.
6560 if (*pBuf != pPrt->PLinkSpeedUsed) {
6562 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6564 break;
6569 * If no port is active return an indeterminated answer
6571 if (!PortActiveFlag) {
6573 switch (Id) {
6575 case OID_SKGE_LINK_CAP:
6576 *pBuf = SK_LMODE_CAP_INDETERMINATED;
6577 break;
6579 case OID_SKGE_LINK_MODE:
6580 *pBuf = SK_LMODE_INDETERMINATED;
6581 break;
6583 case OID_SKGE_LINK_MODE_STATUS:
6584 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6585 break;
6587 case OID_SKGE_LINK_STATUS:
6588 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6589 break;
6591 case OID_SKGE_FLOWCTRL_CAP:
6592 case OID_SKGE_FLOWCTRL_MODE:
6593 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6594 break;
6596 case OID_SKGE_FLOWCTRL_STATUS:
6597 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6598 break;
6600 case OID_SKGE_PHY_OPERATION_CAP:
6601 *pBuf = SK_MS_CAP_INDETERMINATED;
6602 break;
6604 case OID_SKGE_PHY_OPERATION_MODE:
6605 *pBuf = SK_MS_MODE_INDETERMINATED;
6606 break;
6608 case OID_SKGE_PHY_OPERATION_STATUS:
6609 *pBuf = SK_MS_STAT_INDETERMINATED;
6610 break;
6611 case OID_SKGE_SPEED_CAP:
6612 *pBuf = SK_LSPEED_CAP_INDETERMINATED;
6613 break;
6615 case OID_SKGE_SPEED_MODE:
6616 *pBuf = SK_LSPEED_INDETERMINATED;
6617 break;
6619 case OID_SKGE_SPEED_STATUS:
6620 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6621 break;
6626 /*****************************************************************************
6628 * CalculateLinkStatus - Determins the link status of a physical port
6630 * Description:
6631 * Determins the link status the following way:
6632 * LSTAT_PHY_DOWN: Link is down
6633 * LSTAT_AUTONEG: Auto-negotiation failed
6634 * LSTAT_LOG_DOWN: Link is up but RLMT did not yet put the port
6635 * logically up.
6636 * LSTAT_LOG_UP: RLMT marked the port as up
6638 * Returns:
6639 * Link status of physical port
6641 PNMI_STATIC SK_U8 CalculateLinkStatus(
6642 SK_AC *pAC, /* Pointer to adapter context */
6643 SK_IOC IoC, /* IO context handle */
6644 unsigned int PhysPortIndex) /* Physical port index */
6646 SK_U8 Result;
6648 if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
6650 Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
6652 else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
6654 Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
6656 else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
6658 Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
6660 else {
6661 Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
6664 return (Result);
6667 /*****************************************************************************
6669 * CalculateLinkModeStatus - Determins the link mode status of a phys. port
6671 * Description:
6672 * The COMMON module only tells us if the mode is half or full duplex.
6673 * But in the decade of auto sensing it is usefull for the user to
6674 * know if the mode was negotiated or forced. Therefore we have a
6675 * look to the mode, which was last used by the negotiation process.
6677 * Returns:
6678 * The link mode status
6680 PNMI_STATIC SK_U8 CalculateLinkModeStatus(
6681 SK_AC *pAC, /* Pointer to adapter context */
6682 SK_IOC IoC, /* IO context handle */
6683 unsigned int PhysPortIndex) /* Physical port index */
6685 SK_U8 Result;
6687 /* Get the current mode, which can be full or half duplex */
6688 Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
6690 /* Check if no valid mode could be found (link is down) */
6691 if (Result < SK_LMODE_STAT_HALF) {
6693 Result = SK_LMODE_STAT_UNKNOWN;
6695 else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
6698 * Auto-negotiation was used to bring up the link. Change
6699 * the already found duplex status that it indicates
6700 * auto-negotiation was involved.
6702 if (Result == SK_LMODE_STAT_HALF) {
6704 Result = SK_LMODE_STAT_AUTOHALF;
6706 else if (Result == SK_LMODE_STAT_FULL) {
6708 Result = SK_LMODE_STAT_AUTOFULL;
6712 return (Result);
6715 /*****************************************************************************
6717 * GetVpdKeyArr - Obtain an array of VPD keys
6719 * Description:
6720 * Read the VPD keys and build an array of VPD keys, which are
6721 * easy to access.
6723 * Returns:
6724 * SK_PNMI_ERR_OK Task successfully performed.
6725 * SK_PNMI_ERR_GENERAL Something went wrong.
6727 PNMI_STATIC int GetVpdKeyArr(
6728 SK_AC *pAC, /* Pointer to adapter context */
6729 SK_IOC IoC, /* IO context handle */
6730 char *pKeyArr, /* Ptr KeyArray */
6731 unsigned int KeyArrLen, /* Length of array in bytes */
6732 unsigned int *pKeyNo) /* Number of keys */
6734 unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE;
6735 char BufKeys[SK_PNMI_VPD_BUFSIZE];
6736 unsigned int StartOffset;
6737 unsigned int Offset;
6738 int Index;
6739 int Ret;
6742 SK_MEMSET(pKeyArr, 0, KeyArrLen);
6745 * Get VPD key list
6747 Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
6748 (int *)pKeyNo);
6749 if (Ret > 0) {
6751 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
6752 SK_PNMI_ERR014MSG);
6754 return (SK_PNMI_ERR_GENERAL);
6756 /* If no keys are available return now */
6757 if (*pKeyNo == 0 || BufKeysLen == 0) {
6759 return (SK_PNMI_ERR_OK);
6762 * If the key list is too long for us trunc it and give a
6763 * errorlog notification. This case should not happen because
6764 * the maximum number of keys is limited due to RAM limitations
6766 if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
6768 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
6769 SK_PNMI_ERR015MSG);
6771 *pKeyNo = SK_PNMI_VPD_ENTRIES;
6775 * Now build an array of fixed string length size and copy
6776 * the keys together.
6778 for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
6779 Offset ++) {
6781 if (BufKeys[Offset] != 0) {
6783 continue;
6786 if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
6788 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
6789 SK_PNMI_ERR016MSG);
6790 return (SK_PNMI_ERR_GENERAL);
6793 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6794 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6796 Index ++;
6797 StartOffset = Offset + 1;
6800 /* Last key not zero terminated? Get it anyway */
6801 if (StartOffset < Offset) {
6803 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6804 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6807 return (SK_PNMI_ERR_OK);
6810 /*****************************************************************************
6812 * SirqUpdate - Let the SIRQ update its internal values
6814 * Description:
6815 * Just to be sure that the SIRQ module holds its internal data
6816 * structures up to date, we send an update event before we make
6817 * any access.
6819 * Returns:
6820 * SK_PNMI_ERR_OK Task successfully performed.
6821 * SK_PNMI_ERR_GENERAL Something went wrong.
6823 PNMI_STATIC int SirqUpdate(
6824 SK_AC *pAC, /* Pointer to adapter context */
6825 SK_IOC IoC) /* IO context handle */
6827 SK_EVPARA EventParam;
6830 /* Was the module already updated during the current PNMI call? */
6831 if (pAC->Pnmi.SirqUpdatedFlag > 0) {
6833 return (SK_PNMI_ERR_OK);
6836 /* Send an synchronuous update event to the module */
6837 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6838 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
6840 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
6841 SK_PNMI_ERR047MSG);
6843 return (SK_PNMI_ERR_GENERAL);
6846 return (SK_PNMI_ERR_OK);
6849 /*****************************************************************************
6851 * RlmtUpdate - Let the RLMT update its internal values
6853 * Description:
6854 * Just to be sure that the RLMT module holds its internal data
6855 * structures up to date, we send an update event before we make
6856 * any access.
6858 * Returns:
6859 * SK_PNMI_ERR_OK Task successfully performed.
6860 * SK_PNMI_ERR_GENERAL Something went wrong.
6862 PNMI_STATIC int RlmtUpdate(
6863 SK_AC *pAC, /* Pointer to adapter context */
6864 SK_IOC IoC, /* IO context handle */
6865 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6867 SK_EVPARA EventParam;
6870 /* Was the module already updated during the current PNMI call? */
6871 if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
6873 return (SK_PNMI_ERR_OK);
6876 /* Send an synchronuous update event to the module */
6877 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6878 EventParam.Para32[0] = NetIndex;
6879 EventParam.Para32[1] = (SK_U32)-1;
6880 if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
6882 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
6883 SK_PNMI_ERR048MSG);
6885 return (SK_PNMI_ERR_GENERAL);
6888 return (SK_PNMI_ERR_OK);
6891 /*****************************************************************************
6893 * MacUpdate - Force the XMAC to output the current statistic
6895 * Description:
6896 * The XMAC holds its statistic internally. To obtain the current
6897 * values we must send a command so that the statistic data will
6898 * be written to a predefined memory area on the adapter.
6900 * Returns:
6901 * SK_PNMI_ERR_OK Task successfully performed.
6902 * SK_PNMI_ERR_GENERAL Something went wrong.
6904 PNMI_STATIC int MacUpdate(
6905 SK_AC *pAC, /* Pointer to adapter context */
6906 SK_IOC IoC, /* IO context handle */
6907 unsigned int FirstMac, /* Index of the first Mac to be updated */
6908 unsigned int LastMac) /* Index of the last Mac to be updated */
6910 unsigned int MacIndex;
6913 * Were the statistics already updated during the
6914 * current PNMI call?
6916 if (pAC->Pnmi.MacUpdatedFlag > 0) {
6918 return (SK_PNMI_ERR_OK);
6921 /* Send an update command to all MACs specified */
6922 for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
6925 * 2002-09-13 pweber: Freeze the current SW counters.
6926 * (That should be done as close as
6927 * possible to the update of the
6928 * HW counters)
6930 if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
6931 pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
6934 /* 2002-09-13 pweber: Update the HW counter */
6935 if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
6937 return (SK_PNMI_ERR_GENERAL);
6941 return (SK_PNMI_ERR_OK);
6944 /*****************************************************************************
6946 * GetStatVal - Retrieve an XMAC statistic counter
6948 * Description:
6949 * Retrieves the statistic counter of a virtual or physical port. The
6950 * virtual port is identified by the index 0. It consists of all
6951 * currently active ports. To obtain the counter value for this port
6952 * we must add the statistic counter of all active ports. To grant
6953 * continuous counter values for the virtual port even when port
6954 * switches occur we must additionally add a delta value, which was
6955 * calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
6957 * Returns:
6958 * Requested statistic value
6960 PNMI_STATIC SK_U64 GetStatVal(
6961 SK_AC *pAC, /* Pointer to adapter context */
6962 SK_IOC IoC, /* IO context handle */
6963 unsigned int LogPortIndex, /* Index of the logical Port to be processed */
6964 unsigned int StatIndex, /* Index to statistic value */
6965 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6967 unsigned int PhysPortIndex;
6968 unsigned int PhysPortMax;
6969 SK_U64 Val = 0;
6972 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
6974 PhysPortIndex = NetIndex;
6976 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6978 else { /* Single Net mode */
6980 if (LogPortIndex == 0) {
6982 PhysPortMax = pAC->GIni.GIMacsFound;
6984 /* Add counter of all active ports */
6985 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
6986 PhysPortIndex ++) {
6988 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6990 Val += GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6994 /* Correct value because of port switches */
6995 Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
6997 else {
6998 /* Get counter value of physical port */
6999 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
7001 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
7004 return (Val);
7007 /*****************************************************************************
7009 * GetPhysStatVal - Get counter value for physical port
7011 * Description:
7012 * Builds a 64bit counter value. Except for the octet counters
7013 * the lower 32bit are counted in hardware and the upper 32bit
7014 * in software by monitoring counter overflow interrupts in the
7015 * event handler. To grant continous counter values during XMAC
7016 * resets (caused by a workaround) we must add a delta value.
7017 * The delta was calculated in the event handler when a
7018 * SK_PNMI_EVT_XMAC_RESET was received.
7020 * Returns:
7021 * Counter value
7023 PNMI_STATIC SK_U64 GetPhysStatVal(
7024 SK_AC *pAC, /* Pointer to adapter context */
7025 SK_IOC IoC, /* IO context handle */
7026 unsigned int PhysPortIndex, /* Index of the logical Port to be processed */
7027 unsigned int StatIndex) /* Index to statistic value */
7029 SK_U64 Val = 0;
7030 SK_U32 LowVal = 0;
7031 SK_U32 HighVal = 0;
7032 SK_U16 Word;
7033 int MacType;
7034 unsigned int HelpIndex;
7035 SK_GEPORT *pPrt;
7037 SK_PNMI_PORT *pPnmiPrt;
7038 SK_GEMACFUNC *pFnMac;
7040 pPrt = &pAC->GIni.GP[PhysPortIndex];
7042 MacType = pAC->GIni.GIMacType;
7044 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
7045 if (MacType == SK_MAC_XMAC) {
7046 pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
7048 else {
7049 pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex];
7052 pFnMac = &pAC->GIni.GIFunc;
7054 switch (StatIndex) {
7055 case SK_PNMI_HTX:
7056 if (MacType == SK_MAC_GMAC) {
7057 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7058 StatAddr[SK_PNMI_HTX_BROADCAST][MacType].Reg,
7059 &LowVal);
7060 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7061 StatAddr[SK_PNMI_HTX_MULTICAST][MacType].Reg,
7062 &HighVal);
7063 LowVal += HighVal;
7064 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7065 StatAddr[SK_PNMI_HTX_UNICAST][MacType].Reg,
7066 &HighVal);
7067 LowVal += HighVal;
7069 else {
7070 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7071 StatAddr[StatIndex][MacType].Reg,
7072 &LowVal);
7074 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7075 break;
7077 case SK_PNMI_HRX:
7078 if (MacType == SK_MAC_GMAC) {
7079 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7080 StatAddr[SK_PNMI_HRX_BROADCAST][MacType].Reg,
7081 &LowVal);
7082 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7083 StatAddr[SK_PNMI_HRX_MULTICAST][MacType].Reg,
7084 &HighVal);
7085 LowVal += HighVal;
7086 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7087 StatAddr[SK_PNMI_HRX_UNICAST][MacType].Reg,
7088 &HighVal);
7089 LowVal += HighVal;
7091 else {
7092 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7093 StatAddr[StatIndex][MacType].Reg,
7094 &LowVal);
7096 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7097 break;
7099 case SK_PNMI_HTX_OCTET:
7100 case SK_PNMI_HRX_OCTET:
7101 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7102 StatAddr[StatIndex][MacType].Reg,
7103 &HighVal);
7104 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7105 StatAddr[StatIndex + 1][MacType].Reg,
7106 &LowVal);
7107 break;
7109 case SK_PNMI_HTX_BURST:
7110 case SK_PNMI_HTX_EXCESS_DEF:
7111 case SK_PNMI_HTX_CARRIER:
7112 /* Not supported by GMAC */
7113 if (MacType == SK_MAC_GMAC) {
7114 return (Val);
7117 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7118 StatAddr[StatIndex][MacType].Reg,
7119 &LowVal);
7120 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7121 break;
7123 case SK_PNMI_HTX_MACC:
7124 /* GMAC only supports PAUSE MAC control frames */
7125 if (MacType == SK_MAC_GMAC) {
7126 HelpIndex = SK_PNMI_HTX_PMACC;
7128 else {
7129 HelpIndex = StatIndex;
7132 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7133 StatAddr[HelpIndex][MacType].Reg,
7134 &LowVal);
7136 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7137 break;
7139 case SK_PNMI_HTX_COL:
7140 case SK_PNMI_HRX_UNDERSIZE:
7141 /* Not supported by XMAC */
7142 if (MacType == SK_MAC_XMAC) {
7143 return (Val);
7146 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7147 StatAddr[StatIndex][MacType].Reg,
7148 &LowVal);
7149 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7150 break;
7152 case SK_PNMI_HTX_DEFFERAL:
7153 /* Not supported by GMAC */
7154 if (MacType == SK_MAC_GMAC) {
7155 return (Val);
7159 * XMAC counts frames with deferred transmission
7160 * even in full-duplex mode.
7162 * In full-duplex mode the counter remains constant!
7164 if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) ||
7165 (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL)) {
7167 LowVal = 0;
7168 HighVal = 0;
7170 else {
7171 /* Otherwise get contents of hardware register */
7172 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7173 StatAddr[StatIndex][MacType].Reg,
7174 &LowVal);
7175 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7177 break;
7179 case SK_PNMI_HRX_BADOCTET:
7180 /* Not supported by XMAC */
7181 if (MacType == SK_MAC_XMAC) {
7182 return (Val);
7185 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7186 StatAddr[StatIndex][MacType].Reg,
7187 &HighVal);
7188 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7189 StatAddr[StatIndex + 1][MacType].Reg,
7190 &LowVal);
7191 break;
7193 case SK_PNMI_HTX_OCTETLOW:
7194 case SK_PNMI_HRX_OCTETLOW:
7195 case SK_PNMI_HRX_BADOCTETLOW:
7196 return (Val);
7198 case SK_PNMI_HRX_LONGFRAMES:
7199 /* For XMAC the SW counter is managed by PNMI */
7200 if (MacType == SK_MAC_XMAC) {
7201 return (pPnmiPrt->StatRxLongFrameCts);
7204 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7205 StatAddr[StatIndex][MacType].Reg,
7206 &LowVal);
7207 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7208 break;
7210 case SK_PNMI_HRX_TOO_LONG:
7211 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7212 StatAddr[StatIndex][MacType].Reg,
7213 &LowVal);
7214 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7216 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7218 if (MacType == SK_MAC_GMAC) {
7219 /* For GMAC the SW counter is additionally managed by PNMI */
7220 Val += pPnmiPrt->StatRxFrameTooLongCts;
7222 else {
7224 * Frames longer than IEEE 802.3 frame max size are counted
7225 * by XMAC in frame_too_long counter even reception of long
7226 * frames was enabled and the frame was correct.
7227 * So correct the value by subtracting RxLongFrame counter.
7229 Val -= pPnmiPrt->StatRxLongFrameCts;
7232 LowVal = (SK_U32)Val;
7233 HighVal = (SK_U32)(Val >> 32);
7234 break;
7236 case SK_PNMI_HRX_SHORTS:
7237 /* Not supported by GMAC */
7238 if (MacType == SK_MAC_GMAC) {
7239 /* GM_RXE_FRAG?? */
7240 return (Val);
7244 * XMAC counts short frame errors even if link down (#10620)
7246 * If link-down the counter remains constant
7248 if (pPrt->PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
7250 /* Otherwise get incremental difference */
7251 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7252 StatAddr[StatIndex][MacType].Reg,
7253 &LowVal);
7254 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7256 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7257 Val -= pPnmiPrt->RxShortZeroMark;
7259 LowVal = (SK_U32)Val;
7260 HighVal = (SK_U32)(Val >> 32);
7262 break;
7264 case SK_PNMI_HRX_MACC:
7265 case SK_PNMI_HRX_MACC_UNKWN:
7266 case SK_PNMI_HRX_BURST:
7267 case SK_PNMI_HRX_MISSED:
7268 case SK_PNMI_HRX_FRAMING:
7269 case SK_PNMI_HRX_CARRIER:
7270 case SK_PNMI_HRX_IRLENGTH:
7271 case SK_PNMI_HRX_SYMBOL:
7272 case SK_PNMI_HRX_CEXT:
7273 /* Not supported by GMAC */
7274 if (MacType == SK_MAC_GMAC) {
7275 return (Val);
7278 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7279 StatAddr[StatIndex][MacType].Reg,
7280 &LowVal);
7281 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7282 break;
7284 case SK_PNMI_HRX_PMACC_ERR:
7285 /* For GMAC the SW counter is managed by PNMI */
7286 if (MacType == SK_MAC_GMAC) {
7287 return (pPnmiPrt->StatRxPMaccErr);
7290 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7291 StatAddr[StatIndex][MacType].Reg,
7292 &LowVal);
7293 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7294 break;
7296 /* SW counter managed by PNMI */
7297 case SK_PNMI_HTX_SYNC:
7298 LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
7299 HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
7300 break;
7302 /* SW counter managed by PNMI */
7303 case SK_PNMI_HTX_SYNC_OCTET:
7304 LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
7305 HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
7306 break;
7308 case SK_PNMI_HRX_FCS:
7310 * Broadcom filters FCS errors and counts it in
7311 * Receive Error Counter register
7313 if (pPrt->PhyType == SK_PHY_BCOM) {
7314 /* do not read while not initialized (PHY_READ hangs!)*/
7315 if (pPrt->PState != SK_PRT_RESET) {
7316 SkXmPhyRead(pAC, IoC, PhysPortIndex, PHY_BCOM_RE_CTR, &Word);
7318 LowVal = Word;
7320 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7322 else {
7323 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7324 StatAddr[StatIndex][MacType].Reg,
7325 &LowVal);
7326 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7328 break;
7330 default:
7331 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7332 StatAddr[StatIndex][MacType].Reg,
7333 &LowVal);
7334 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7335 break;
7338 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7340 /* Correct value because of possible XMAC reset. XMAC Errata #2 */
7341 Val += pPnmiPrt->CounterOffset[StatIndex];
7343 return (Val);
7346 /*****************************************************************************
7348 * ResetCounter - Set all counters and timestamps to zero
7350 * Description:
7351 * Notifies other common modules which store statistic data to
7352 * reset their counters and finally reset our own counters.
7354 * Returns:
7355 * Nothing
7357 PNMI_STATIC void ResetCounter(
7358 SK_AC *pAC, /* Pointer to adapter context */
7359 SK_IOC IoC, /* IO context handle */
7360 SK_U32 NetIndex)
7362 unsigned int PhysPortIndex;
7363 SK_EVPARA EventParam;
7366 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
7368 /* Notify sensor module */
7369 SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
7371 /* Notify RLMT module */
7372 EventParam.Para32[0] = NetIndex;
7373 EventParam.Para32[1] = (SK_U32)-1;
7374 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
7375 EventParam.Para32[1] = 0;
7377 /* Notify SIRQ module */
7378 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
7380 /* Notify CSUM module */
7381 #ifdef SK_USE_CSUM
7382 EventParam.Para32[0] = NetIndex;
7383 EventParam.Para32[1] = (SK_U32)-1;
7384 SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
7385 EventParam);
7386 #endif /* SK_USE_CSUM */
7388 /* Clear XMAC statistic */
7389 for (PhysPortIndex = 0; PhysPortIndex <
7390 (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
7392 (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex);
7394 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
7395 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
7396 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7397 CounterOffset, 0, sizeof(pAC->Pnmi.Port[
7398 PhysPortIndex].CounterOffset));
7399 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
7400 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
7401 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7402 StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
7403 PhysPortIndex].StatSyncOctetsCts));
7404 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7405 StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
7406 PhysPortIndex].StatRxLongFrameCts));
7407 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7408 StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[
7409 PhysPortIndex].StatRxFrameTooLongCts));
7410 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7411 StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[
7412 PhysPortIndex].StatRxPMaccErr));
7416 * Clear local statistics
7418 SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
7419 sizeof(pAC->Pnmi.VirtualCounterOffset));
7420 pAC->Pnmi.RlmtChangeCts = 0;
7421 pAC->Pnmi.RlmtChangeTime = 0;
7422 SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
7423 sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
7424 pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
7425 pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
7426 pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
7427 pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
7428 pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
7429 pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
7430 pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
7431 pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
7432 pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
7433 pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
7434 pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
7435 pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
7438 /*****************************************************************************
7440 * GetTrapEntry - Get an entry in the trap buffer
7442 * Description:
7443 * The trap buffer stores various events. A user application somehow
7444 * gets notified that an event occured and retrieves the trap buffer
7445 * contens (or simply polls the buffer). The buffer is organized as
7446 * a ring which stores the newest traps at the beginning. The oldest
7447 * traps are overwritten by the newest ones. Each trap entry has a
7448 * unique number, so that applications may detect new trap entries.
7450 * Returns:
7451 * A pointer to the trap entry
7453 PNMI_STATIC char* GetTrapEntry(
7454 SK_AC *pAC, /* Pointer to adapter context */
7455 SK_U32 TrapId, /* SNMP ID of the trap */
7456 unsigned int Size) /* Space needed for trap entry */
7458 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7459 unsigned int BufFree = pAC->Pnmi.TrapBufFree;
7460 unsigned int Beg = pAC->Pnmi.TrapQueueBeg;
7461 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7462 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7463 int Wrap;
7464 unsigned int NeededSpace;
7465 unsigned int EntrySize;
7466 SK_U32 Val32;
7467 SK_U64 Val64;
7470 /* Last byte of entry will get a copy of the entry length */
7471 Size ++;
7474 * Calculate needed buffer space */
7475 if (Beg >= Size) {
7477 NeededSpace = Size;
7478 Wrap = SK_FALSE;
7480 else {
7481 NeededSpace = Beg + Size;
7482 Wrap = SK_TRUE;
7486 * Check if enough buffer space is provided. Otherwise
7487 * free some entries. Leave one byte space between begin
7488 * and end of buffer to make it possible to detect whether
7489 * the buffer is full or empty
7491 while (BufFree < NeededSpace + 1) {
7493 if (End == 0) {
7495 End = SK_PNMI_TRAP_QUEUE_LEN;
7498 EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
7499 BufFree += EntrySize;
7500 End -= EntrySize;
7501 #ifdef DEBUG
7502 SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
7503 #endif /* DEBUG */
7504 if (End == BufPad) {
7505 #ifdef DEBUG
7506 SK_MEMSET(pBuf, (char)(-1), End);
7507 #endif /* DEBUG */
7508 BufFree += End;
7509 End = 0;
7510 BufPad = 0;
7515 * Insert new entry as first entry. Newest entries are
7516 * stored at the beginning of the queue.
7518 if (Wrap) {
7520 BufPad = Beg;
7521 Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
7523 else {
7524 Beg = Beg - Size;
7526 BufFree -= NeededSpace;
7528 /* Save the current offsets */
7529 pAC->Pnmi.TrapQueueBeg = Beg;
7530 pAC->Pnmi.TrapQueueEnd = End;
7531 pAC->Pnmi.TrapBufPad = BufPad;
7532 pAC->Pnmi.TrapBufFree = BufFree;
7534 /* Initialize the trap entry */
7535 *(pBuf + Beg + Size - 1) = (char)Size;
7536 *(pBuf + Beg) = (char)Size;
7537 Val32 = (pAC->Pnmi.TrapUnique) ++;
7538 SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
7539 SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
7540 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
7541 SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
7543 return (pBuf + Beg);
7546 /*****************************************************************************
7548 * CopyTrapQueue - Copies the trap buffer for the TRAP OID
7550 * Description:
7551 * On a query of the TRAP OID the trap buffer contents will be
7552 * copied continuously to the request buffer, which must be large
7553 * enough. No length check is performed.
7555 * Returns:
7556 * Nothing
7558 PNMI_STATIC void CopyTrapQueue(
7559 SK_AC *pAC, /* Pointer to adapter context */
7560 char *pDstBuf) /* Buffer to which the queued traps will be copied */
7562 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7563 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7564 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7565 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7566 unsigned int Len;
7567 unsigned int DstOff = 0;
7570 while (Trap != End) {
7572 Len = (unsigned int)*(pBuf + Trap);
7575 * Last byte containing a copy of the length will
7576 * not be copied.
7578 *(pDstBuf + DstOff) = (char)(Len - 1);
7579 SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
7580 DstOff += Len - 1;
7582 Trap += Len;
7583 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7585 Trap = BufPad;
7590 /*****************************************************************************
7592 * GetTrapQueueLen - Get the length of the trap buffer
7594 * Description:
7595 * Evaluates the number of currently stored traps and the needed
7596 * buffer size to retrieve them.
7598 * Returns:
7599 * Nothing
7601 PNMI_STATIC void GetTrapQueueLen(
7602 SK_AC *pAC, /* Pointer to adapter context */
7603 unsigned int *pLen, /* Length in Bytes of all queued traps */
7604 unsigned int *pEntries) /* Returns number of trapes stored in queue */
7606 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7607 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7608 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7609 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7610 unsigned int Len;
7611 unsigned int Entries = 0;
7612 unsigned int TotalLen = 0;
7615 while (Trap != End) {
7617 Len = (unsigned int)*(pBuf + Trap);
7618 TotalLen += Len - 1;
7619 Entries ++;
7621 Trap += Len;
7622 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7624 Trap = BufPad;
7628 *pEntries = Entries;
7629 *pLen = TotalLen;
7632 /*****************************************************************************
7634 * QueueSimpleTrap - Store a simple trap to the trap buffer
7636 * Description:
7637 * A simple trap is a trap with now additional data. It consists
7638 * simply of a trap code.
7640 * Returns:
7641 * Nothing
7643 PNMI_STATIC void QueueSimpleTrap(
7644 SK_AC *pAC, /* Pointer to adapter context */
7645 SK_U32 TrapId) /* Type of sensor trap */
7647 GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
7650 /*****************************************************************************
7652 * QueueSensorTrap - Stores a sensor trap in the trap buffer
7654 * Description:
7655 * Gets an entry in the trap buffer and fills it with sensor related
7656 * data.
7658 * Returns:
7659 * Nothing
7661 PNMI_STATIC void QueueSensorTrap(
7662 SK_AC *pAC, /* Pointer to adapter context */
7663 SK_U32 TrapId, /* Type of sensor trap */
7664 unsigned int SensorIndex) /* Index of sensor which caused the trap */
7666 char *pBuf;
7667 unsigned int Offset;
7668 unsigned int DescrLen;
7669 SK_U32 Val32;
7672 /* Get trap buffer entry */
7673 DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
7674 pBuf = GetTrapEntry(pAC, TrapId,
7675 SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
7676 Offset = SK_PNMI_TRAP_SIMPLE_LEN;
7678 /* Store additionally sensor trap related data */
7679 Val32 = OID_SKGE_SENSOR_INDEX;
7680 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7681 *(pBuf + Offset + 4) = 4;
7682 Val32 = (SK_U32)SensorIndex;
7683 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7684 Offset += 9;
7686 Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
7687 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7688 *(pBuf + Offset + 4) = (char)DescrLen;
7689 SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
7690 DescrLen);
7691 Offset += DescrLen + 5;
7693 Val32 = OID_SKGE_SENSOR_TYPE;
7694 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7695 *(pBuf + Offset + 4) = 1;
7696 *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
7697 Offset += 6;
7699 Val32 = OID_SKGE_SENSOR_VALUE;
7700 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7701 *(pBuf + Offset + 4) = 4;
7702 Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
7703 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7706 /*****************************************************************************
7708 * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
7710 * Description:
7711 * Nothing further to explain.
7713 * Returns:
7714 * Nothing
7716 PNMI_STATIC void QueueRlmtNewMacTrap(
7717 SK_AC *pAC, /* Pointer to adapter context */
7718 unsigned int ActiveMac) /* Index (0..n) of the currently active port */
7720 char *pBuf;
7721 SK_U32 Val32;
7724 pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
7725 SK_PNMI_TRAP_RLMT_CHANGE_LEN);
7727 Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
7728 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7729 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7730 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
7733 /*****************************************************************************
7735 * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
7737 * Description:
7738 * Nothing further to explain.
7740 * Returns:
7741 * Nothing
7743 PNMI_STATIC void QueueRlmtPortTrap(
7744 SK_AC *pAC, /* Pointer to adapter context */
7745 SK_U32 TrapId, /* Type of RLMT port trap */
7746 unsigned int PortIndex) /* Index of the port, which changed its state */
7748 char *pBuf;
7749 SK_U32 Val32;
7752 pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
7754 Val32 = OID_SKGE_RLMT_PORT_INDEX;
7755 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7756 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7757 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
7760 /*****************************************************************************
7762 * CopyMac - Copies a MAC address
7764 * Description:
7765 * Nothing further to explain.
7767 * Returns:
7768 * Nothing
7770 PNMI_STATIC void CopyMac(
7771 char *pDst, /* Pointer to destination buffer */
7772 SK_MAC_ADDR *pMac) /* Pointer of Source */
7774 int i;
7777 for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
7779 *(pDst + i) = pMac->a[i];
7783 #ifdef SK_POWER_MGMT
7784 /*****************************************************************************
7786 * PowerManagement - OID handler function of PowerManagement OIDs
7788 * Description:
7789 * The code is simple. No description necessary.
7791 * Returns:
7792 * SK_PNMI_ERR_OK The request was successfully performed.
7793 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7794 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7795 * the correct data (e.g. a 32bit value is
7796 * needed, but a 16 bit value was passed).
7797 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7798 * exist (e.g. port instance 3 on a two port
7799 * adapter.
7802 PNMI_STATIC int PowerManagement(
7803 SK_AC *pAC, /* Pointer to adapter context */
7804 SK_IOC IoC, /* IO context handle */
7805 int Action, /* Get/PreSet/Set action */
7806 SK_U32 Id, /* Object ID that is to be processed */
7807 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
7808 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
7809 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7810 unsigned int TableIndex, /* Index to the Id table */
7811 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
7814 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7817 * Check instance. We only handle single instance variables
7819 if (Instance != (SK_U32)(-1) && Instance != 1) {
7821 *pLen = 0;
7822 return (SK_PNMI_ERR_UNKNOWN_INST);
7826 /* Check length */
7827 switch (Id) {
7829 case OID_PNP_CAPABILITIES:
7830 if (*pLen < sizeof(SK_PNP_CAPABILITIES)) {
7832 *pLen = sizeof(SK_PNP_CAPABILITIES);
7833 return (SK_PNMI_ERR_TOO_SHORT);
7835 break;
7837 case OID_PNP_SET_POWER:
7838 case OID_PNP_QUERY_POWER:
7839 if (*pLen < sizeof(SK_DEVICE_POWER_STATE))
7841 *pLen = sizeof(SK_DEVICE_POWER_STATE);
7842 return (SK_PNMI_ERR_TOO_SHORT);
7844 break;
7846 case OID_PNP_ADD_WAKE_UP_PATTERN:
7847 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7848 if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) {
7850 *pLen = sizeof(SK_PM_PACKET_PATTERN);
7851 return (SK_PNMI_ERR_TOO_SHORT);
7853 break;
7855 case OID_PNP_ENABLE_WAKE_UP:
7856 if (*pLen < sizeof(SK_U32)) {
7858 *pLen = sizeof(SK_U32);
7859 return (SK_PNMI_ERR_TOO_SHORT);
7861 break;
7865 * Perform action
7867 if (Action == SK_PNMI_GET) {
7870 * Get value
7872 switch (Id) {
7874 case OID_PNP_CAPABILITIES:
7875 RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen);
7876 break;
7878 case OID_PNP_QUERY_POWER:
7879 /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
7880 the miniport to indicate whether it can transition its NIC
7881 to the low-power state.
7882 A miniport driver must always return NDIS_STATUS_SUCCESS
7883 to a query of OID_PNP_QUERY_POWER. */
7884 *pLen = sizeof(SK_DEVICE_POWER_STATE);;
7885 RetCode = SK_PNMI_ERR_OK;
7886 break;
7888 /* NDIS handles these OIDs as write-only.
7889 * So in case of get action the buffer with written length = 0
7890 * is returned
7892 case OID_PNP_SET_POWER:
7893 case OID_PNP_ADD_WAKE_UP_PATTERN:
7894 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7895 *pLen = 0;
7896 RetCode = SK_PNMI_ERR_NOT_SUPPORTED;
7897 break;
7899 case OID_PNP_ENABLE_WAKE_UP:
7900 RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen);
7901 break;
7903 default:
7904 RetCode = SK_PNMI_ERR_GENERAL;
7905 break;
7908 return (RetCode);
7913 * Perform preset or set
7916 /* POWER module does not support PRESET action */
7917 if (Action == SK_PNMI_PRESET) {
7918 return (SK_PNMI_ERR_OK);
7921 switch (Id) {
7922 case OID_PNP_SET_POWER:
7923 RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen);
7924 break;
7926 case OID_PNP_ADD_WAKE_UP_PATTERN:
7927 RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen);
7928 break;
7930 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7931 RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen);
7932 break;
7934 case OID_PNP_ENABLE_WAKE_UP:
7935 RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen);
7936 break;
7938 default:
7939 RetCode = SK_PNMI_ERR_READ_ONLY;
7942 return (RetCode);
7944 #endif /* SK_POWER_MGMT */
7946 #ifdef SK_DIAG_SUPPORT
7947 /*****************************************************************************
7949 * DiagActions - OID handler function of Diagnostic driver
7951 * Description:
7952 * The code is simple. No description necessary.
7954 * Returns:
7955 * SK_PNMI_ERR_OK The request was successfully performed.
7956 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7957 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7958 * the correct data (e.g. a 32bit value is
7959 * needed, but a 16 bit value was passed).
7960 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7961 * exist (e.g. port instance 3 on a two port
7962 * adapter.
7965 PNMI_STATIC int DiagActions(
7966 SK_AC *pAC, /* Pointer to adapter context */
7967 SK_IOC IoC, /* IO context handle */
7968 int Action, /* GET/PRESET/SET action */
7969 SK_U32 Id, /* Object ID that is to be processed */
7970 char *pBuf, /* Buffer used for the management data transfer */
7971 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
7972 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7973 unsigned int TableIndex, /* Index to the Id table */
7974 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
7977 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7980 * Check instance. We only handle single instance variables.
7982 if (Instance != (SK_U32)(-1) && Instance != 1) {
7984 *pLen = 0;
7985 return (SK_PNMI_ERR_UNKNOWN_INST);
7989 * Check length.
7991 switch (Id) {
7993 case OID_SKGE_DIAG_MODE:
7994 if (*pLen < sizeof(SK_U32)) {
7996 *pLen = sizeof(SK_U32);
7997 return (SK_PNMI_ERR_TOO_SHORT);
7999 break;
8001 default:
8002 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040, SK_PNMI_ERR040MSG);
8003 *pLen = 0;
8004 return (SK_PNMI_ERR_GENERAL);
8007 /* Perform action. */
8009 /* GET value. */
8010 if (Action == SK_PNMI_GET) {
8012 switch (Id) {
8014 case OID_SKGE_DIAG_MODE:
8015 SK_PNMI_STORE_U32(pBuf, pAC->DiagModeActive);
8016 *pLen = sizeof(SK_U32);
8017 RetCode = SK_PNMI_ERR_OK;
8018 break;
8020 default:
8021 *pLen = 0;
8022 RetCode = SK_PNMI_ERR_GENERAL;
8023 break;
8026 return (RetCode);
8029 /* From here SET or PRESET value. */
8031 /* PRESET value is not supported. */
8032 if (Action == SK_PNMI_PRESET) {
8033 return (SK_PNMI_ERR_OK);
8036 /* SET value. */
8037 switch (Id) {
8038 case OID_SKGE_DIAG_MODE:
8040 /* Handle the SET. */
8041 switch (*pBuf) {
8043 /* Enter the DIAG mode in the driver. */
8044 case 1:
8045 /* If DiagMode is not active, we can enter it. */
8046 if (!pAC->DiagModeActive) {
8048 RetCode = SkDrvEnterDiagMode(pAC);
8050 else {
8052 RetCode = SK_PNMI_ERR_GENERAL;
8054 break;
8056 /* Leave the DIAG mode in the driver. */
8057 case 0:
8058 RetCode = SkDrvLeaveDiagMode(pAC);
8059 break;
8061 default:
8062 RetCode = SK_PNMI_ERR_BAD_VALUE;
8063 break;
8065 break;
8067 default:
8068 RetCode = SK_PNMI_ERR_GENERAL;
8071 if (RetCode == SK_PNMI_ERR_OK) {
8072 *pLen = sizeof(SK_U32);
8074 else {
8076 *pLen = 0;
8078 return (RetCode);
8080 #endif /* SK_DIAG_SUPPORT */
8082 /*****************************************************************************
8084 * Vct - OID handler function of OIDs
8086 * Description:
8087 * The code is simple. No description necessary.
8089 * Returns:
8090 * SK_PNMI_ERR_OK The request was performed successfully.
8091 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
8092 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
8093 * the correct data (e.g. a 32bit value is
8094 * needed, but a 16 bit value was passed).
8095 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
8096 * exist (e.g. port instance 3 on a two port
8097 * adapter).
8098 * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed.
8102 PNMI_STATIC int Vct(
8103 SK_AC *pAC, /* Pointer to adapter context */
8104 SK_IOC IoC, /* IO context handle */
8105 int Action, /* GET/PRESET/SET action */
8106 SK_U32 Id, /* Object ID that is to be processed */
8107 char *pBuf, /* Buffer used for the management data transfer */
8108 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
8109 SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */
8110 unsigned int TableIndex, /* Index to the Id table */
8111 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
8113 SK_GEPORT *pPrt;
8114 SK_PNMI_VCT *pVctBackupData;
8115 SK_U32 LogPortMax;
8116 SK_U32 PhysPortMax;
8117 SK_U32 PhysPortIndex;
8118 SK_U32 Limit;
8119 SK_U32 Offset;
8120 SK_BOOL Link;
8121 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
8122 int i;
8123 SK_EVPARA Para;
8124 SK_U32 CableLength;
8127 * Calculate the port indexes from the instance.
8129 PhysPortMax = pAC->GIni.GIMacsFound;
8130 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
8132 /* Dual net mode? */
8133 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
8134 LogPortMax--;
8137 if ((Instance != (SK_U32) (-1))) {
8138 /* Check instance range. */
8139 if ((Instance < 2) || (Instance > LogPortMax)) {
8140 *pLen = 0;
8141 return (SK_PNMI_ERR_UNKNOWN_INST);
8144 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
8145 PhysPortIndex = NetIndex;
8147 else {
8148 PhysPortIndex = Instance - 2;
8150 Limit = PhysPortIndex + 1;
8152 else {
8154 * Instance == (SK_U32) (-1), get all Instances of that OID.
8156 * Not implemented yet. May be used in future releases.
8158 PhysPortIndex = 0;
8159 Limit = PhysPortMax;
8162 pPrt = &pAC->GIni.GP[PhysPortIndex];
8163 if (pPrt->PHWLinkUp) {
8164 Link = SK_TRUE;
8166 else {
8167 Link = SK_FALSE;
8170 /* Check MAC type */
8171 if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
8172 *pLen = 0;
8173 return (SK_PNMI_ERR_GENERAL);
8176 /* Initialize backup data pointer. */
8177 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
8179 /* Check action type */
8180 if (Action == SK_PNMI_GET) {
8181 /* Check length */
8182 switch (Id) {
8184 case OID_SKGE_VCT_GET:
8185 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
8186 *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
8187 return (SK_PNMI_ERR_TOO_SHORT);
8189 break;
8191 case OID_SKGE_VCT_STATUS:
8192 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
8193 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
8194 return (SK_PNMI_ERR_TOO_SHORT);
8196 break;
8198 default:
8199 *pLen = 0;
8200 return (SK_PNMI_ERR_GENERAL);
8203 /* Get value */
8204 Offset = 0;
8205 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8206 switch (Id) {
8208 case OID_SKGE_VCT_GET:
8209 if ((Link == SK_FALSE) &&
8210 (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
8211 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
8212 if (RetCode == 0) {
8213 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
8214 pAC->Pnmi.VctStatus[PhysPortIndex] |=
8215 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
8217 /* Copy results for later use to PNMI struct. */
8218 for (i = 0; i < 4; i++) {
8219 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
8220 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
8221 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
8224 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
8225 CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
8227 else {
8228 CableLength = 0;
8230 pVctBackupData->PMdiPairLen[i] = CableLength;
8231 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
8234 Para.Para32[0] = PhysPortIndex;
8235 Para.Para32[1] = -1;
8236 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
8237 SkEventDispatcher(pAC, IoC);
8239 else {
8240 ; /* VCT test is running. */
8244 /* Get all results. */
8245 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
8246 Offset += sizeof(SK_U8);
8247 *(pBuf + Offset) = pPrt->PCableLen;
8248 Offset += sizeof(SK_U8);
8249 for (i = 0; i < 4; i++) {
8250 SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
8251 Offset += sizeof(SK_U32);
8253 for (i = 0; i < 4; i++) {
8254 *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
8255 Offset += sizeof(SK_U8);
8258 RetCode = SK_PNMI_ERR_OK;
8259 break;
8261 case OID_SKGE_VCT_STATUS:
8262 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
8263 Offset += sizeof(SK_U8);
8264 RetCode = SK_PNMI_ERR_OK;
8265 break;
8267 default:
8268 *pLen = 0;
8269 return (SK_PNMI_ERR_GENERAL);
8271 } /* for */
8272 *pLen = Offset;
8273 return (RetCode);
8275 } /* if SK_PNMI_GET */
8278 * From here SET or PRESET action. Check if the passed
8279 * buffer length is plausible.
8282 /* Check length */
8283 switch (Id) {
8284 case OID_SKGE_VCT_SET:
8285 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
8286 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
8287 return (SK_PNMI_ERR_TOO_SHORT);
8289 break;
8291 default:
8292 *pLen = 0;
8293 return (SK_PNMI_ERR_GENERAL);
8297 * Perform preset or set.
8300 /* VCT does not support PRESET action. */
8301 if (Action == SK_PNMI_PRESET) {
8302 return (SK_PNMI_ERR_OK);
8305 Offset = 0;
8306 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8307 switch (Id) {
8308 case OID_SKGE_VCT_SET: /* Start VCT test. */
8309 if (Link == SK_FALSE) {
8310 SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
8312 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
8313 if (RetCode == 0) { /* RetCode: 0 => Start! */
8314 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
8315 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8316 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
8319 * Start VCT timer counter.
8321 SK_MEMSET((char *) &Para, 0, sizeof(Para));
8322 Para.Para32[0] = PhysPortIndex;
8323 Para.Para32[1] = -1;
8324 SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
8325 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
8326 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8327 RetCode = SK_PNMI_ERR_OK;
8329 else { /* RetCode: 2 => Running! */
8330 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8331 RetCode = SK_PNMI_ERR_OK;
8334 else { /* RetCode: 4 => Link! */
8335 RetCode = 4;
8336 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8337 RetCode = SK_PNMI_ERR_OK;
8339 Offset += sizeof(SK_U32);
8340 break;
8342 default:
8343 *pLen = 0;
8344 return (SK_PNMI_ERR_GENERAL);
8346 } /* for */
8347 *pLen = Offset;
8348 return (RetCode);
8350 } /* Vct */
8353 PNMI_STATIC void CheckVctStatus(
8354 SK_AC *pAC,
8355 SK_IOC IoC,
8356 char *pBuf,
8357 SK_U32 Offset,
8358 SK_U32 PhysPortIndex)
8360 SK_GEPORT *pPrt;
8361 SK_PNMI_VCT *pVctData;
8362 SK_U32 RetCode;
8364 pPrt = &pAC->GIni.GP[PhysPortIndex];
8366 pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
8367 pVctData->VctStatus = SK_PNMI_VCT_NONE;
8369 if (!pPrt->PHWLinkUp) {
8371 /* Was a VCT test ever made before? */
8372 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8373 if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
8374 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8376 else {
8377 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8381 /* Check VCT test status. */
8382 RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
8383 if (RetCode == 2) { /* VCT test is running. */
8384 pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
8386 else { /* VCT data was copied to pAC here. Check PENDING state. */
8387 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
8388 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8392 if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
8393 pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
8396 else {
8398 /* Was a VCT test ever made before? */
8399 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8400 pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8401 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8404 /* DSP only valid in 100/1000 modes. */
8405 if (pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed !=
8406 SK_LSPEED_STAT_10MBPS) {
8407 pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
8410 } /* CheckVctStatus */
8413 /*****************************************************************************
8415 * SkPnmiGenIoctl - Handles new generic PNMI IOCTL, calls the needed
8416 * PNMI function depending on the subcommand and
8417 * returns all data belonging to the complete database
8418 * or OID request.
8420 * Description:
8421 * Looks up the requested subcommand, calls the corresponding handler
8422 * function and passes all required parameters to it.
8423 * The function is called by the driver. It is needed to handle the new
8424 * generic PNMI IOCTL. This IOCTL is given to the driver and contains both
8425 * the OID and a subcommand to decide what kind of request has to be done.
8427 * Returns:
8428 * SK_PNMI_ERR_OK The request was successfully performed
8429 * SK_PNMI_ERR_GENERAL A general severe internal error occured
8430 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
8431 * the data.
8432 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
8433 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
8434 * exist (e.g. port instance 3 on a two port
8435 * adapter.
8437 int SkPnmiGenIoctl(
8438 SK_AC *pAC, /* Pointer to adapter context struct */
8439 SK_IOC IoC, /* I/O context */
8440 void *pBuf, /* Buffer used for the management data transfer */
8441 unsigned int *pLen, /* Length of buffer */
8442 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
8444 SK_I32 Mode; /* Store value of subcommand. */
8445 SK_U32 Oid; /* Store value of OID. */
8446 int ReturnCode; /* Store return value to show status of PNMI action. */
8447 int HeaderLength; /* Length of desired action plus OID. */
8449 ReturnCode = SK_PNMI_ERR_GENERAL;
8451 SK_MEMCPY(&Mode, pBuf, sizeof(SK_I32));
8452 SK_MEMCPY(&Oid, (char *) pBuf + sizeof(SK_I32), sizeof(SK_U32));
8453 HeaderLength = sizeof(SK_I32) + sizeof(SK_U32);
8454 *pLen = *pLen - HeaderLength;
8455 SK_MEMCPY((char *) pBuf + sizeof(SK_I32), (char *) pBuf + HeaderLength, *pLen);
8457 switch(Mode) {
8458 case SK_GET_SINGLE_VAR:
8459 ReturnCode = SkPnmiGetVar(pAC, IoC, Oid,
8460 (char *) pBuf + sizeof(SK_I32), pLen,
8461 ((SK_U32) (-1)), NetIndex);
8462 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8463 *pLen = *pLen + sizeof(SK_I32);
8464 break;
8465 case SK_PRESET_SINGLE_VAR:
8466 ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid,
8467 (char *) pBuf + sizeof(SK_I32), pLen,
8468 ((SK_U32) (-1)), NetIndex);
8469 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8470 *pLen = *pLen + sizeof(SK_I32);
8471 break;
8472 case SK_SET_SINGLE_VAR:
8473 ReturnCode = SkPnmiSetVar(pAC, IoC, Oid,
8474 (char *) pBuf + sizeof(SK_I32), pLen,
8475 ((SK_U32) (-1)), NetIndex);
8476 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8477 *pLen = *pLen + sizeof(SK_I32);
8478 break;
8479 case SK_GET_FULL_MIB:
8480 ReturnCode = SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8481 break;
8482 case SK_PRESET_FULL_MIB:
8483 ReturnCode = SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8484 break;
8485 case SK_SET_FULL_MIB:
8486 ReturnCode = SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8487 break;
8488 default:
8489 break;
8492 return (ReturnCode);
8494 } /* SkGeIocGen */