blob: d0e33cbd6ad48055ce40dd7472eefb52a3963a27 [file] [log] [blame]
wdenkeb20ad32003-09-05 23:19:14 +00001/*****************************************************************************
2 *
3 * Name: skgepnmi.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.102 $
6 * Date: $Date: 2002/12/16 14:03:24 $
7 * Purpose: Private Network Management Interface
8 *
9 ****************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * The information in this file is provided "AS IS" without warranty.
21 *
22 ******************************************************************************/
23
24/*****************************************************************************
25 *
26 * History:
27 *
28 * $Log: skgepnmi.c,v $
29 * Revision 1.102 2002/12/16 14:03:24 tschilli
30 * VCT code in Vct() changed.
wdenk9c53f402003-10-15 23:53:47 +000031 *
wdenkeb20ad32003-09-05 23:19:14 +000032 * Revision 1.101 2002/12/16 09:04:10 tschilli
33 * Code for VCT handling added.
wdenk9c53f402003-10-15 23:53:47 +000034 *
wdenkeb20ad32003-09-05 23:19:14 +000035 * Revision 1.100 2002/09/26 14:28:13 tschilli
36 * For XMAC the values in the SK_PNMI_PORT Port struct are copied to
37 * the new SK_PNMI_PORT BufPort struct during a MacUpdate() call.
38 * These values are used when GetPhysStatVal() is called. With this
39 * mechanism you get the best results when software corrections for
40 * counters are needed. Example: RX_LONGFRAMES.
wdenk9c53f402003-10-15 23:53:47 +000041 *
wdenkeb20ad32003-09-05 23:19:14 +000042 * Revision 1.99 2002/09/17 12:31:19 tschilli
43 * OID_SKGE_TX_HW_ERROR_CTS, OID_SKGE_OUT_ERROR_CTS, OID_GEN_XMIT_ERROR:
44 * Double count of SK_PNMI_HTX_EXCESS_COL in function General() removed.
45 * OID_PNP_CAPABILITIES: sizeof(SK_PM_WAKE_UP_CAPABILITIES) changed to
46 * sizeof(SK_PNP_CAPABILITIES) in function PowerManagement().
wdenk9c53f402003-10-15 23:53:47 +000047 *
wdenkeb20ad32003-09-05 23:19:14 +000048 * Revision 1.98 2002/09/10 09:00:03 rwahl
49 * Adapted boolean definitions according sktypes.
wdenk9c53f402003-10-15 23:53:47 +000050 *
wdenkeb20ad32003-09-05 23:19:14 +000051 * Revision 1.97 2002/09/05 15:07:03 rwahl
52 * Editorial changes.
wdenk9c53f402003-10-15 23:53:47 +000053 *
wdenkeb20ad32003-09-05 23:19:14 +000054 * Revision 1.96 2002/09/05 11:04:14 rwahl
55 * - Rx/Tx packets statistics of virtual port were zero on link down (#10750)
56 * - For GMAC the overflow IRQ for Rx longframe counter was not counted.
57 * - Incorrect calculation for oids OID_SKGE_RX_HW_ERROR_CTS,
58 * OID_SKGE_IN_ERRORS_CTS, OID_GEN_RCV_ERROR.
59 * - Moved correction for OID_SKGE_STAT_RX_TOO_LONG to GetPhysStatVal().
60 * - Editorial changes.
wdenk9c53f402003-10-15 23:53:47 +000061 *
wdenkeb20ad32003-09-05 23:19:14 +000062 * Revision 1.95 2002/09/04 08:53:37 rwahl
63 * - Incorrect statistics for Rx_too_long counter with jumbo frame (#10751)
64 * - StatRxFrameTooLong & StatRxPMaccErr counters were not reset.
65 * - Fixed compiler warning for debug msg arg types.
wdenk9c53f402003-10-15 23:53:47 +000066 *
wdenkeb20ad32003-09-05 23:19:14 +000067 * Revision 1.94 2002/08/09 15:42:14 rwahl
68 * - Fixed StatAddr table for GMAC.
69 * - VirtualConf(): returned indeterminated status for speed oids if no
70 * active port.
wdenk9c53f402003-10-15 23:53:47 +000071 *
wdenkeb20ad32003-09-05 23:19:14 +000072 * Revision 1.93 2002/08/09 11:04:59 rwahl
73 * Added handler for link speed caps.
wdenk9c53f402003-10-15 23:53:47 +000074 *
wdenkeb20ad32003-09-05 23:19:14 +000075 * Revision 1.92 2002/08/09 09:43:03 rwahl
76 * - Added handler for NDIS OID_PNP_xxx ids.
wdenk9c53f402003-10-15 23:53:47 +000077 *
wdenkeb20ad32003-09-05 23:19:14 +000078 * Revision 1.91 2002/07/17 19:53:03 rwahl
79 * - Added StatOvrflwBit table for XMAC & GMAC.
80 * - Extended StatAddr table for GMAC. Added check of number of counters
81 * in enumeration and size of StatAddr table on init level.
82 * - Added use of GIFunc table.
83 * - ChipSet is not static anymore,
84 * - Extended SIRQ event handler for both mac types.
85 * - Fixed rx short counter bug (#10620)
86 * - Added handler for oids SKGE_SPEED_MODE & SKGE_SPEED_STATUS.
87 * - Extendet GetPhysStatVal() for GMAC.
88 * - Editorial changes.
wdenk9c53f402003-10-15 23:53:47 +000089 *
wdenkeb20ad32003-09-05 23:19:14 +000090 * Revision 1.90 2002/05/22 08:56:25 rwahl
91 * - Moved OID table to separate source file.
92 * - Fix: TX_DEFFERAL counter incremented in full-duplex mode.
93 * - Use string definitions for error msgs.
wdenk9c53f402003-10-15 23:53:47 +000094 *
wdenkeb20ad32003-09-05 23:19:14 +000095 * Revision 1.89 2001/09/18 10:01:30 mkunz
96 * some OID's fixed for dualnetmode
wdenk9c53f402003-10-15 23:53:47 +000097 *
wdenkeb20ad32003-09-05 23:19:14 +000098 * Revision 1.88 2001/08/02 07:58:08 rwahl
99 * - Fixed NetIndex to csum module at ResetCounter().
wdenk9c53f402003-10-15 23:53:47 +0000100 *
wdenkeb20ad32003-09-05 23:19:14 +0000101 * Revision 1.87 2001/04/06 13:35:09 mkunz
102 * -Bugs fixed in handling of OID_SKGE_MTU and the VPD OID's
wdenk9c53f402003-10-15 23:53:47 +0000103 *
wdenkeb20ad32003-09-05 23:19:14 +0000104 * Revision 1.86 2001/03/09 09:18:03 mkunz
105 * Changes in SK_DBG_MSG
wdenk9c53f402003-10-15 23:53:47 +0000106 *
wdenkeb20ad32003-09-05 23:19:14 +0000107 * Revision 1.85 2001/03/08 09:37:31 mkunz
108 * Bugfix in ResetCounter for Pnmi.Port structure
wdenk9c53f402003-10-15 23:53:47 +0000109 *
wdenkeb20ad32003-09-05 23:19:14 +0000110 * Revision 1.84 2001/03/06 09:04:55 mkunz
111 * Made some changes in instance calculation
wdenk9c53f402003-10-15 23:53:47 +0000112 *
wdenkeb20ad32003-09-05 23:19:14 +0000113 * Revision 1.83 2001/02/15 09:15:32 mkunz
114 * Necessary changes for dual net mode added
wdenk9c53f402003-10-15 23:53:47 +0000115 *
wdenkeb20ad32003-09-05 23:19:14 +0000116 * Revision 1.82 2001/02/07 08:24:19 mkunz
117 * -Made changes in handling of OID_SKGE_MTU
wdenk9c53f402003-10-15 23:53:47 +0000118 *
wdenkeb20ad32003-09-05 23:19:14 +0000119 * Revision 1.81 2001/02/06 09:58:00 mkunz
120 * -Vpd bug fixed
121 * -OID_SKGE_MTU added
122 * -pnmi support for dual net mode. Interface function and macros extended
wdenk9c53f402003-10-15 23:53:47 +0000123 *
wdenkeb20ad32003-09-05 23:19:14 +0000124 * Revision 1.80 2001/01/22 13:41:35 rassmann
125 * Supporting two nets on dual-port adapters.
wdenk9c53f402003-10-15 23:53:47 +0000126 *
wdenkeb20ad32003-09-05 23:19:14 +0000127 * Revision 1.79 2000/12/05 14:57:40 cgoos
128 * SetStruct failed before first Link Up (link mode of virtual
129 * port "INDETERMINATED").
wdenk9c53f402003-10-15 23:53:47 +0000130 *
wdenkeb20ad32003-09-05 23:19:14 +0000131 * Revision 1.78 2000/09/12 10:44:58 cgoos
132 * Fixed SK_PNMI_STORE_U32 calls with typecasted argument.
wdenk9c53f402003-10-15 23:53:47 +0000133 *
wdenkeb20ad32003-09-05 23:19:14 +0000134 * Revision 1.77 2000/09/07 08:10:19 rwahl
135 * - Modified algorithm for 64bit NDIS statistic counters;
136 * returns 64bit or 32bit value depending on passed buffer
137 * size. Indicate capability for 64bit NDIS counter, if passed
138 * buffer size is zero. OID_GEN_XMIT_ERROR, OID_GEN_RCV_ERROR,
139 * and OID_GEN_RCV_NO_BUFFER handled as 64bit counter, too.
140 * - corrected OID_SKGE_RLMT_PORT_PREFERRED.
wdenk9c53f402003-10-15 23:53:47 +0000141 *
wdenkeb20ad32003-09-05 23:19:14 +0000142 * Revision 1.76 2000/08/03 15:23:39 rwahl
143 * - Correction for FrameTooLong counter has to be moved to OID handling
144 * routines (instead of statistic counter routine).
145 * - Fix in XMAC Reset Event handling: Only offset counter for hardware
146 * statistic registers are updated.
wdenk9c53f402003-10-15 23:53:47 +0000147 *
wdenkeb20ad32003-09-05 23:19:14 +0000148 * Revision 1.75 2000/08/01 16:46:05 rwahl
149 * - Added StatRxLongFrames counter and correction of FrameTooLong counter.
150 * - Added directive to control width (default = 32bit) of NDIS statistic
151 * counters (SK_NDIS_64BIT_CTR).
wdenk9c53f402003-10-15 23:53:47 +0000152 *
wdenkeb20ad32003-09-05 23:19:14 +0000153 * Revision 1.74 2000/07/04 11:41:53 rwahl
154 * - Added volition connector type.
wdenk9c53f402003-10-15 23:53:47 +0000155 *
wdenkeb20ad32003-09-05 23:19:14 +0000156 * Revision 1.73 2000/03/15 16:33:10 rwahl
157 * Fixed bug 10510; wrong reset of virtual port statistic counters.
wdenk9c53f402003-10-15 23:53:47 +0000158 *
wdenkeb20ad32003-09-05 23:19:14 +0000159 * Revision 1.72 1999/12/06 16:15:53 rwahl
160 * Fixed problem of instance range for current and factory MAC address.
wdenk9c53f402003-10-15 23:53:47 +0000161 *
wdenkeb20ad32003-09-05 23:19:14 +0000162 * Revision 1.71 1999/12/06 10:14:20 rwahl
163 * Fixed bug 10476; set operation for PHY_OPERATION_MODE.
wdenk9c53f402003-10-15 23:53:47 +0000164 *
wdenkeb20ad32003-09-05 23:19:14 +0000165 * Revision 1.70 1999/11/22 13:33:34 cgoos
166 * Changed license header to GPL.
wdenk9c53f402003-10-15 23:53:47 +0000167 *
wdenkeb20ad32003-09-05 23:19:14 +0000168 * Revision 1.69 1999/10/18 11:42:15 rwahl
169 * Added typecasts for checking event dependent param (debug only).
wdenk9c53f402003-10-15 23:53:47 +0000170 *
wdenkeb20ad32003-09-05 23:19:14 +0000171 * Revision 1.68 1999/10/06 09:35:59 cgoos
172 * Added state check to PHY_READ call (hanged if called during startup).
wdenk9c53f402003-10-15 23:53:47 +0000173 *
wdenkeb20ad32003-09-05 23:19:14 +0000174 * Revision 1.67 1999/09/22 09:53:20 rwahl
175 * - Read Broadcom register for updating fcs error counter (1000Base-T).
176 *
177 * Revision 1.66 1999/08/26 13:47:56 rwahl
178 * Added SK_DRIVER_SENDEVENT when queueing RLMT_CHANGE_THRES trap.
wdenk9c53f402003-10-15 23:53:47 +0000179 *
wdenkeb20ad32003-09-05 23:19:14 +0000180 * Revision 1.65 1999/07/26 07:49:35 cgoos
181 * Added two typecasts to avoid compiler warnings.
wdenk9c53f402003-10-15 23:53:47 +0000182 *
wdenkeb20ad32003-09-05 23:19:14 +0000183 * Revision 1.64 1999/05/20 09:24:12 cgoos
184 * Changes for 1000Base-T (sensors, Master/Slave).
185 *
186 * Revision 1.63 1999/04/13 15:11:58 mhaveman
187 * Moved include of rlmt.h to header skgepnmi.h because some macros
188 * are needed there.
wdenk9c53f402003-10-15 23:53:47 +0000189 *
wdenkeb20ad32003-09-05 23:19:14 +0000190 * Revision 1.62 1999/04/13 15:08:07 mhaveman
191 * Replaced again SK_RLMT_CHECK_LINK with SK_PNMI_RLMT_MODE_CHK_LINK
192 * to grant unified interface by only using the PNMI header file.
193 * SK_PNMI_RLMT_MODE_CHK_LINK is defined the same as SK_RLMT_CHECK_LINK.
wdenk9c53f402003-10-15 23:53:47 +0000194 *
wdenkeb20ad32003-09-05 23:19:14 +0000195 * Revision 1.61 1999/04/13 15:02:48 mhaveman
196 * Changes caused by review:
197 * -Changed some comments
198 * -Removed redundant check for OID_SKGE_PHYS_FAC_ADDR
199 * -Optimized PRESET check.
200 * -Meaning of error SK_ADDR_DUPLICATE_ADDRESS changed. Set of same
201 * address will now not cause this error. Removed corresponding check.
wdenk9c53f402003-10-15 23:53:47 +0000202 *
wdenkeb20ad32003-09-05 23:19:14 +0000203 * Revision 1.60 1999/03/23 10:41:23 mhaveman
204 * Added comments.
wdenk9c53f402003-10-15 23:53:47 +0000205 *
wdenkeb20ad32003-09-05 23:19:14 +0000206 * Revision 1.59 1999/02/19 08:01:28 mhaveman
207 * Fixed bug 10372 that after counter reset all ports were displayed
208 * as inactive.
wdenk9c53f402003-10-15 23:53:47 +0000209 *
wdenkeb20ad32003-09-05 23:19:14 +0000210 * Revision 1.58 1999/02/16 18:04:47 mhaveman
211 * Fixed problem of twisted OIDs SENSOR_WAR_TIME and SENSOR_ERR_TIME.
wdenk9c53f402003-10-15 23:53:47 +0000212 *
wdenkeb20ad32003-09-05 23:19:14 +0000213 * Revision 1.56 1999/01/27 12:29:11 mhaveman
214 * SkTimerStart was called with time value in milli seconds but needs
215 * micro seconds.
wdenk9c53f402003-10-15 23:53:47 +0000216 *
wdenkeb20ad32003-09-05 23:19:14 +0000217 * Revision 1.55 1999/01/25 15:00:38 mhaveman
218 * Added support to allow multiple ports to be active. If this feature in
219 * future will be used, the Management Data Base variables PORT_ACTIVE
220 * and PORT_PREFERED should be moved to the port specific part of RLMT.
221 * Currently they return the values of the first active physical port
222 * found. A set to the virtual port will actually change all active
223 * physical ports. A get returns the melted values of all active physical
224 * ports. If the port values differ a return value INDETERMINATED will
225 * be returned. This effects especially the CONF group.
wdenk9c53f402003-10-15 23:53:47 +0000226 *
wdenkeb20ad32003-09-05 23:19:14 +0000227 * Revision 1.54 1999/01/19 10:10:22 mhaveman
228 * -Fixed bug 10354: Counter values of virtual port were wrong after port
229 * switches
230 * -Added check if a switch to the same port is notified.
wdenk9c53f402003-10-15 23:53:47 +0000231 *
wdenkeb20ad32003-09-05 23:19:14 +0000232 * Revision 1.53 1999/01/07 09:25:21 mhaveman
233 * Forgot to initialize a variable.
wdenk9c53f402003-10-15 23:53:47 +0000234 *
wdenkeb20ad32003-09-05 23:19:14 +0000235 * Revision 1.52 1999/01/05 10:34:33 mhaveman
236 * Fixed little error in RlmtChangeEstimate calculation.
wdenk9c53f402003-10-15 23:53:47 +0000237 *
wdenkeb20ad32003-09-05 23:19:14 +0000238 * Revision 1.51 1999/01/05 09:59:07 mhaveman
239 * -Moved timer start to init level 2
240 * -Redesigned port switch average calculation to avoid 64bit
241 * arithmetic.
wdenk9c53f402003-10-15 23:53:47 +0000242 *
wdenkeb20ad32003-09-05 23:19:14 +0000243 * Revision 1.50 1998/12/10 15:13:59 mhaveman
244 * -Fixed: PHYS_CUR_ADDR returned wrong addresses
245 * -Fixed: RLMT_PORT_PREFERED and RLMT_CHANGE_THRES preset returned
246 * always BAD_VALUE.
247 * -Fixed: TRAP buffer seemed to sometimes suddenly empty
wdenk9c53f402003-10-15 23:53:47 +0000248 *
wdenkeb20ad32003-09-05 23:19:14 +0000249 * Revision 1.49 1998/12/09 16:17:07 mhaveman
250 * Fixed: Couldnot delete VPD keys on UNIX.
wdenk9c53f402003-10-15 23:53:47 +0000251 *
wdenkeb20ad32003-09-05 23:19:14 +0000252 * Revision 1.48 1998/12/09 14:11:10 mhaveman
253 * -Add: Debugmessage for XMAC_RESET supressed to minimize output.
254 * -Fixed: RlmtChangeThreshold will now be initialized.
255 * -Fixed: VPD_ENTRIES_LIST extended value with unnecessary space char.
256 * -Fixed: On VPD key creation an invalid key name could be created
257 * (e.g. A5)
258 * -Some minor changes in comments and code.
wdenk9c53f402003-10-15 23:53:47 +0000259 *
wdenkeb20ad32003-09-05 23:19:14 +0000260 * Revision 1.47 1998/12/08 16:00:31 mhaveman
261 * -Fixed: For RLMT_PORT_ACTIVE will now be returned a 0 if no port
262 * is active.
263 * -Fixed: For the RLMT statistics group only the last value was
264 * returned and the rest of the buffer was filled with 0xff
265 * -Fixed: Mysteriously the preset on RLMT_MODE still returned
266 * BAD_VALUE.
267 * Revision 1.46 1998/12/08 10:04:56 mhaveman
268 * -Fixed: Preset on RLMT_MODE returned always BAD_VALUE error.
269 * -Fixed: Alignment error in GetStruct
270 * -Fixed: If for Get/Preset/SetStruct the buffer size is equal or
271 * larger than SK_PNMI_MIN_STRUCT_SIZE the return value is stored
272 * to the buffer. In this case the caller should always return
273 * ok to its upper routines. Only if the buffer size is less
274 * than SK_PNMI_MIN_STRUCT_SIZE and the return value is unequal
275 * to 0, an error should be returned by the caller.
276 * -Fixed: Wrong number of instances with RLMT statistic.
277 * -Fixed: Return now SK_LMODE_STAT_UNKNOWN if the LinkModeStatus is 0.
wdenk9c53f402003-10-15 23:53:47 +0000278 *
wdenkeb20ad32003-09-05 23:19:14 +0000279 * Revision 1.45 1998/12/03 17:17:24 mhaveman
280 * -Removed for VPD create action the buffer size limitation to 4 bytes.
281 * -Pass now physical/active physical port to ADDR for CUR_ADDR set
wdenk9c53f402003-10-15 23:53:47 +0000282 *
wdenkeb20ad32003-09-05 23:19:14 +0000283 * Revision 1.44 1998/12/03 15:14:35 mhaveman
284 * Another change to Vpd instance evaluation.
285 *
286 * Revision 1.43 1998/12/03 14:18:10 mhaveman
287 * -Fixed problem in PnmiSetStruct. It was impossible to set any value.
288 * -Removed VPD key evaluation for VPD_FREE_BYTES and VPD_ACTION.
289 *
290 * Revision 1.42 1998/12/03 11:31:47 mhaveman
291 * Inserted cast to satisfy lint.
wdenk9c53f402003-10-15 23:53:47 +0000292 *
wdenkeb20ad32003-09-05 23:19:14 +0000293 * Revision 1.41 1998/12/03 11:28:16 mhaveman
294 * Removed SK_PNMI_CHECKPTR
wdenk9c53f402003-10-15 23:53:47 +0000295 *
wdenkeb20ad32003-09-05 23:19:14 +0000296 * Revision 1.40 1998/12/03 11:19:07 mhaveman
297 * Fixed problems
298 * -A set to virtual port will now be ignored. A set with broadcast
299 * address to any port will be ignored.
300 * -GetStruct function made VPD instance calculation wrong.
301 * -Prefered port returned -1 instead of 0.
wdenk9c53f402003-10-15 23:53:47 +0000302 *
wdenkeb20ad32003-09-05 23:19:14 +0000303 * Revision 1.39 1998/11/26 15:30:29 mhaveman
304 * Added sense mode to link mode.
wdenk9c53f402003-10-15 23:53:47 +0000305 *
wdenkeb20ad32003-09-05 23:19:14 +0000306 * Revision 1.38 1998/11/23 15:34:00 mhaveman
307 * -Fixed bug for RX counters. On an RX overflow interrupt the high
308 * words of all RX counters were incremented.
309 * -SET operations on FLOWCTRL_MODE and LINK_MODE accept now the
310 * value 0, which has no effect. It is usefull for multiple instance
311 * SETs.
wdenk9c53f402003-10-15 23:53:47 +0000312 *
wdenkeb20ad32003-09-05 23:19:14 +0000313 * Revision 1.37 1998/11/20 08:02:04 mhaveman
314 * -Fixed: Ports were compared with MAX_SENSORS
315 * -Fixed: Crash in GetTrapEntry with MEMSET macro
316 * -Fixed: Conversions between physical, logical port index and instance
wdenk9c53f402003-10-15 23:53:47 +0000317 *
wdenkeb20ad32003-09-05 23:19:14 +0000318 * Revision 1.36 1998/11/16 07:48:53 mhaveman
319 * Casted SK_DRIVER_SENDEVENT with (void) to eleminate compiler warnings
320 * on Solaris.
wdenk9c53f402003-10-15 23:53:47 +0000321 *
wdenkeb20ad32003-09-05 23:19:14 +0000322 * Revision 1.35 1998/11/16 07:45:34 mhaveman
323 * SkAddrOverride now returns value and will be checked.
324 *
325 * Revision 1.34 1998/11/10 13:40:37 mhaveman
326 * Needed to change interface, because NT driver needs a return value
327 * of needed buffer space on TOO_SHORT errors. Therefore all
328 * SkPnmiGet/Preset/Set functions now have a pointer to the length
329 * parameter, where the needed space on error is returned.
wdenk9c53f402003-10-15 23:53:47 +0000330 *
wdenkeb20ad32003-09-05 23:19:14 +0000331 * Revision 1.33 1998/11/03 13:52:46 mhaveman
332 * Made file lint conform.
wdenk9c53f402003-10-15 23:53:47 +0000333 *
wdenkeb20ad32003-09-05 23:19:14 +0000334 * Revision 1.32 1998/11/03 13:19:07 mhaveman
335 * The events SK_HWEV_SET_LMODE and SK_HWEV_SET_FLOWMODE pass now in
336 * Para32[0] the physical MAC index and in Para32[1] the new mode.
wdenk9c53f402003-10-15 23:53:47 +0000337 *
wdenkeb20ad32003-09-05 23:19:14 +0000338 * Revision 1.31 1998/11/03 12:30:40 gklug
339 * fix: compiler warning memset
340 *
341 * Revision 1.30 1998/11/03 12:04:46 mhaveman
342 * Fixed problem in SENSOR_VALUE, which wrote beyond the buffer end
343 * Fixed alignment problem with CHIPSET.
344 *
345 * Revision 1.29 1998/11/02 11:23:54 mhaveman
346 * Corrected SK_ERROR_LOG to SK_ERR_LOG. Sorry.
wdenk9c53f402003-10-15 23:53:47 +0000347 *
wdenkeb20ad32003-09-05 23:19:14 +0000348 * Revision 1.28 1998/11/02 10:47:16 mhaveman
349 * Added syslog messages for internal errors.
wdenk9c53f402003-10-15 23:53:47 +0000350 *
wdenkeb20ad32003-09-05 23:19:14 +0000351 * Revision 1.27 1998/10/30 15:48:06 mhaveman
352 * Fixed problems after simulation of SK_PNMI_EVT_CHG_EST_TIMER and
353 * RlmtChangeThreshold calculation.
wdenk9c53f402003-10-15 23:53:47 +0000354 *
wdenkeb20ad32003-09-05 23:19:14 +0000355 * Revision 1.26 1998/10/29 15:36:55 mhaveman
356 * -Fixed bug in trap buffer handling.
357 * -OID_SKGE_DRIVER_DESCR, OID_SKGE_DRIVER_VERSION, OID_SKGE_HW_DESCR,
358 * OID_SKGE_HW_VERSION, OID_SKGE_VPD_ENTRIES_LIST, OID_SKGE_VPD_KEY,
359 * OID_SKGE_VPD_VALUE, and OID_SKGE_SENSOR_DESCR return values with
360 * a leading octet before each string storing the string length.
361 * -Perform a RlmtUpdate during SK_PNMI_EVT_XMAC_RESET to minimize
362 * RlmtUpdate calls in GetStatVal.
363 * -Inserted SK_PNMI_CHECKFLAGS macro increase readability.
wdenk9c53f402003-10-15 23:53:47 +0000364 *
wdenkeb20ad32003-09-05 23:19:14 +0000365 * Revision 1.25 1998/10/29 08:50:36 mhaveman
366 * Fixed problems after second event simulation.
wdenk9c53f402003-10-15 23:53:47 +0000367 *
wdenkeb20ad32003-09-05 23:19:14 +0000368 * Revision 1.24 1998/10/28 08:44:37 mhaveman
369 * -Fixed alignment problem
370 * -Fixed problems during event simulation
371 * -Fixed sequence of error return code (INSTANCE -> ACCESS -> SHORT)
372 * -Changed type of parameter Instance back to SK_U32 because of VPD
373 * -Updated new VPD function calls
374 *
375 * Revision 1.23 1998/10/23 10:16:37 mhaveman
376 * Fixed bugs after buffer test simulation.
wdenk9c53f402003-10-15 23:53:47 +0000377 *
wdenkeb20ad32003-09-05 23:19:14 +0000378 * Revision 1.22 1998/10/21 13:23:52 mhaveman
379 * -Call syntax of SkOsGetTime() changed to SkOsGetTime(pAc).
380 * -Changed calculation of hundrets of seconds.
381 *
382 * Revision 1.20 1998/10/20 07:30:45 mhaveman
383 * Made type changes to unsigned integer where possible.
wdenk9c53f402003-10-15 23:53:47 +0000384 *
wdenkeb20ad32003-09-05 23:19:14 +0000385 * Revision 1.19 1998/10/19 10:51:30 mhaveman
386 * -Made Bug fixes after simulation run
387 * -Renamed RlmtMAC... to RlmtPort...
388 * -Marked workarounds with Errata comments
wdenk9c53f402003-10-15 23:53:47 +0000389 *
wdenkeb20ad32003-09-05 23:19:14 +0000390 * Revision 1.18 1998/10/14 07:50:08 mhaveman
391 * -For OID_SKGE_LINK_STATUS the link down detection has moved from RLMT
392 * to HWACCESS.
393 * -Provided all MEMCPY/MEMSET macros with (char *) pointers, because
394 * Solaris throwed warnings when mapping to bcopy/bset.
395 *
396 * Revision 1.17 1998/10/13 07:42:01 mhaveman
397 * -Added OIDs OID_SKGE_TRAP_NUMBER and OID_SKGE_ALL_DATA
398 * -Removed old cvs history entries
399 * -Renamed MacNumber to PortNumber
400 *
401 * Revision 1.16 1998/10/07 10:52:49 mhaveman
402 * -Inserted handling of some OID_GEN_ Ids for windows
403 * -Fixed problem with 803.2 statistic.
wdenk9c53f402003-10-15 23:53:47 +0000404 *
wdenkeb20ad32003-09-05 23:19:14 +0000405 * Revision 1.15 1998/10/01 09:16:29 mhaveman
406 * Added Debug messages for function call and UpdateFlag tracing.
wdenk9c53f402003-10-15 23:53:47 +0000407 *
wdenkeb20ad32003-09-05 23:19:14 +0000408 * Revision 1.14 1998/09/30 13:39:09 mhaveman
409 * -Reduced namings of 'MAC' by replacing them with 'PORT'.
410 * -Completed counting of OID_SKGE_RX_HW_ERROR_CTS,
411 * OID_SKGE_TX_HW_ERROR_CTS,
412 * OID_SKGE_IN_ERRORS_CTS, and OID_SKGE_OUT_ERROR_CTS.
413 * -SET check for RlmtMode
wdenk9c53f402003-10-15 23:53:47 +0000414 *
wdenkeb20ad32003-09-05 23:19:14 +0000415 * Revision 1.13 1998/09/28 13:13:08 mhaveman
416 * Hide strcmp, strlen, and strncpy behind macros SK_STRCMP, SK_STRLEN,
417 * and SK_STRNCPY. (Same reasons as for mem.. and MEM..)
wdenk9c53f402003-10-15 23:53:47 +0000418 *
wdenkeb20ad32003-09-05 23:19:14 +0000419 * Revision 1.12 1998/09/16 08:18:36 cgoos
420 * Fix: XM_INxx and XM_OUTxx called with different parameter order:
421 * sometimes IoC,Mac,... sometimes Mac,IoC,... Now always first variant.
422 * Fix: inserted "Pnmi." into some pAC->pDriverDescription / Version.
423 * Change: memset, memcpy to makros SK_MEMSET, SK_MEMCPY
424 *
425 * Revision 1.11 1998/09/04 17:01:45 mhaveman
426 * Added SyncCounter as macro and OID_SKGE_.._NO_DESCR_CTS to
427 * OID_SKGE_RX_NO_BUF_CTS.
wdenk9c53f402003-10-15 23:53:47 +0000428 *
wdenkeb20ad32003-09-05 23:19:14 +0000429 * Revision 1.10 1998/09/04 14:35:35 mhaveman
430 * Added macro counters, that are counted by driver.
wdenk9c53f402003-10-15 23:53:47 +0000431 *
wdenkeb20ad32003-09-05 23:19:14 +0000432 ****************************************************************************/
433
434
wdenkde887eb2003-09-10 18:20:28 +0000435#include <config.h>
436
wdenkeb20ad32003-09-05 23:19:14 +0000437static const char SysKonnectFileId[] =
438 "@(#) $Id: skgepnmi.c,v 1.102 2002/12/16 14:03:24 tschilli Exp $"
439 " (C) SysKonnect.";
440
441#include "h/skdrv1st.h"
442#include "h/sktypes.h"
443#include "h/xmac_ii.h"
444#include "h/skdebug.h"
445#include "h/skqueue.h"
446#include "h/skgepnmi.h"
447#include "h/skgesirq.h"
448#include "h/skcsum.h"
449#include "h/skvpd.h"
450#include "h/skgehw.h"
451#include "h/skgeinit.h"
452#include "h/skdrv2nd.h"
453#include "h/skgepnm2.h"
454#ifdef SK_POWER_MGMT
455#include "h/skgepmgt.h"
456#endif
457/* defines *******************************************************************/
458
459#ifndef DEBUG
460#define PNMI_STATIC static
461#else /* DEBUG */
462#define PNMI_STATIC
463#endif /* DEBUG */
464
465/*
466 * Public Function prototypes
467 */
468int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level);
469int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
470 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
471int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
472 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
473int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
474 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
475int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
476 unsigned int *pLen, SK_U32 NetIndex);
wdenk9c53f402003-10-15 23:53:47 +0000477int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
wdenkeb20ad32003-09-05 23:19:14 +0000478 unsigned int *pLen, SK_U32 NetIndex);
wdenk9c53f402003-10-15 23:53:47 +0000479int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
wdenkeb20ad32003-09-05 23:19:14 +0000480 unsigned int *pLen, SK_U32 NetIndex);
481int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
482
483
484/*
485 * Private Function prototypes
486 */
487
488PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
489 PhysPortIndex);
490PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
491 PhysPortIndex);
492PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac);
493PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
494PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
495 unsigned int PhysPortIndex, unsigned int StatIndex);
496PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
497 unsigned int StatIndex, SK_U32 NetIndex);
498PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
499PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
500 unsigned int *pEntries);
501PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr,
502 unsigned int KeyArrLen, unsigned int *pKeyNo);
503PNMI_STATIC int LookupId(SK_U32 Id);
504PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
505 unsigned int LastMac);
506PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
507 unsigned int *pLen, SK_U32 NetIndex);
508PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id,
509 char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
510PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
511PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
512 unsigned int PortIndex);
513PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
514 unsigned int SensorIndex);
515PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
516PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
517PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
518PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
519PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
520PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
521 unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
522PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
523
524/*
525 * Table to correlate OID with handler function and index to
526 * hardware register stored in StatAddress if applicable.
527 */
528#include "skgemib.c"
529
530/* global variables **********************************************************/
531
532/*
533 * Overflow status register bit table and corresponding counter
534 * dependent on MAC type - the number relates to the size of overflow
wdenk9c53f402003-10-15 23:53:47 +0000535 * mask returned by the pFnMacOverflow function
wdenkeb20ad32003-09-05 23:19:14 +0000536 */
537PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = {
Wolfgang Denka1be4762008-05-20 16:00:29 +0200538/* Bit0 */ { SK_PNMI_HTX, SK_PNMI_HTX_UNICAST},
539/* Bit1 */ { SK_PNMI_HTX_OCTETHIGH, SK_PNMI_HTX_BROADCAST},
540/* Bit2 */ { SK_PNMI_HTX_OCTETLOW, SK_PNMI_HTX_PMACC},
541/* Bit3 */ { SK_PNMI_HTX_BROADCAST, SK_PNMI_HTX_MULTICAST},
542/* Bit4 */ { SK_PNMI_HTX_MULTICAST, SK_PNMI_HTX_OCTETLOW},
543/* Bit5 */ { SK_PNMI_HTX_UNICAST, SK_PNMI_HTX_OCTETHIGH},
544/* Bit6 */ { SK_PNMI_HTX_LONGFRAMES, SK_PNMI_HTX_64},
545/* Bit7 */ { SK_PNMI_HTX_BURST, SK_PNMI_HTX_127},
546/* Bit8 */ { SK_PNMI_HTX_PMACC, SK_PNMI_HTX_255},
547/* Bit9 */ { SK_PNMI_HTX_MACC, SK_PNMI_HTX_511},
548/* Bit10 */ { SK_PNMI_HTX_SINGLE_COL, SK_PNMI_HTX_1023},
549/* Bit11 */ { SK_PNMI_HTX_MULTI_COL, SK_PNMI_HTX_MAX},
550/* Bit12 */ { SK_PNMI_HTX_EXCESS_COL, SK_PNMI_HTX_LONGFRAMES},
551/* Bit13 */ { SK_PNMI_HTX_LATE_COL, SK_PNMI_HTX_RESERVED},
552/* Bit14 */ { SK_PNMI_HTX_DEFFERAL, SK_PNMI_HTX_COL},
553/* Bit15 */ { SK_PNMI_HTX_EXCESS_DEF, SK_PNMI_HTX_LATE_COL},
554/* Bit16 */ { SK_PNMI_HTX_UNDERRUN, SK_PNMI_HTX_EXCESS_COL},
555/* Bit17 */ { SK_PNMI_HTX_CARRIER, SK_PNMI_HTX_MULTI_COL},
556/* Bit18 */ { SK_PNMI_HTX_UTILUNDER, SK_PNMI_HTX_SINGLE_COL},
557/* Bit19 */ { SK_PNMI_HTX_UTILOVER, SK_PNMI_HTX_UNDERRUN},
558/* Bit20 */ { SK_PNMI_HTX_64, SK_PNMI_HTX_RESERVED},
559/* Bit21 */ { SK_PNMI_HTX_127, SK_PNMI_HTX_RESERVED},
560/* Bit22 */ { SK_PNMI_HTX_255, SK_PNMI_HTX_RESERVED},
561/* Bit23 */ { SK_PNMI_HTX_511, SK_PNMI_HTX_RESERVED},
562/* Bit24 */ { SK_PNMI_HTX_1023, SK_PNMI_HTX_RESERVED},
563/* Bit25 */ { SK_PNMI_HTX_MAX, SK_PNMI_HTX_RESERVED},
564/* Bit26 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
565/* Bit27 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
566/* Bit28 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
567/* Bit29 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
568/* Bit30 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
569/* Bit31 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
570/* Bit32 */ { SK_PNMI_HRX, SK_PNMI_HRX_UNICAST},
571/* Bit33 */ { SK_PNMI_HRX_OCTETHIGH, SK_PNMI_HRX_BROADCAST},
572/* Bit34 */ { SK_PNMI_HRX_OCTETLOW, SK_PNMI_HRX_PMACC},
573/* Bit35 */ { SK_PNMI_HRX_BROADCAST, SK_PNMI_HRX_MULTICAST},
574/* Bit36 */ { SK_PNMI_HRX_MULTICAST, SK_PNMI_HRX_FCS},
575/* Bit37 */ { SK_PNMI_HRX_UNICAST, SK_PNMI_HRX_RESERVED},
576/* Bit38 */ { SK_PNMI_HRX_PMACC, SK_PNMI_HRX_OCTETLOW},
577/* Bit39 */ { SK_PNMI_HRX_MACC, SK_PNMI_HRX_OCTETHIGH},
578/* Bit40 */ { SK_PNMI_HRX_PMACC_ERR, SK_PNMI_HRX_BADOCTETLOW},
wdenkeb20ad32003-09-05 23:19:14 +0000579/* Bit41 */ { SK_PNMI_HRX_MACC_UNKWN, SK_PNMI_HRX_BADOCTETHIGH},
Wolfgang Denka1be4762008-05-20 16:00:29 +0200580/* Bit42 */ { SK_PNMI_HRX_BURST, SK_PNMI_HRX_UNDERSIZE},
581/* Bit43 */ { SK_PNMI_HRX_MISSED, SK_PNMI_HRX_RUNT},
582/* Bit44 */ { SK_PNMI_HRX_FRAMING, SK_PNMI_HRX_64},
583/* Bit45 */ { SK_PNMI_HRX_OVERFLOW, SK_PNMI_HRX_127},
584/* Bit46 */ { SK_PNMI_HRX_JABBER, SK_PNMI_HRX_255},
585/* Bit47 */ { SK_PNMI_HRX_CARRIER, SK_PNMI_HRX_511},
586/* Bit48 */ { SK_PNMI_HRX_IRLENGTH, SK_PNMI_HRX_1023},
587/* Bit49 */ { SK_PNMI_HRX_SYMBOL, SK_PNMI_HRX_MAX},
588/* Bit50 */ { SK_PNMI_HRX_SHORTS, SK_PNMI_HRX_LONGFRAMES},
589/* Bit51 */ { SK_PNMI_HRX_RUNT, SK_PNMI_HRX_TOO_LONG},
590/* Bit52 */ { SK_PNMI_HRX_TOO_LONG, SK_PNMI_HRX_JABBER},
591/* Bit53 */ { SK_PNMI_HRX_FCS, SK_PNMI_HRX_RESERVED},
592/* Bit54 */ { SK_PNMI_HRX_RESERVED, SK_PNMI_HRX_OVERFLOW},
593/* Bit55 */ { SK_PNMI_HRX_CEXT, SK_PNMI_HRX_RESERVED},
594/* Bit56 */ { SK_PNMI_HRX_UTILUNDER, SK_PNMI_HRX_RESERVED},
595/* Bit57 */ { SK_PNMI_HRX_UTILOVER, SK_PNMI_HRX_RESERVED},
596/* Bit58 */ { SK_PNMI_HRX_64, SK_PNMI_HRX_RESERVED},
597/* Bit59 */ { SK_PNMI_HRX_127, SK_PNMI_HRX_RESERVED},
598/* Bit60 */ { SK_PNMI_HRX_255, SK_PNMI_HRX_RESERVED},
599/* Bit61 */ { SK_PNMI_HRX_511, SK_PNMI_HRX_RESERVED},
600/* Bit62 */ { SK_PNMI_HRX_1023, SK_PNMI_HRX_RESERVED},
601/* Bit63 */ { SK_PNMI_HRX_MAX, SK_PNMI_HRX_RESERVED}
wdenkeb20ad32003-09-05 23:19:14 +0000602};
603
604/*
605 * Table for hardware register saving on resets and port switches
606 */
607PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = {
608 /* SK_PNMI_HTX */
609 {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}},
610 /* SK_PNMI_HTX_OCTETHIGH */
611 {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}},
612 /* SK_PNMI_HTX_OCTETLOW */
613 {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}},
614 /* SK_PNMI_HTX_BROADCAST */
615 {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}},
616 /* SK_PNMI_HTX_MULTICAST */
617 {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}},
618 /* SK_PNMI_HTX_UNICAST */
619 {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}},
620 /* SK_PNMI_HTX_BURST */
621 {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}},
622 /* SK_PNMI_HTX_PMACC */
623 {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}},
624 /* SK_PNMI_HTX_MACC */
625 {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
626 /* SK_PNMI_HTX_COL */
627 {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}},
628 /* SK_PNMI_HTX_SINGLE_COL */
629 {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}},
630 /* SK_PNMI_HTX_MULTI_COL */
631 {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}},
632 /* SK_PNMI_HTX_EXCESS_COL */
633 {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}},
634 /* SK_PNMI_HTX_LATE_COL */
635 {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}},
636 /* SK_PNMI_HTX_DEFFERAL */
637 {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}},
638 /* SK_PNMI_HTX_EXCESS_DEF */
639 {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}},
640 /* SK_PNMI_HTX_UNDERRUN */
641 {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}},
642 /* SK_PNMI_HTX_CARRIER */
643 {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}},
644 /* SK_PNMI_HTX_UTILUNDER */
645 {{0, SK_FALSE}, {0, SK_FALSE}},
646 /* SK_PNMI_HTX_UTILOVER */
647 {{0, SK_FALSE}, {0, SK_FALSE}},
648 /* SK_PNMI_HTX_64 */
649 {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}},
650 /* SK_PNMI_HTX_127 */
651 {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}},
652 /* SK_PNMI_HTX_255 */
653 {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}},
654 /* SK_PNMI_HTX_511 */
655 {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}},
656 /* SK_PNMI_HTX_1023 */
657 {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}},
658 /* SK_PNMI_HTX_MAX */
659 {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}},
660 /* SK_PNMI_HTX_LONGFRAMES */
661 {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}},
662 /* SK_PNMI_HTX_SYNC */
663 {{0, SK_FALSE}, {0, SK_FALSE}},
664 /* SK_PNMI_HTX_SYNC_OCTET */
665 {{0, SK_FALSE}, {0, SK_FALSE}},
666 /* SK_PNMI_HTX_RESERVED */
667 {{0, SK_FALSE}, {0, SK_FALSE}},
668 /* SK_PNMI_HRX */
669 {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}},
670 /* SK_PNMI_HRX_OCTETHIGH */
671 {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}},
672 /* SK_PNMI_HRX_OCTETLOW */
673 {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}},
674 /* SK_PNMI_HRX_BADOCTETHIGH */
675 {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}},
676 /* SK_PNMI_HRX_BADOCTETLOW */
677 {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}},
678 /* SK_PNMI_HRX_BROADCAST */
679 {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}},
680 /* SK_PNMI_HRX_MULTICAST */
681 {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}},
682 /* SK_PNMI_HRX_UNICAST */
683 {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}},
684 /* SK_PNMI_HRX_PMACC */
685 {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}},
686 /* SK_PNMI_HRX_MACC */
687 {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
688 /* SK_PNMI_HRX_PMACC_ERR */
689 {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}},
690 /* SK_PNMI_HRX_MACC_UNKWN */
691 {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}},
692 /* SK_PNMI_HRX_BURST */
693 {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}},
694 /* SK_PNMI_HRX_MISSED */
695 {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}},
696 /* SK_PNMI_HRX_FRAMING */
697 {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}},
698 /* SK_PNMI_HRX_UNDERSIZE */
699 {{0, SK_FALSE},{GM_RXF_SHT, SK_TRUE}},
700 /* SK_PNMI_HRX_OVERFLOW */
701 {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}},
702 /* SK_PNMI_HRX_JABBER */
703 {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}},
704 /* SK_PNMI_HRX_CARRIER */
705 {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}},
706 /* SK_PNMI_HRX_IRLENGTH */
707 {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}},
708 /* SK_PNMI_HRX_SYMBOL */
709 {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}},
710 /* SK_PNMI_HRX_SHORTS */
711 {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}},
712 /* SK_PNMI_HRX_RUNT */
713 {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}},
714 /* SK_PNMI_HRX_TOO_LONG */
715 {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}},
716 /* SK_PNMI_HRX_FCS */
717 {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}},
718 /* SK_PNMI_HRX_CEXT */
719 {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}},
720 /* SK_PNMI_HRX_UTILUNDER */
721 {{0, SK_FALSE}, {0, SK_FALSE}},
722 /* SK_PNMI_HRX_UTILOVER */
723 {{0, SK_FALSE}, {0, SK_FALSE}},
724 /* SK_PNMI_HRX_64 */
725 {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}},
726 /* SK_PNMI_HRX_127 */
727 {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}},
728 /* SK_PNMI_HRX_255 */
729 {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}},
730 /* SK_PNMI_HRX_511 */
731 {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}},
732 /* SK_PNMI_HRX_1023 */
733 {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}},
734 /* SK_PNMI_HRX_MAX */
735 {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}},
736 /* SK_PNMI_HRX_LONGFRAMES */
737 {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}},
738 /* SK_PNMI_HRX_RESERVED */
739 {{0, SK_FALSE}, {0, SK_FALSE}}
740};
741
742
743/*****************************************************************************
744 *
745 * Public functions
746 *
747 */
748
749/*****************************************************************************
750 *
751 * SkPnmiInit - Init function of PNMI
752 *
753 * Description:
754 * SK_INIT_DATA: Initialises the data structures
755 * SK_INIT_IO: Resets the XMAC statistics, determines the device and
756 * connector type.
757 * SK_INIT_RUN: Starts a timer event for port switch per hour
758 * calculation.
759 *
760 * Returns:
761 * Always 0
762 */
763int SkPnmiInit(
764SK_AC *pAC, /* Pointer to adapter context */
765SK_IOC IoC, /* IO context handle */
766int Level) /* Initialization level */
767{
768 unsigned int PortMax; /* Number of ports */
769 unsigned int PortIndex; /* Current port index in loop */
770 SK_U16 Val16; /* Multiple purpose 16 bit variable */
771 SK_U8 Val8; /* Mulitple purpose 8 bit variable */
772 SK_EVPARA EventParam; /* Event struct for timer event */
773 SK_GEPORT *pPrt;
774 SK_PNMI_VCT *pVctBackupData;
775
776
777 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
778 ("PNMI: SkPnmiInit: Called, level=%d\n", Level));
779
780 switch (Level) {
781
782 case SK_INIT_DATA:
783 SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
784 pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
785 pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
786 pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
787 for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
788
789 pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
790 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
791 }
792
793#ifdef SK_PNMI_CHECK
794 if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) {
wdenk9c53f402003-10-15 23:53:47 +0000795
wdenkeb20ad32003-09-05 23:19:14 +0000796 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG);
797
798 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
799 ("CounterOffset struct size (%d) differs from"
800 "SK_PNMI_MAX_IDX (%d)\n",
801 SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
802 BRK;
803 }
804
805 if (SK_PNMI_MAX_IDX !=
806 (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) {
wdenk9c53f402003-10-15 23:53:47 +0000807
wdenkeb20ad32003-09-05 23:19:14 +0000808 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG);
809
810 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
811 ("StatAddr table size (%d) differs from "
812 "SK_PNMI_MAX_IDX (%d)\n",
wdenk9c53f402003-10-15 23:53:47 +0000813 (sizeof(StatAddr) /
wdenkeb20ad32003-09-05 23:19:14 +0000814 (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)),
815 SK_PNMI_MAX_IDX));
816 BRK;
817 }
818#endif /* SK_PNMI_CHECK */
819 break;
820
821 case SK_INIT_IO:
822 /*
823 * Reset MAC counters
824 */
825 PortMax = pAC->GIni.GIMacsFound;
826
827 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
828
829 pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
830 }
wdenk9c53f402003-10-15 23:53:47 +0000831
832 /* Initialize DSP variables for Vct() to 0xff => Never written! */
wdenkeb20ad32003-09-05 23:19:14 +0000833 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
834 pPrt = &pAC->GIni.GP[PortIndex];
835 pPrt->PCableLen =0xff;
836 pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
837 pVctBackupData->PCableLen = 0xff;
838 }
wdenk9c53f402003-10-15 23:53:47 +0000839
wdenkeb20ad32003-09-05 23:19:14 +0000840 /*
841 * Get pci bus speed
842 */
843 SK_IN16(IoC, B0_CTST, &Val16);
844 if ((Val16 & CS_BUS_CLOCK) == 0) {
845
846 pAC->Pnmi.PciBusSpeed = 33;
847 }
848 else {
849 pAC->Pnmi.PciBusSpeed = 66;
850 }
851
852 /*
853 * Get pci bus width
854 */
855 SK_IN16(IoC, B0_CTST, &Val16);
856 if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
857
858 pAC->Pnmi.PciBusWidth = 32;
859 }
860 else {
861 pAC->Pnmi.PciBusWidth = 64;
862 }
863
864 /*
865 * Get chipset
866 */
867 switch (pAC->GIni.GIChipId) {
868 case CHIP_ID_GENESIS:
869 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
870 break;
871
872 case CHIP_ID_YUKON:
873 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
874 break;
875
876 default:
877 break;
878 }
879
880 /*
881 * Get PMD and DeviceType
882 */
883 SK_IN8(IoC, B2_PMD_TYP, &Val8);
884 switch (Val8) {
885 case 'S':
886 pAC->Pnmi.PMD = 3;
887 if (pAC->GIni.GIMacsFound > 1) {
888
889 pAC->Pnmi.DeviceType = 0x00020002;
890 }
891 else {
892 pAC->Pnmi.DeviceType = 0x00020001;
893 }
894 break;
895
896 case 'L':
897 pAC->Pnmi.PMD = 2;
898 if (pAC->GIni.GIMacsFound > 1) {
899
900 pAC->Pnmi.DeviceType = 0x00020004;
901 }
902 else {
903 pAC->Pnmi.DeviceType = 0x00020003;
904 }
905 break;
906
907 case 'C':
908 pAC->Pnmi.PMD = 4;
909 if (pAC->GIni.GIMacsFound > 1) {
910
911 pAC->Pnmi.DeviceType = 0x00020006;
912 }
913 else {
914 pAC->Pnmi.DeviceType = 0x00020005;
915 }
916 break;
917
918 case 'T':
919 pAC->Pnmi.PMD = 5;
920 if (pAC->GIni.GIMacsFound > 1) {
921
922 pAC->Pnmi.DeviceType = 0x00020008;
923 }
924 else {
925 pAC->Pnmi.DeviceType = 0x00020007;
926 }
927 break;
928
929 default :
930 pAC->Pnmi.PMD = 1;
931 pAC->Pnmi.DeviceType = 0;
932 break;
933 }
934
935 /*
936 * Get connector
937 */
938 SK_IN8(IoC, B2_CONN_TYP, &Val8);
939 switch (Val8) {
940 case 'C':
941 pAC->Pnmi.Connector = 2;
942 break;
943
944 case 'D':
945 pAC->Pnmi.Connector = 3;
946 break;
947
948 case 'F':
949 pAC->Pnmi.Connector = 4;
950 break;
951
952 case 'J':
953 pAC->Pnmi.Connector = 5;
954 break;
955
956 case 'V':
957 pAC->Pnmi.Connector = 6;
958 break;
959
960 default:
961 pAC->Pnmi.Connector = 1;
962 break;
wdenk9c53f402003-10-15 23:53:47 +0000963 }
wdenkeb20ad32003-09-05 23:19:14 +0000964 break;
wdenk9c53f402003-10-15 23:53:47 +0000965
wdenkeb20ad32003-09-05 23:19:14 +0000966 case SK_INIT_RUN:
967 /*
968 * Start timer for RLMT change counter
969 */
970 SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
971 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
972 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
973 EventParam);
974 break;
975
976 default:
977 break; /* Nothing todo */
978 }
979
980 return (0);
981}
982
983/*****************************************************************************
984 *
985 * SkPnmiGetVar - Retrieves the value of a single OID
986 *
987 * Description:
988 * Calls a general sub-function for all this stuff. If the instance
989 * -1 is passed, the values of all instances are returned in an
990 * array of values.
991 *
992 * Returns:
993 * SK_PNMI_ERR_OK The request was successfully performed
994 * SK_PNMI_ERR_GENERAL A general severe internal error occured
995 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
996 * the data.
997 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
998 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
999 * exist (e.g. port instance 3 on a two port
1000 * adapter.
1001 */
1002int SkPnmiGetVar(
1003SK_AC *pAC, /* Pointer to adapter context */
1004SK_IOC IoC, /* IO context handle */
1005SK_U32 Id, /* Object ID that is to be processed */
1006void *pBuf, /* Buffer to which to mgmt data will be retrieved */
1007unsigned int *pLen, /* On call: buffer length. On return: used buffer */
1008SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
1009SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1010{
1011 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1012 ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
1013 Id, *pLen, Instance, NetIndex));
1014
1015 return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
1016 Instance, NetIndex));
1017}
1018
1019/*****************************************************************************
1020 *
1021 * SkPnmiPreSetVar - Presets the value of a single OID
1022 *
1023 * Description:
1024 * Calls a general sub-function for all this stuff. The preset does
1025 * the same as a set, but returns just before finally setting the
1026 * new value. This is usefull to check if a set might be successfull.
1027 * If as instance a -1 is passed, an array of values is supposed and
1028 * all instance of the OID will be set.
1029 *
1030 * Returns:
1031 * SK_PNMI_ERR_OK The request was successfully performed.
1032 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1033 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1034 * the correct data (e.g. a 32bit value is
1035 * needed, but a 16 bit value was passed).
1036 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1037 * value range.
1038 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
1039 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
1040 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1041 * exist (e.g. port instance 3 on a two port
1042 * adapter.
1043 */
1044int SkPnmiPreSetVar(
1045SK_AC *pAC, /* Pointer to adapter context */
1046SK_IOC IoC, /* IO context handle */
1047SK_U32 Id, /* Object ID that is to be processed */
1048void *pBuf, /* Buffer which stores the mgmt data to be set */
1049unsigned int *pLen, /* Total length of mgmt data */
1050SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
1051SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1052{
1053 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1054 ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
1055 Id, *pLen, Instance, NetIndex));
1056
1057
1058 return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
1059 Instance, NetIndex));
1060}
1061
1062/*****************************************************************************
1063 *
1064 * SkPnmiSetVar - Sets the value of a single OID
1065 *
1066 * Description:
1067 * Calls a general sub-function for all this stuff. The preset does
1068 * the same as a set, but returns just before finally setting the
1069 * new value. This is usefull to check if a set might be successfull.
1070 * If as instance a -1 is passed, an array of values is supposed and
1071 * all instance of the OID will be set.
1072 *
1073 * Returns:
1074 * SK_PNMI_ERR_OK The request was successfully performed.
1075 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1076 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1077 * the correct data (e.g. a 32bit value is
1078 * needed, but a 16 bit value was passed).
1079 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1080 * value range.
1081 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
1082 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
1083 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1084 * exist (e.g. port instance 3 on a two port
1085 * adapter.
1086 */
1087int SkPnmiSetVar(
1088SK_AC *pAC, /* Pointer to adapter context */
1089SK_IOC IoC, /* IO context handle */
1090SK_U32 Id, /* Object ID that is to be processed */
1091void *pBuf, /* Buffer which stores the mgmt data to be set */
1092unsigned int *pLen, /* Total length of mgmt data */
1093SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
1094SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1095{
1096 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1097 ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
1098 Id, *pLen, Instance, NetIndex));
1099
1100 return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
1101 Instance, NetIndex));
1102}
1103
1104/*****************************************************************************
1105 *
1106 * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA
1107 *
1108 * Description:
1109 * Runs through the IdTable, queries the single OIDs and stores the
1110 * returned data into the management database structure
1111 * SK_PNMI_STRUCT_DATA. The offset of the OID in the structure
1112 * is stored in the IdTable. The return value of the function will also
1113 * be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
1114 * minimum size of SK_PNMI_MIN_STRUCT_SIZE.
1115 *
1116 * Returns:
1117 * SK_PNMI_ERR_OK The request was successfully performed
1118 * SK_PNMI_ERR_GENERAL A general severe internal error occured
1119 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
1120 * the data.
wdenk9c53f402003-10-15 23:53:47 +00001121 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
wdenkeb20ad32003-09-05 23:19:14 +00001122 */
1123int SkPnmiGetStruct(
1124SK_AC *pAC, /* Pointer to adapter context */
1125SK_IOC IoC, /* IO context handle */
1126void *pBuf, /* Buffer which will store the retrieved data */
1127unsigned int *pLen, /* Length of buffer */
1128SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1129{
1130 int Ret;
1131 unsigned int TableIndex;
1132 unsigned int DstOffset;
1133 unsigned int InstanceNo;
1134 unsigned int InstanceCnt;
1135 SK_U32 Instance;
1136 unsigned int TmpLen;
1137 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
1138
1139
1140 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1141 ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
1142 *pLen, NetIndex));
1143
1144 if (*pLen < SK_PNMI_STRUCT_SIZE) {
1145
1146 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
1147
1148 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
1149 (SK_U32)(-1));
1150 }
1151
1152 *pLen = SK_PNMI_STRUCT_SIZE;
1153 return (SK_PNMI_ERR_TOO_SHORT);
1154 }
1155
1156 /*
1157 * Check NetIndex
1158 */
1159 if (NetIndex >= pAC->Rlmt.NumNets) {
1160 return (SK_PNMI_ERR_UNKNOWN_NET);
1161 }
1162
1163 /* Update statistic */
1164 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
1165
1166 if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
1167 SK_PNMI_ERR_OK) {
1168
1169 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1170 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1171 return (Ret);
1172 }
1173
1174 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
1175
1176 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1177 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1178 return (Ret);
1179 }
1180
1181 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
1182
1183 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1184 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1185 return (Ret);
1186 }
1187
1188 /*
1189 * Increment semaphores to indicate that an update was
1190 * already done
1191 */
1192 pAC->Pnmi.MacUpdatedFlag ++;
1193 pAC->Pnmi.RlmtUpdatedFlag ++;
1194 pAC->Pnmi.SirqUpdatedFlag ++;
1195
1196 /* Get vpd keys for instance calculation */
1197 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
1198 if (Ret != SK_PNMI_ERR_OK) {
1199
1200 pAC->Pnmi.MacUpdatedFlag --;
1201 pAC->Pnmi.RlmtUpdatedFlag --;
1202 pAC->Pnmi.SirqUpdatedFlag --;
1203
1204 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
1205 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1206 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1207 return (SK_PNMI_ERR_GENERAL);
1208 }
1209
1210 /* Retrieve values */
1211 SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
1212 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
1213
1214 InstanceNo = IdTable[TableIndex].InstanceNo;
1215 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
1216 InstanceCnt ++) {
1217
1218 DstOffset = IdTable[TableIndex].Offset +
1219 (InstanceCnt - 1) *
1220 IdTable[TableIndex].StructSize;
1221
1222 /*
1223 * For the VPD the instance is not an index number
1224 * but the key itself. Determin with the instance
1225 * counter the VPD key to be used.
1226 */
1227 if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
1228 IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
1229 IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
1230 IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
1231
1232 SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
1233 }
1234 else {
1235 Instance = (SK_U32)InstanceCnt;
1236 }
1237
1238 TmpLen = *pLen - DstOffset;
1239 Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
1240 IdTable[TableIndex].Id, (char *)pBuf +
1241 DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
1242
1243 /*
1244 * An unknown instance error means that we reached
1245 * the last instance of that variable. Proceed with
1246 * the next OID in the table and ignore the return
1247 * code.
1248 */
1249 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
1250
wdenk9c53f402003-10-15 23:53:47 +00001251 break;
wdenkeb20ad32003-09-05 23:19:14 +00001252 }
1253
1254 if (Ret != SK_PNMI_ERR_OK) {
1255
1256 pAC->Pnmi.MacUpdatedFlag --;
1257 pAC->Pnmi.RlmtUpdatedFlag --;
1258 pAC->Pnmi.SirqUpdatedFlag --;
1259
1260 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
1261 SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
1262 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1263 return (Ret);
1264 }
1265 }
1266 }
1267
1268 pAC->Pnmi.MacUpdatedFlag --;
1269 pAC->Pnmi.RlmtUpdatedFlag --;
1270 pAC->Pnmi.SirqUpdatedFlag --;
1271
1272 *pLen = SK_PNMI_STRUCT_SIZE;
1273 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
1274 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
1275 return (SK_PNMI_ERR_OK);
1276}
1277
1278/*****************************************************************************
1279 *
1280 * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
1281 *
1282 * Description:
1283 * Calls a general sub-function for all this set stuff. The preset does
1284 * the same as a set, but returns just before finally setting the
1285 * new value. This is usefull to check if a set might be successfull.
1286 * The sub-function runs through the IdTable, checks which OIDs are able
1287 * to set, and calls the handler function of the OID to perform the
1288 * preset. The return value of the function will also be stored in
1289 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
1290 * SK_PNMI_MIN_STRUCT_SIZE.
1291 *
1292 * Returns:
1293 * SK_PNMI_ERR_OK The request was successfully performed.
1294 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1295 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1296 * the correct data (e.g. a 32bit value is
1297 * needed, but a 16 bit value was passed).
1298 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1299 * value range.
1300 */
1301int SkPnmiPreSetStruct(
1302SK_AC *pAC, /* Pointer to adapter context */
1303SK_IOC IoC, /* IO context handle */
1304void *pBuf, /* Buffer which contains the data to be set */
1305unsigned int *pLen, /* Length of buffer */
1306SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1307{
1308 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1309 ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
1310 *pLen, NetIndex));
1311
wdenk9c53f402003-10-15 23:53:47 +00001312 return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf,
1313 pLen, NetIndex));
wdenkeb20ad32003-09-05 23:19:14 +00001314}
1315
1316/*****************************************************************************
1317 *
1318 * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA
1319 *
1320 * Description:
1321 * Calls a general sub-function for all this set stuff. The return value
1322 * of the function will also be stored in SK_PNMI_STRUCT_DATA if the
1323 * passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE.
1324 * The sub-function runs through the IdTable, checks which OIDs are able
1325 * to set, and calls the handler function of the OID to perform the
1326 * set. The return value of the function will also be stored in
1327 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
1328 * SK_PNMI_MIN_STRUCT_SIZE.
1329 *
1330 * Returns:
1331 * SK_PNMI_ERR_OK The request was successfully performed.
1332 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1333 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1334 * the correct data (e.g. a 32bit value is
1335 * needed, but a 16 bit value was passed).
1336 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1337 * value range.
1338 */
1339int SkPnmiSetStruct(
1340SK_AC *pAC, /* Pointer to adapter context */
1341SK_IOC IoC, /* IO context handle */
1342void *pBuf, /* Buffer which contains the data to be set */
1343unsigned int *pLen, /* Length of buffer */
1344SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1345{
1346 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1347 ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
1348 *pLen, NetIndex));
1349
wdenk9c53f402003-10-15 23:53:47 +00001350 return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf,
1351 pLen, NetIndex));
wdenkeb20ad32003-09-05 23:19:14 +00001352}
1353
1354/*****************************************************************************
1355 *
1356 * SkPnmiEvent - Event handler
1357 *
1358 * Description:
1359 * Handles the following events:
1360 * SK_PNMI_EVT_SIRQ_OVERFLOW When a hardware counter overflows an
1361 * interrupt will be generated which is
1362 * first handled by SIRQ which generates a
1363 * this event. The event increments the
1364 * upper 32 bit of the 64 bit counter.
1365 * SK_PNMI_EVT_SEN_XXX The event is generated by the I2C module
1366 * when a sensor reports a warning or
1367 * error. The event will store a trap
1368 * message in the trap buffer.
1369 * SK_PNMI_EVT_CHG_EST_TIMER The timer event was initiated by this
1370 * module and is used to calculate the
1371 * port switches per hour.
1372 * SK_PNMI_EVT_CLEAR_COUNTER The event clears all counters and
1373 * timestamps.
1374 * SK_PNMI_EVT_XMAC_RESET The event is generated by the driver
1375 * before a hard reset of the XMAC is
1376 * performed. All counters will be saved
1377 * and added to the hardware counter
1378 * values after reset to grant continuous
1379 * counter values.
1380 * SK_PNMI_EVT_RLMT_PORT_UP Generated by RLMT to notify that a port
1381 * went logically up. A trap message will
1382 * be stored to the trap buffer.
1383 * SK_PNMI_EVT_RLMT_PORT_DOWN Generated by RLMT to notify that a port
1384 * went logically down. A trap message will
1385 * be stored to the trap buffer.
1386 * SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
1387 * spanning tree root bridges were
1388 * detected. A trap message will be stored
1389 * to the trap buffer.
1390 * SK_PNMI_EVT_RLMT_ACTIVE_DOWN Notifies PNMI that an active port went
1391 * down. PNMI will not further add the
1392 * statistic values to the virtual port.
1393 * SK_PNMI_EVT_RLMT_ACTIVE_UP Notifies PNMI that a port went up and
1394 * is now an active port. PNMI will now
1395 * add the statistic data of this port to
1396 * the virtual port.
1397 * SK_PNMI_EVT_RLMT_SET_NETS Notifies PNMI about the net mode. The first Parameter
1398 * contains the number of nets. 1 means single net, 2 means
1399 * dual net. The second Parameter is -1
1400 *
1401 * Returns:
1402 * Always 0
1403 */
1404int SkPnmiEvent(
1405SK_AC *pAC, /* Pointer to adapter context */
1406SK_IOC IoC, /* IO context handle */
1407SK_U32 Event, /* Event-Id */
1408SK_EVPARA Param) /* Event dependent parameter */
1409{
1410 unsigned int PhysPortIndex;
1411 unsigned int MaxNetNumber;
1412 int CounterIndex;
1413 int Ret;
1414 SK_U16 MacStatus;
1415 SK_U64 OverflowStatus;
1416 SK_U64 Mask;
1417 int MacType;
1418 SK_U64 Value;
1419 SK_U32 Val32;
1420 SK_U16 Register;
1421 SK_EVPARA EventParam;
1422 SK_U64 NewestValue;
1423 SK_U64 OldestValue;
1424 SK_U64 Delta;
1425 SK_PNMI_ESTIMATE *pEst;
1426 SK_U32 NetIndex;
1427 SK_GEPORT *pPrt;
1428 SK_PNMI_VCT *pVctBackupData;
1429 SK_U32 RetCode;
1430 int i;
1431 SK_U32 CableLength;
1432
1433
1434#ifdef DEBUG
1435 if (Event != SK_PNMI_EVT_XMAC_RESET) {
1436
1437 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1438 ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n",
1439 (unsigned int)Event, (unsigned int)Param.Para64));
1440 }
1441#endif
1442 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call");
1443
1444 MacType = pAC->GIni.GIMacType;
wdenk9c53f402003-10-15 23:53:47 +00001445
wdenkeb20ad32003-09-05 23:19:14 +00001446 switch (Event) {
1447
1448 case SK_PNMI_EVT_SIRQ_OVERFLOW:
1449 PhysPortIndex = (int)Param.Para32[0];
1450 MacStatus = (SK_U16)Param.Para32[1];
1451#ifdef DEBUG
1452 if (PhysPortIndex >= SK_MAX_MACS) {
1453
1454 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1455 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter"
1456 " wrong, PhysPortIndex=0x%x\n",
1457 PhysPortIndex));
1458 return (0);
1459 }
1460#endif
1461 OverflowStatus = 0;
1462
1463 /*
1464 * Check which source caused an overflow interrupt.
1465 */
1466 if ((pAC->GIni.GIFunc.pFnMacOverflow(
1467 pAC, IoC, PhysPortIndex, MacStatus, &OverflowStatus) != 0) ||
1468 (OverflowStatus == 0)) {
1469
1470 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
wdenk9c53f402003-10-15 23:53:47 +00001471 return (0);
wdenkeb20ad32003-09-05 23:19:14 +00001472 }
1473
1474 /*
1475 * Check the overflow status register and increment
1476 * the upper dword of corresponding counter.
1477 */
1478 for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8;
1479 CounterIndex ++) {
1480
1481 Mask = (SK_U64)1 << CounterIndex;
1482 if ((OverflowStatus & Mask) == 0) {
1483
1484 continue;
1485 }
1486
1487 switch (StatOvrflwBit[CounterIndex][MacType]) {
1488
1489 case SK_PNMI_HTX_UTILUNDER:
1490 case SK_PNMI_HTX_UTILOVER:
1491 XM_IN16(IoC, PhysPortIndex, XM_TX_CMD,
1492 &Register);
1493 Register |= XM_TX_SAM_LINE;
1494 XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD,
1495 Register);
1496 break;
1497
1498 case SK_PNMI_HRX_UTILUNDER:
1499 case SK_PNMI_HRX_UTILOVER:
1500 XM_IN16(IoC, PhysPortIndex, XM_RX_CMD,
1501 &Register);
1502 Register |= XM_RX_SAM_LINE;
1503 XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD,
1504 Register);
1505 break;
1506
1507 case SK_PNMI_HTX_OCTETHIGH:
1508 case SK_PNMI_HTX_OCTETLOW:
1509 case SK_PNMI_HTX_RESERVED:
1510 case SK_PNMI_HRX_OCTETHIGH:
1511 case SK_PNMI_HRX_OCTETLOW:
1512 case SK_PNMI_HRX_IRLENGTH:
1513 case SK_PNMI_HRX_RESERVED:
wdenk9c53f402003-10-15 23:53:47 +00001514
wdenkeb20ad32003-09-05 23:19:14 +00001515 /*
1516 * the following counters aren't be handled (id > 63)
1517 */
1518 case SK_PNMI_HTX_SYNC:
1519 case SK_PNMI_HTX_SYNC_OCTET:
1520 break;
1521
1522 case SK_PNMI_HRX_LONGFRAMES:
1523 if (MacType == SK_MAC_GMAC) {
1524 pAC->Pnmi.Port[PhysPortIndex].
1525 CounterHigh[CounterIndex] ++;
1526 }
1527 break;
1528
1529 default:
1530 pAC->Pnmi.Port[PhysPortIndex].
1531 CounterHigh[CounterIndex] ++;
1532 }
1533 }
1534 break;
1535
1536 case SK_PNMI_EVT_SEN_WAR_LOW:
1537#ifdef DEBUG
1538 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1539
1540 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1541 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n",
1542 (unsigned int)Param.Para64));
1543 return (0);
1544 }
1545#endif
1546 /*
1547 * Store a trap message in the trap buffer and generate
1548 * an event for user space applications with the
1549 * SK_DRIVER_SENDEVENT macro.
1550 */
1551 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW,
1552 (unsigned int)Param.Para64);
1553 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1554 break;
1555
1556 case SK_PNMI_EVT_SEN_WAR_UPP:
1557#ifdef DEBUG
1558 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1559
1560 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1561 ("PNMI: ERR:SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n",
1562 (unsigned int)Param.Para64));
1563 return (0);
1564 }
1565#endif
1566 /*
1567 * Store a trap message in the trap buffer and generate
1568 * an event for user space applications with the
1569 * SK_DRIVER_SENDEVENT macro.
1570 */
1571 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP,
1572 (unsigned int)Param.Para64);
1573 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1574 break;
1575
1576 case SK_PNMI_EVT_SEN_ERR_LOW:
1577#ifdef DEBUG
1578 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1579
1580 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1581 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n",
1582 (unsigned int)Param.Para64));
1583 return (0);
1584 }
1585#endif
1586 /*
1587 * Store a trap message in the trap buffer and generate
1588 * an event for user space applications with the
1589 * SK_DRIVER_SENDEVENT macro.
1590 */
1591 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW,
1592 (unsigned int)Param.Para64);
1593 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1594 break;
wdenk9c53f402003-10-15 23:53:47 +00001595
wdenkeb20ad32003-09-05 23:19:14 +00001596 case SK_PNMI_EVT_SEN_ERR_UPP:
1597#ifdef DEBUG
1598 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1599
1600 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1601 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
1602 (unsigned int)Param.Para64));
1603 return (0);
1604 }
1605#endif
1606 /*
1607 * Store a trap message in the trap buffer and generate
1608 * an event for user space applications with the
1609 * SK_DRIVER_SENDEVENT macro.
1610 */
1611 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP,
1612 (unsigned int)Param.Para64);
1613 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1614 break;
1615
1616 case SK_PNMI_EVT_CHG_EST_TIMER:
1617 /*
1618 * Calculate port switch average on a per hour basis
1619 * Time interval for check : 28125 ms
1620 * Number of values for average : 8
1621 *
1622 * Be careful in changing these values, on change check
1623 * - typedef of SK_PNMI_ESTIMATE (Size of EstValue
1624 * array one less than value number)
1625 * - Timer initilization SkTimerStart() in SkPnmiInit
1626 * - Delta value below must be multiplicated with
1627 * power of 2
1628 *
1629 */
1630 pEst = &pAC->Pnmi.RlmtChangeEstimate;
1631 CounterIndex = pEst->EstValueIndex + 1;
1632 if (CounterIndex == 7) {
1633
1634 CounterIndex = 0;
1635 }
1636 pEst->EstValueIndex = CounterIndex;
1637
1638 NewestValue = pAC->Pnmi.RlmtChangeCts;
1639 OldestValue = pEst->EstValue[CounterIndex];
1640 pEst->EstValue[CounterIndex] = NewestValue;
1641
1642 /*
1643 * Calculate average. Delta stores the number of
1644 * port switches per 28125 * 8 = 225000 ms
1645 */
1646 if (NewestValue >= OldestValue) {
1647
1648 Delta = NewestValue - OldestValue;
1649 }
1650 else {
1651 /* Overflow situation */
1652 Delta = (SK_U64)(0 - OldestValue) + NewestValue;
1653 }
1654
1655 /*
1656 * Extrapolate delta to port switches per hour.
1657 * Estimate = Delta * (3600000 / 225000)
1658 * = Delta * 16
1659 * = Delta << 4
1660 */
1661 pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4;
1662
1663 /*
1664 * Check if threshold is exceeded. If the threshold is
1665 * permanently exceeded every 28125 ms an event will be
1666 * generated to remind the user of this condition.
1667 */
1668 if ((pAC->Pnmi.RlmtChangeThreshold != 0) &&
1669 (pAC->Pnmi.RlmtChangeEstimate.Estimate >=
1670 pAC->Pnmi.RlmtChangeThreshold)) {
1671
1672 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES);
1673 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1674 }
1675
1676 SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
1677 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
1678 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
1679 EventParam);
1680 break;
1681
1682 case SK_PNMI_EVT_CLEAR_COUNTER:
1683 /*
1684 * Param.Para32[0] contains the NetIndex (0 ..1).
1685 * Param.Para32[1] is reserved, contains -1.
1686 */
1687 NetIndex = (SK_U32)Param.Para32[0];
1688
1689#ifdef DEBUG
1690 if (NetIndex >= pAC->Rlmt.NumNets) {
1691
1692 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1693 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
1694 NetIndex));
1695
1696 return (0);
1697 }
1698#endif
1699
1700 /*
1701 * Set all counters and timestamps to zero
1702 */
1703 ResetCounter(pAC, IoC, NetIndex); /* the according NetIndex is required
wdenk9c53f402003-10-15 23:53:47 +00001704 as a Parameter of the Event */
wdenkeb20ad32003-09-05 23:19:14 +00001705 break;
1706
1707 case SK_PNMI_EVT_XMAC_RESET:
1708 /*
1709 * To grant continuous counter values store the current
1710 * XMAC statistic values to the entries 1..n of the
wdenk9c53f402003-10-15 23:53:47 +00001711 * CounterOffset array. XMAC Errata #2
wdenkeb20ad32003-09-05 23:19:14 +00001712 */
1713#ifdef DEBUG
1714 if ((unsigned int)Param.Para64 >= SK_MAX_MACS) {
1715
1716 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1717 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n",
1718 (unsigned int)Param.Para64));
1719 return (0);
1720 }
1721#endif
1722 PhysPortIndex = (unsigned int)Param.Para64;
1723
1724 /*
1725 * Update XMAC statistic to get fresh values
1726 */
1727 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
1728 if (Ret != SK_PNMI_ERR_OK) {
1729
1730 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1731 return (0);
1732 }
1733 /*
1734 * Increment semaphore to indicate that an update was
1735 * already done
1736 */
1737 pAC->Pnmi.MacUpdatedFlag ++;
1738
1739 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1740 CounterIndex ++) {
1741
1742 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1743
1744 continue;
1745 }
1746
1747 pAC->Pnmi.Port[PhysPortIndex].
1748 CounterOffset[CounterIndex] = GetPhysStatVal(
1749 pAC, IoC, PhysPortIndex, CounterIndex);
1750 pAC->Pnmi.Port[PhysPortIndex].
1751 CounterHigh[CounterIndex] = 0;
1752 }
1753
1754 pAC->Pnmi.MacUpdatedFlag --;
1755 break;
1756
1757 case SK_PNMI_EVT_RLMT_PORT_UP:
1758 PhysPortIndex = (unsigned int)Param.Para32[0];
1759#ifdef DEBUG
1760 if (PhysPortIndex >= SK_MAX_MACS) {
1761
1762 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1763 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter"
wdenk9c53f402003-10-15 23:53:47 +00001764 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
wdenkeb20ad32003-09-05 23:19:14 +00001765
1766 return (0);
1767 }
1768#endif
1769 /*
1770 * Store a trap message in the trap buffer and generate an event for
1771 * user space applications with the SK_DRIVER_SENDEVENT macro.
1772 */
1773 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
1774 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1775
1776 /* Bugfix for XMAC errata (#10620)*/
1777 if (pAC->GIni.GIMacType == SK_MAC_XMAC){
1778
1779 /* Add incremental difference to offset (#10620)*/
1780 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1781 XM_RXE_SHT_ERR, &Val32);
wdenk9c53f402003-10-15 23:53:47 +00001782
wdenkeb20ad32003-09-05 23:19:14 +00001783 Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1784 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1785 pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
1786 Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
1787 }
wdenk9c53f402003-10-15 23:53:47 +00001788
wdenkeb20ad32003-09-05 23:19:14 +00001789 /* Tell VctStatus() that a link was up meanwhile. */
wdenk9c53f402003-10-15 23:53:47 +00001790 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK;
wdenkeb20ad32003-09-05 23:19:14 +00001791 break;
1792
1793 case SK_PNMI_EVT_RLMT_PORT_DOWN:
1794 PhysPortIndex = (unsigned int)Param.Para32[0];
1795
1796#ifdef DEBUG
1797 if (PhysPortIndex >= SK_MAX_MACS) {
1798
1799 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1800 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter"
wdenk9c53f402003-10-15 23:53:47 +00001801 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
wdenkeb20ad32003-09-05 23:19:14 +00001802
1803 return (0);
1804 }
1805#endif
1806 /*
1807 * Store a trap message in the trap buffer and generate an event for
1808 * user space applications with the SK_DRIVER_SENDEVENT macro.
1809 */
1810 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
1811 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
wdenk9c53f402003-10-15 23:53:47 +00001812
wdenkeb20ad32003-09-05 23:19:14 +00001813 /* Bugfix #10620 - get zero level for incremental difference */
1814 if ((pAC->GIni.GIMacType == SK_MAC_XMAC)) {
1815
1816 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1817 XM_RXE_SHT_ERR, &Val32);
wdenk9c53f402003-10-15 23:53:47 +00001818 pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark =
wdenkeb20ad32003-09-05 23:19:14 +00001819 (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1820 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1821 }
1822 break;
1823
1824 case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
1825 PhysPortIndex = (unsigned int)Param.Para32[0];
1826 NetIndex = (SK_U32)Param.Para32[1];
1827
1828#ifdef DEBUG
1829 if (PhysPortIndex >= SK_MAX_MACS) {
1830
1831 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1832 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
1833 PhysPortIndex));
1834 }
1835
1836 if (NetIndex >= pAC->Rlmt.NumNets) {
1837
1838 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1839 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
1840 NetIndex));
1841 }
1842#endif
1843 /*
1844 * For now, ignore event if NetIndex != 0.
1845 */
1846 if (Param.Para32[1] != 0) {
1847
1848 return (0);
1849 }
1850
1851 /*
1852 * Nothing to do if port is already inactive
1853 */
1854 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1855
1856 return (0);
1857 }
1858
1859 /*
1860 * Update statistic counters to calculate new offset for the virtual
1861 * port and increment semaphore to indicate that an update was already
1862 * done.
1863 */
1864 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1865 SK_PNMI_ERR_OK) {
1866
1867 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1868 return (0);
1869 }
1870 pAC->Pnmi.MacUpdatedFlag ++;
1871
1872 /*
1873 * Calculate new counter offset for virtual port to grant continous
1874 * counting on port switches. The virtual port consists of all currently
1875 * active ports. The port down event indicates that a port is removed
1876 * from the virtual port. Therefore add the counter value of the removed
1877 * port to the CounterOffset for the virtual port to grant the same
1878 * counter value.
1879 */
1880 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1881 CounterIndex ++) {
1882
1883 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1884
1885 continue;
1886 }
1887
1888 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1889
1890 pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
1891 }
1892
1893 /*
1894 * Set port to inactive
1895 */
1896 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
1897
1898 pAC->Pnmi.MacUpdatedFlag --;
1899 break;
1900
1901 case SK_PNMI_EVT_RLMT_ACTIVE_UP:
1902 PhysPortIndex = (unsigned int)Param.Para32[0];
1903 NetIndex = (SK_U32)Param.Para32[1];
1904
1905#ifdef DEBUG
1906 if (PhysPortIndex >= SK_MAX_MACS) {
1907
1908 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1909 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
1910 PhysPortIndex));
1911 }
1912
1913 if (NetIndex >= pAC->Rlmt.NumNets) {
1914
1915 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1916 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
1917 NetIndex));
1918 }
1919#endif
1920 /*
1921 * For now, ignore event if NetIndex != 0.
1922 */
1923 if (Param.Para32[1] != 0) {
1924
1925 return (0);
1926 }
1927
1928 /*
1929 * Nothing to do if port is already active
1930 */
1931 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1932
1933 return (0);
1934 }
1935
1936 /*
1937 * Statistic maintenance
1938 */
1939 pAC->Pnmi.RlmtChangeCts ++;
1940 pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
1941
1942 /*
1943 * Store a trap message in the trap buffer and generate an event for
1944 * user space applications with the SK_DRIVER_SENDEVENT macro.
1945 */
1946 QueueRlmtNewMacTrap(pAC, PhysPortIndex);
1947 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1948
1949 /*
1950 * Update statistic counters to calculate new offset for the virtual
1951 * port and increment semaphore to indicate that an update was
1952 * already done.
1953 */
1954 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1955 SK_PNMI_ERR_OK) {
1956
1957 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1958 return (0);
1959 }
1960 pAC->Pnmi.MacUpdatedFlag ++;
1961
1962 /*
1963 * Calculate new counter offset for virtual port to grant continous
1964 * counting on port switches. A new port is added to the virtual port.
1965 * Therefore substract the counter value of the new port from the
1966 * CounterOffset for the virtual port to grant the same value.
1967 */
1968 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1969 CounterIndex ++) {
1970
1971 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1972
1973 continue;
1974 }
1975
1976 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1977
1978 pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
1979 }
1980
1981 /*
1982 * Set port to active
1983 */
1984 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
1985
1986 pAC->Pnmi.MacUpdatedFlag --;
1987 break;
1988
1989 case SK_PNMI_EVT_RLMT_SEGMENTATION:
1990 /*
1991 * Para.Para32[0] contains the NetIndex.
1992 */
1993
1994 /*
1995 * Store a trap message in the trap buffer and generate an event for
1996 * user space applications with the SK_DRIVER_SENDEVENT macro.
1997 */
1998 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
1999 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
2000 break;
2001
2002 case SK_PNMI_EVT_RLMT_SET_NETS:
2003 /*
2004 * Param.Para32[0] contains the number of Nets.
2005 * Param.Para32[1] is reserved, contains -1.
2006 */
2007 /*
wdenk9c53f402003-10-15 23:53:47 +00002008 * Check number of nets
wdenkeb20ad32003-09-05 23:19:14 +00002009 */
2010 MaxNetNumber = pAC->GIni.GIMacsFound;
2011 if (((unsigned int)Param.Para32[0] < 1)
2012 || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
2013 return (SK_PNMI_ERR_UNKNOWN_NET);
2014 }
2015
wdenk9c53f402003-10-15 23:53:47 +00002016 if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
2017 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
2018 }
2019 else { /* dual net mode */
2020 pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
2021 }
2022 break;
wdenkeb20ad32003-09-05 23:19:14 +00002023
2024 case SK_PNMI_EVT_VCT_RESET:
2025 PhysPortIndex = Param.Para32[0];
2026 pPrt = &pAC->GIni.GP[PhysPortIndex];
2027 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
wdenk9c53f402003-10-15 23:53:47 +00002028
wdenkeb20ad32003-09-05 23:19:14 +00002029 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
2030 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
2031 if (RetCode == 2) {
2032 /*
2033 * VCT test is still running.
2034 * Start VCT timer counter again.
2035 */
2036 SK_MEMSET((char *) &Param, 0, sizeof(Param));
2037 Param.Para32[0] = PhysPortIndex;
2038 Param.Para32[1] = -1;
2039 SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
2040 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
2041 break;
2042 }
2043 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
2044 pAC->Pnmi.VctStatus[PhysPortIndex] |=
2045 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
wdenk9c53f402003-10-15 23:53:47 +00002046
wdenkeb20ad32003-09-05 23:19:14 +00002047 /* Copy results for later use to PNMI struct. */
2048 for (i = 0; i < 4; i++) {
2049 if (pPrt->PMdiPairLen[i] > 35) {
2050 CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
2051 }
2052 else {
2053 CableLength = 0;
2054 }
2055 pVctBackupData->PMdiPairLen[i] = CableLength;
2056 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
2057 }
wdenk9c53f402003-10-15 23:53:47 +00002058
wdenkeb20ad32003-09-05 23:19:14 +00002059 Param.Para32[0] = PhysPortIndex;
2060 Param.Para32[1] = -1;
2061 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
2062 SkEventDispatcher(pAC, IoC);
2063 }
wdenk9c53f402003-10-15 23:53:47 +00002064
wdenkeb20ad32003-09-05 23:19:14 +00002065 break;
2066
2067 default:
2068 break;
2069 }
2070
2071 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
2072 return (0);
2073}
2074
2075
2076/******************************************************************************
2077 *
2078 * Private functions
2079 *
2080 */
2081
2082/*****************************************************************************
2083 *
2084 * PnmiVar - Gets, presets, and sets single OIDs
2085 *
2086 * Description:
2087 * Looks up the requested OID, calls the corresponding handler
2088 * function, and passes the parameters with the get, preset, or
2089 * set command. The function is called by SkGePnmiGetVar,
2090 * SkGePnmiPreSetVar, or SkGePnmiSetVar.
2091 *
2092 * Returns:
2093 * SK_PNMI_ERR_XXX. For details have a look to the description of the
2094 * calling functions.
wdenk9c53f402003-10-15 23:53:47 +00002095 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
wdenkeb20ad32003-09-05 23:19:14 +00002096 */
2097PNMI_STATIC int PnmiVar(
2098SK_AC *pAC, /* Pointer to adapter context */
2099SK_IOC IoC, /* IO context handle */
2100int Action, /* Get/PreSet/Set action */
2101SK_U32 Id, /* Object ID that is to be processed */
2102char *pBuf, /* Buffer which stores the mgmt data to be set */
2103unsigned int *pLen, /* Total length of mgmt data */
2104SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
2105SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2106{
2107 unsigned int TableIndex;
2108 int Ret;
2109
2110
2111 if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
2112
2113 *pLen = 0;
2114 return (SK_PNMI_ERR_UNKNOWN_OID);
2115 }
wdenk9c53f402003-10-15 23:53:47 +00002116
2117 /*
2118 * Check NetIndex
wdenkeb20ad32003-09-05 23:19:14 +00002119 */
2120 if (NetIndex >= pAC->Rlmt.NumNets) {
2121 return (SK_PNMI_ERR_UNKNOWN_NET);
2122 }
2123
2124 SK_PNMI_CHECKFLAGS("PnmiVar: On call");
2125
2126 Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
2127 Instance, TableIndex, NetIndex);
2128
2129 SK_PNMI_CHECKFLAGS("PnmiVar: On return");
2130
2131 return (Ret);
2132}
2133
2134/*****************************************************************************
2135 *
2136 * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA
2137 *
2138 * Description:
2139 * The return value of the function will also be stored in
2140 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
2141 * SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable,
2142 * checks which OIDs are able to set, and calls the handler function of
2143 * the OID to perform the set. The return value of the function will
2144 * also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
2145 * minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called
2146 * by SkGePnmiPreSetStruct and SkGePnmiSetStruct.
2147 *
2148 * Returns:
2149 * SK_PNMI_ERR_XXX. The codes are described in the calling functions.
wdenk9c53f402003-10-15 23:53:47 +00002150 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
wdenkeb20ad32003-09-05 23:19:14 +00002151 */
2152PNMI_STATIC int PnmiStruct(
2153SK_AC *pAC, /* Pointer to adapter context */
2154SK_IOC IoC, /* IO context handle */
2155int Action, /* Set action to be performed */
2156char *pBuf, /* Buffer which contains the data to be set */
2157unsigned int *pLen, /* Length of buffer */
2158SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2159{
2160 int Ret;
2161 unsigned int TableIndex;
2162 unsigned int DstOffset;
2163 unsigned int Len;
2164 unsigned int InstanceNo;
2165 unsigned int InstanceCnt;
2166 SK_U32 Instance;
2167 SK_U32 Id;
2168
2169
2170 /* Check if the passed buffer has the right size */
2171 if (*pLen < SK_PNMI_STRUCT_SIZE) {
2172
2173 /* Check if we can return the error within the buffer */
2174 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
2175
2176 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
2177 (SK_U32)(-1));
2178 }
2179
2180 *pLen = SK_PNMI_STRUCT_SIZE;
2181 return (SK_PNMI_ERR_TOO_SHORT);
2182 }
wdenk9c53f402003-10-15 23:53:47 +00002183
2184 /*
2185 * Check NetIndex
wdenkeb20ad32003-09-05 23:19:14 +00002186 */
2187 if (NetIndex >= pAC->Rlmt.NumNets) {
2188 return (SK_PNMI_ERR_UNKNOWN_NET);
2189 }
wdenk9c53f402003-10-15 23:53:47 +00002190
wdenkeb20ad32003-09-05 23:19:14 +00002191 SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
2192
2193 /*
2194 * Update the values of RLMT and SIRQ and increment semaphores to
2195 * indicate that an update was already done.
2196 */
2197 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
2198
2199 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
2200 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2201 return (Ret);
2202 }
2203
2204 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
2205
2206 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
2207 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2208 return (Ret);
2209 }
2210
2211 pAC->Pnmi.RlmtUpdatedFlag ++;
2212 pAC->Pnmi.SirqUpdatedFlag ++;
2213
2214 /* Preset/Set values */
2215 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
2216
2217 if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
2218 (IdTable[TableIndex].Access != SK_PNMI_WO)) {
2219
2220 continue;
2221 }
2222
2223 InstanceNo = IdTable[TableIndex].InstanceNo;
2224 Id = IdTable[TableIndex].Id;
2225
2226 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
2227 InstanceCnt ++) {
2228
2229 DstOffset = IdTable[TableIndex].Offset +
2230 (InstanceCnt - 1) *
2231 IdTable[TableIndex].StructSize;
2232
2233 /*
2234 * Because VPD multiple instance variables are
2235 * not setable we do not need to evaluate VPD
2236 * instances. Have a look to VPD instance
2237 * calculation in SkPnmiGetStruct().
2238 */
2239 Instance = (SK_U32)InstanceCnt;
2240
2241 /*
2242 * Evaluate needed buffer length
2243 */
2244 Len = 0;
2245 Ret = IdTable[TableIndex].Func(pAC, IoC,
2246 SK_PNMI_GET, IdTable[TableIndex].Id,
2247 NULL, &Len, Instance, TableIndex, NetIndex);
2248
2249 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
2250
2251 break;
2252 }
2253 if (Ret != SK_PNMI_ERR_TOO_SHORT) {
2254
2255 pAC->Pnmi.RlmtUpdatedFlag --;
2256 pAC->Pnmi.SirqUpdatedFlag --;
2257
2258 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
2259 SK_PNMI_SET_STAT(pBuf,
2260 SK_PNMI_ERR_GENERAL, DstOffset);
2261 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2262 return (SK_PNMI_ERR_GENERAL);
2263 }
2264 if (Id == OID_SKGE_VPD_ACTION) {
2265
2266 switch (*(pBuf + DstOffset)) {
2267
2268 case SK_PNMI_VPD_CREATE:
2269 Len = 3 + *(pBuf + DstOffset + 3);
2270 break;
2271
2272 case SK_PNMI_VPD_DELETE:
2273 Len = 3;
2274 break;
2275
2276 default:
2277 Len = 1;
2278 break;
2279 }
2280 }
2281
2282 /* Call the OID handler function */
2283 Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
2284 IdTable[TableIndex].Id, pBuf + DstOffset,
2285 &Len, Instance, TableIndex, NetIndex);
2286
2287 if (Ret != SK_PNMI_ERR_OK) {
2288
2289 pAC->Pnmi.RlmtUpdatedFlag --;
2290 pAC->Pnmi.SirqUpdatedFlag --;
2291
2292 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
2293 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
2294 DstOffset);
2295 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2296 return (SK_PNMI_ERR_BAD_VALUE);
2297 }
2298 }
2299 }
2300
2301 pAC->Pnmi.RlmtUpdatedFlag --;
2302 pAC->Pnmi.SirqUpdatedFlag --;
2303
2304 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
2305 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
2306 return (SK_PNMI_ERR_OK);
2307}
2308
2309/*****************************************************************************
2310 *
2311 * LookupId - Lookup an OID in the IdTable
2312 *
2313 * Description:
2314 * Scans the IdTable to find the table entry of an OID.
2315 *
2316 * Returns:
2317 * The table index or -1 if not found.
2318 */
2319PNMI_STATIC int LookupId(
2320SK_U32 Id) /* Object identifier to be searched */
2321{
2322 int i;
2323
2324 for (i = 0; i < ID_TABLE_SIZE; i++) {
2325
2326 if (IdTable[i].Id == Id) {
2327
2328 return i;
2329 }
2330 }
2331
2332 return (-1);
2333}
2334
2335/*****************************************************************************
2336 *
2337 * OidStruct - Handler of OID_SKGE_ALL_DATA
2338 *
2339 * Description:
2340 * This OID performs a Get/Preset/SetStruct call and returns all data
2341 * in a SK_PNMI_STRUCT_DATA structure.
2342 *
2343 * Returns:
2344 * SK_PNMI_ERR_OK The request was successfully performed.
2345 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2346 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2347 * the correct data (e.g. a 32bit value is
2348 * needed, but a 16 bit value was passed).
2349 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2350 * value range.
2351 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2352 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2353 * exist (e.g. port instance 3 on a two port
2354 * adapter.
2355 */
2356PNMI_STATIC int OidStruct(
2357SK_AC *pAC, /* Pointer to adapter context */
2358SK_IOC IoC, /* IO context handle */
2359int Action, /* Get/PreSet/Set action */
2360SK_U32 Id, /* Object ID that is to be processed */
2361char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2362unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2363SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2364unsigned int TableIndex, /* Index to the Id table */
2365SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2366{
2367 if (Id != OID_SKGE_ALL_DATA) {
2368
2369 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
2370 SK_PNMI_ERR003MSG);
2371
2372 *pLen = 0;
2373 return (SK_PNMI_ERR_GENERAL);
2374 }
2375
2376 /*
2377 * Check instance. We only handle single instance variables
2378 */
2379 if (Instance != (SK_U32)(-1) && Instance != 1) {
2380
2381 *pLen = 0;
2382 return (SK_PNMI_ERR_UNKNOWN_INST);
2383 }
2384
2385 switch (Action) {
2386
2387 case SK_PNMI_GET:
2388 return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
2389
2390 case SK_PNMI_PRESET:
2391 return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
2392
2393 case SK_PNMI_SET:
2394 return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
2395 }
2396
2397 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
2398
2399 *pLen = 0;
2400 return (SK_PNMI_ERR_GENERAL);
2401}
2402
2403/*****************************************************************************
2404 *
2405 * Perform - OID handler of OID_SKGE_ACTION
2406 *
2407 * Description:
2408 * None.
2409 *
2410 * Returns:
2411 * SK_PNMI_ERR_OK The request was successfully performed.
2412 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2413 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2414 * the correct data (e.g. a 32bit value is
2415 * needed, but a 16 bit value was passed).
2416 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2417 * value range.
2418 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2419 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2420 * exist (e.g. port instance 3 on a two port
2421 * adapter.
2422 */
2423PNMI_STATIC int Perform(
2424SK_AC *pAC, /* Pointer to adapter context */
2425SK_IOC IoC, /* IO context handle */
2426int Action, /* Get/PreSet/Set action */
2427SK_U32 Id, /* Object ID that is to be processed */
2428char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2429unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2430SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2431unsigned int TableIndex, /* Index to the Id table */
2432SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2433{
2434 int Ret;
2435 SK_U32 ActionOp;
2436
2437
2438 /*
2439 * Check instance. We only handle single instance variables
2440 */
2441 if (Instance != (SK_U32)(-1) && Instance != 1) {
2442
2443 *pLen = 0;
2444 return (SK_PNMI_ERR_UNKNOWN_INST);
2445 }
2446
2447 if (*pLen < sizeof(SK_U32)) {
2448
2449 *pLen = sizeof(SK_U32);
2450 return (SK_PNMI_ERR_TOO_SHORT);
2451 }
2452
2453 /* Check if a get should be performed */
2454 if (Action == SK_PNMI_GET) {
2455
2456 /* A get is easy. We always return the same value */
2457 ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
2458 SK_PNMI_STORE_U32(pBuf, ActionOp);
2459 *pLen = sizeof(SK_U32);
2460
2461 return (SK_PNMI_ERR_OK);
2462 }
2463
2464 /* Continue with PRESET/SET action */
2465 if (*pLen > sizeof(SK_U32)) {
2466
2467 return (SK_PNMI_ERR_BAD_VALUE);
2468 }
2469
2470 /* Check if the command is a known one */
2471 SK_PNMI_READ_U32(pBuf, ActionOp);
2472 if (*pLen > sizeof(SK_U32) ||
2473 (ActionOp != SK_PNMI_ACT_IDLE &&
2474 ActionOp != SK_PNMI_ACT_RESET &&
2475 ActionOp != SK_PNMI_ACT_SELFTEST &&
2476 ActionOp != SK_PNMI_ACT_RESETCNT)) {
2477
2478 *pLen = 0;
2479 return (SK_PNMI_ERR_BAD_VALUE);
2480 }
2481
2482 /* A preset ends here */
2483 if (Action == SK_PNMI_PRESET) {
2484
2485 return (SK_PNMI_ERR_OK);
2486 }
2487
2488 switch (ActionOp) {
2489
2490 case SK_PNMI_ACT_IDLE:
2491 /* Nothing to do */
2492 break;
2493
2494 case SK_PNMI_ACT_RESET:
2495 /*
2496 * Perform a driver reset or something that comes near
2497 * to this.
2498 */
2499 Ret = SK_DRIVER_RESET(pAC, IoC);
2500 if (Ret != 0) {
2501
2502 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
2503 SK_PNMI_ERR005MSG);
2504
2505 return (SK_PNMI_ERR_GENERAL);
2506 }
2507 break;
2508
2509 case SK_PNMI_ACT_SELFTEST:
2510 /*
2511 * Perform a driver selftest or something similar to this.
2512 * Currently this feature is not used and will probably
2513 * implemented in another way.
2514 */
2515 Ret = SK_DRIVER_SELFTEST(pAC, IoC);
2516 pAC->Pnmi.TestResult = Ret;
2517 break;
2518
2519 case SK_PNMI_ACT_RESETCNT:
2520 /* Set all counters and timestamps to zero */
2521 ResetCounter(pAC, IoC, NetIndex);
2522 break;
2523
2524 default:
2525 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
2526 SK_PNMI_ERR006MSG);
2527
2528 return (SK_PNMI_ERR_GENERAL);
2529 }
2530
2531 return (SK_PNMI_ERR_OK);
2532}
2533
2534/*****************************************************************************
2535 *
2536 * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX
2537 *
2538 * Description:
2539 * Retrieves the statistic values of the virtual port (logical
2540 * index 0). Only special OIDs of NDIS are handled which consist
2541 * of a 32 bit instead of a 64 bit value. The OIDs are public
2542 * because perhaps some other platform can use them too.
2543 *
2544 * Returns:
2545 * SK_PNMI_ERR_OK The request was successfully performed.
2546 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2547 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2548 * the correct data (e.g. a 32bit value is
2549 * needed, but a 16 bit value was passed).
2550 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2551 * exist (e.g. port instance 3 on a two port
2552 * adapter.
2553 */
2554PNMI_STATIC int Mac8023Stat(
2555SK_AC *pAC, /* Pointer to adapter context */
2556SK_IOC IoC, /* IO context handle */
2557int Action, /* Get/PreSet/Set action */
2558SK_U32 Id, /* Object ID that is to be processed */
2559char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2560unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2561SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2562unsigned int TableIndex, /* Index to the Id table */
2563SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2564{
2565 int Ret;
2566 SK_U64 StatVal;
2567 SK_U32 StatVal32;
2568 SK_BOOL Is64BitReq = SK_FALSE;
2569
2570 /*
2571 * Only the active Mac is returned
2572 */
2573 if (Instance != (SK_U32)(-1) && Instance != 1) {
2574
2575 *pLen = 0;
2576 return (SK_PNMI_ERR_UNKNOWN_INST);
2577 }
2578
2579 /*
2580 * Check action type
2581 */
2582 if (Action != SK_PNMI_GET) {
2583
2584 *pLen = 0;
2585 return (SK_PNMI_ERR_READ_ONLY);
2586 }
2587
2588 /*
2589 * Check length
2590 */
2591 switch (Id) {
2592
2593 case OID_802_3_PERMANENT_ADDRESS:
2594 case OID_802_3_CURRENT_ADDRESS:
2595 if (*pLen < sizeof(SK_MAC_ADDR)) {
2596
2597 *pLen = sizeof(SK_MAC_ADDR);
2598 return (SK_PNMI_ERR_TOO_SHORT);
2599 }
2600 break;
2601
2602 default:
2603#ifndef SK_NDIS_64BIT_CTR
2604 if (*pLen < sizeof(SK_U32)) {
2605 *pLen = sizeof(SK_U32);
2606 return (SK_PNMI_ERR_TOO_SHORT);
2607 }
2608
2609#else /* SK_NDIS_64BIT_CTR */
2610
2611 /*
2612 * for compatibility, at least 32bit are required for oid
2613 */
2614 if (*pLen < sizeof(SK_U32)) {
2615 /*
2616 * but indicate handling for 64bit values,
2617 * if insufficient space is provided
2618 */
2619 *pLen = sizeof(SK_U64);
2620 return (SK_PNMI_ERR_TOO_SHORT);
2621 }
2622
2623 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
2624#endif /* SK_NDIS_64BIT_CTR */
2625 break;
2626 }
2627
2628 /*
2629 * Update all statistics, because we retrieve virtual MAC, which
2630 * consists of multiple physical statistics and increment semaphore
2631 * to indicate that an update was already done.
2632 */
2633 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2634 if ( Ret != SK_PNMI_ERR_OK) {
2635
2636 *pLen = 0;
2637 return (Ret);
2638 }
2639 pAC->Pnmi.MacUpdatedFlag ++;
2640
2641 /*
2642 * Get value (MAC Index 0 identifies the virtual MAC)
2643 */
2644 switch (Id) {
2645
2646 case OID_802_3_PERMANENT_ADDRESS:
2647 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2648 *pLen = sizeof(SK_MAC_ADDR);
2649 break;
2650
2651 case OID_802_3_CURRENT_ADDRESS:
2652 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2653 *pLen = sizeof(SK_MAC_ADDR);
2654 break;
2655
2656 default:
2657 StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
2658
2659 /*
2660 * by default 32bit values are evaluated
2661 */
2662 if (!Is64BitReq) {
2663 StatVal32 = (SK_U32)StatVal;
2664 SK_PNMI_STORE_U32(pBuf, StatVal32);
2665 *pLen = sizeof(SK_U32);
2666 }
2667 else {
2668 SK_PNMI_STORE_U64(pBuf, StatVal);
2669 *pLen = sizeof(SK_U64);
2670 }
2671 break;
2672 }
2673
2674 pAC->Pnmi.MacUpdatedFlag --;
2675
2676 return (SK_PNMI_ERR_OK);
2677}
2678
2679/*****************************************************************************
2680 *
2681 * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX
2682 *
2683 * Description:
2684 * Retrieves the XMAC statistic data.
2685 *
2686 * Returns:
2687 * SK_PNMI_ERR_OK The request was successfully performed.
2688 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2689 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2690 * the correct data (e.g. a 32bit value is
2691 * needed, but a 16 bit value was passed).
2692 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2693 * exist (e.g. port instance 3 on a two port
2694 * adapter.
2695 */
2696PNMI_STATIC int MacPrivateStat(
2697SK_AC *pAC, /* Pointer to adapter context */
2698SK_IOC IoC, /* IO context handle */
2699int Action, /* Get/PreSet/Set action */
2700SK_U32 Id, /* Object ID that is to be processed */
2701char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2702unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2703SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2704unsigned int TableIndex, /* Index to the Id table */
2705SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2706{
2707 unsigned int LogPortMax;
2708 unsigned int LogPortIndex;
2709 unsigned int PhysPortMax;
2710 unsigned int Limit;
2711 unsigned int Offset;
2712 int Ret;
2713 SK_U64 StatVal;
2714
2715
2716 /*
2717 * Calculate instance if wished. MAC index 0 is the virtual
2718 * MAC.
2719 */
2720 PhysPortMax = pAC->GIni.GIMacsFound;
2721 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2722
2723 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2724 LogPortMax--;
2725 }
2726
2727 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2728 /* Check instance range */
2729 if ((Instance < 1) || (Instance > LogPortMax)) {
2730
2731 *pLen = 0;
2732 return (SK_PNMI_ERR_UNKNOWN_INST);
2733 }
2734 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2735 Limit = LogPortIndex + 1;
2736 }
2737
2738 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2739
2740 LogPortIndex = 0;
2741 Limit = LogPortMax;
2742 }
2743
2744
2745 /*
2746 * Check action
2747 */
2748 if (Action != SK_PNMI_GET) {
2749
2750 *pLen = 0;
2751 return (SK_PNMI_ERR_READ_ONLY);
2752 }
2753
2754 /*
2755 * Check length
2756 */
2757 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
2758
2759 *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
2760 return (SK_PNMI_ERR_TOO_SHORT);
2761 }
2762
2763 /*
2764 * Update XMAC statistic and increment semaphore to indicate that
2765 * an update was already done.
2766 */
2767 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2768 if (Ret != SK_PNMI_ERR_OK) {
2769
2770 *pLen = 0;
2771 return (Ret);
2772 }
2773 pAC->Pnmi.MacUpdatedFlag ++;
2774
2775 /*
2776 * Get value
2777 */
2778 Offset = 0;
2779 for (; LogPortIndex < Limit; LogPortIndex ++) {
2780
2781 switch (Id) {
2782
2783/* XXX not yet implemented due to XMAC problems
2784 case OID_SKGE_STAT_TX_UTIL:
2785 return (SK_PNMI_ERR_GENERAL);
2786*/
2787/* XXX not yet implemented due to XMAC problems
2788 case OID_SKGE_STAT_RX_UTIL:
2789 return (SK_PNMI_ERR_GENERAL);
2790*/
2791 case OID_SKGE_STAT_RX:
2792 case OID_SKGE_STAT_TX:
2793 switch (pAC->GIni.GIMacType) {
2794 case SK_MAC_XMAC:
2795 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2796 IdTable[TableIndex].Param, NetIndex);
2797 break;
2798
2799 case SK_MAC_GMAC:
2800 if (Id == OID_SKGE_STAT_TX) {
2801
2802 StatVal =
2803 GetStatVal(pAC, IoC, LogPortIndex,
2804 SK_PNMI_HTX_BROADCAST, NetIndex) +
2805 GetStatVal(pAC, IoC, LogPortIndex,
2806 SK_PNMI_HTX_MULTICAST, NetIndex) +
2807 GetStatVal(pAC, IoC, LogPortIndex,
2808 SK_PNMI_HTX_UNICAST, NetIndex);
2809 }
2810 else {
2811 StatVal =
2812 GetStatVal(pAC, IoC, LogPortIndex,
2813 SK_PNMI_HRX_BROADCAST, NetIndex) +
2814 GetStatVal(pAC, IoC, LogPortIndex,
2815 SK_PNMI_HRX_MULTICAST, NetIndex) +
2816 GetStatVal(pAC, IoC, LogPortIndex,
2817 SK_PNMI_HRX_UNICAST, NetIndex) +
2818 GetStatVal(pAC, IoC, LogPortIndex,
2819 SK_PNMI_HRX_UNDERSIZE, NetIndex);
2820 }
2821 break;
2822
2823 default:
2824 StatVal = 0;
2825 break;
2826 }
2827
2828 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2829 break;
2830
2831 default:
2832 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2833 IdTable[TableIndex].Param, NetIndex);
2834 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2835 break;
2836 }
2837
2838 Offset += sizeof(SK_U64);
2839 }
2840 *pLen = Offset;
2841
2842 pAC->Pnmi.MacUpdatedFlag --;
2843
2844 return (SK_PNMI_ERR_OK);
2845}
2846
2847/*****************************************************************************
2848 *
2849 * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR
2850 *
2851 * Description:
2852 * Get/Presets/Sets the current and factory MAC address. The MAC
2853 * address of the virtual port, which is reported to the OS, may
2854 * not be changed, but the physical ones. A set to the virtual port
2855 * will be ignored. No error should be reported because otherwise
2856 * a multiple instance set (-1) would always fail.
2857 *
2858 * Returns:
2859 * SK_PNMI_ERR_OK The request was successfully performed.
2860 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2861 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2862 * the correct data (e.g. a 32bit value is
2863 * needed, but a 16 bit value was passed).
2864 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2865 * value range.
2866 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2867 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2868 * exist (e.g. port instance 3 on a two port
2869 * adapter.
2870 */
2871PNMI_STATIC int Addr(
2872SK_AC *pAC, /* Pointer to adapter context */
2873SK_IOC IoC, /* IO context handle */
2874int Action, /* Get/PreSet/Set action */
2875SK_U32 Id, /* Object ID that is to be processed */
2876char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2877unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2878SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2879unsigned int TableIndex, /* Index to the Id table */
2880SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2881{
2882 int Ret;
2883 unsigned int LogPortMax;
2884 unsigned int PhysPortMax;
2885 unsigned int LogPortIndex;
2886 unsigned int PhysPortIndex;
2887 unsigned int Limit;
2888 unsigned int Offset = 0;
2889
2890 /*
2891 * Calculate instance if wished. MAC index 0 is the virtual
2892 * MAC.
2893 */
2894 PhysPortMax = pAC->GIni.GIMacsFound;
2895 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2896
2897 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2898 LogPortMax--;
2899 }
2900
2901 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2902 /* Check instance range */
2903 if ((Instance < 1) || (Instance > LogPortMax)) {
2904
2905 *pLen = 0;
2906 return (SK_PNMI_ERR_UNKNOWN_INST);
2907 }
2908 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2909 Limit = LogPortIndex + 1;
2910 }
2911
2912 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2913
2914 LogPortIndex = 0;
2915 Limit = LogPortMax;
2916 }
2917
2918 /*
2919 * Perform Action
2920 */
2921 if (Action == SK_PNMI_GET) {
2922
2923 /*
2924 * Check length
2925 */
2926 if (*pLen < (Limit - LogPortIndex) * 6) {
2927
2928 *pLen = (Limit - LogPortIndex) * 6;
2929 return (SK_PNMI_ERR_TOO_SHORT);
2930 }
2931
2932 /*
2933 * Get value
2934 */
2935 for (; LogPortIndex < Limit; LogPortIndex ++) {
2936
2937 switch (Id) {
2938
2939 case OID_SKGE_PHYS_CUR_ADDR:
2940 if (LogPortIndex == 0) {
2941 CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2942 }
2943 else {
2944 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
2945
2946 CopyMac(pBuf + Offset,
2947 &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
2948 }
2949 Offset += 6;
2950 break;
2951
2952 case OID_SKGE_PHYS_FAC_ADDR:
2953 if (LogPortIndex == 0) {
2954 CopyMac(pBuf + Offset,
2955 &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2956 }
2957 else {
2958 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
2959 pAC, LogPortIndex);
2960
2961 CopyMac(pBuf + Offset,
2962 &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
2963 }
2964 Offset += 6;
2965 break;
2966
2967 default:
2968 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
2969 SK_PNMI_ERR008MSG);
2970
2971 *pLen = 0;
2972 return (SK_PNMI_ERR_GENERAL);
2973 }
2974 }
2975
2976 *pLen = Offset;
2977 }
2978 else {
2979 /*
2980 * The logical MAC address may not be changed only
2981 * the physical ones
2982 */
2983 if (Id == OID_SKGE_PHYS_FAC_ADDR) {
2984
2985 *pLen = 0;
2986 return (SK_PNMI_ERR_READ_ONLY);
2987 }
2988
2989 /*
2990 * Only the current address may be changed
2991 */
2992 if (Id != OID_SKGE_PHYS_CUR_ADDR) {
2993
2994 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
2995 SK_PNMI_ERR009MSG);
2996
2997 *pLen = 0;
2998 return (SK_PNMI_ERR_GENERAL);
2999 }
3000
3001 /*
3002 * Check length
3003 */
3004 if (*pLen < (Limit - LogPortIndex) * 6) {
3005
3006 *pLen = (Limit - LogPortIndex) * 6;
3007 return (SK_PNMI_ERR_TOO_SHORT);
3008 }
3009 if (*pLen > (Limit - LogPortIndex) * 6) {
3010
3011 *pLen = 0;
3012 return (SK_PNMI_ERR_BAD_VALUE);
3013 }
3014
3015 /*
3016 * Check Action
3017 */
3018 if (Action == SK_PNMI_PRESET) {
3019
3020 *pLen = 0;
3021 return (SK_PNMI_ERR_OK);
3022 }
3023
3024 /*
3025 * Set OID_SKGE_MAC_CUR_ADDR
3026 */
3027 for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
3028
3029 /*
3030 * A set to virtual port and set of broadcast
3031 * address will be ignored
3032 */
3033 if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
3034 "\xff\xff\xff\xff\xff\xff", 6) == 0) {
3035
3036 continue;
3037 }
3038
3039 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
3040 LogPortIndex);
3041
3042 Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
3043 (SK_MAC_ADDR *)(pBuf + Offset),
3044 (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
3045 SK_ADDR_PHYSICAL_ADDRESS));
3046 if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {
3047
3048 return (SK_PNMI_ERR_GENERAL);
3049 }
3050 }
3051 *pLen = Offset;
3052 }
3053
3054 return (SK_PNMI_ERR_OK);
3055}
3056
3057/*****************************************************************************
3058 *
3059 * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
3060 *
3061 * Description:
3062 * Retrieves the statistic values of the CSUM module. The CSUM data
3063 * structure must be available in the SK_AC even if the CSUM module
3064 * is not included, because PNMI reads the statistic data from the
3065 * CSUM part of SK_AC directly.
3066 *
3067 * Returns:
3068 * SK_PNMI_ERR_OK The request was successfully performed.
3069 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3070 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3071 * the correct data (e.g. a 32bit value is
3072 * needed, but a 16 bit value was passed).
3073 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3074 * exist (e.g. port instance 3 on a two port
3075 * adapter.
3076 */
3077PNMI_STATIC int CsumStat(
3078SK_AC *pAC, /* Pointer to adapter context */
3079SK_IOC IoC, /* IO context handle */
3080int Action, /* Get/PreSet/Set action */
3081SK_U32 Id, /* Object ID that is to be processed */
3082char *pBuf, /* Buffer to which to mgmt data will be retrieved */
3083unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3084SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3085unsigned int TableIndex, /* Index to the Id table */
3086SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
3087{
3088 unsigned int Index;
3089 unsigned int Limit;
3090 unsigned int Offset = 0;
3091 SK_U64 StatVal;
3092
3093
3094 /*
3095 * Calculate instance if wished
3096 */
3097 if (Instance != (SK_U32)(-1)) {
3098
3099 if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
3100
3101 *pLen = 0;
3102 return (SK_PNMI_ERR_UNKNOWN_INST);
3103 }
3104 Index = (unsigned int)Instance - 1;
3105 Limit = Index + 1;
3106 }
3107 else {
3108 Index = 0;
3109 Limit = SKCS_NUM_PROTOCOLS;
3110 }
3111
3112 /*
3113 * Check action
3114 */
3115 if (Action != SK_PNMI_GET) {
3116
3117 *pLen = 0;
3118 return (SK_PNMI_ERR_READ_ONLY);
3119 }
3120
3121 /*
3122 * Check length
3123 */
3124 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
3125
3126 *pLen = (Limit - Index) * sizeof(SK_U64);
3127 return (SK_PNMI_ERR_TOO_SHORT);
3128 }
3129
3130 /*
3131 * Get value
3132 */
3133 for (; Index < Limit; Index ++) {
3134
3135 switch (Id) {
3136
3137 case OID_SKGE_CHKSM_RX_OK_CTS:
3138 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
3139 break;
3140
3141 case OID_SKGE_CHKSM_RX_UNABLE_CTS:
3142 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
3143 break;
3144
3145 case OID_SKGE_CHKSM_RX_ERR_CTS:
3146 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
3147 break;
3148
3149 case OID_SKGE_CHKSM_TX_OK_CTS:
3150 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
3151 break;
3152
3153 case OID_SKGE_CHKSM_TX_UNABLE_CTS:
3154 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
3155 break;
3156
3157 default:
3158 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
3159 SK_PNMI_ERR010MSG);
3160
3161 *pLen = 0;
3162 return (SK_PNMI_ERR_GENERAL);
3163 }
3164
3165 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
3166 Offset += sizeof(SK_U64);
3167 }
3168
3169 /*
3170 * Store used buffer space
3171 */
3172 *pLen = Offset;
3173
3174 return (SK_PNMI_ERR_OK);
3175}
3176
3177/*****************************************************************************
3178 *
3179 * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
3180 *
3181 * Description:
3182 * Retrieves the statistic values of the I2C module, which handles
3183 * the temperature and voltage sensors.
3184 *
3185 * Returns:
3186 * SK_PNMI_ERR_OK The request was successfully performed.
3187 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3188 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3189 * the correct data (e.g. a 32bit value is
3190 * needed, but a 16 bit value was passed).
3191 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3192 * exist (e.g. port instance 3 on a two port
3193 * adapter.
3194 */
3195PNMI_STATIC int SensorStat(
3196SK_AC *pAC, /* Pointer to adapter context */
3197SK_IOC IoC, /* IO context handle */
3198int Action, /* Get/PreSet/Set action */
3199SK_U32 Id, /* Object ID that is to be processed */
3200char *pBuf, /* Buffer to which to mgmt data will be retrieved */
3201unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3202SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3203unsigned int TableIndex, /* Index to the Id table */
3204SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
3205{
3206 unsigned int i;
3207 unsigned int Index;
3208 unsigned int Limit;
3209 unsigned int Offset;
3210 unsigned int Len;
3211 SK_U32 Val32;
3212 SK_U64 Val64;
3213
3214
3215 /*
3216 * Calculate instance if wished
3217 */
3218 if ((Instance != (SK_U32)(-1))) {
3219
3220 if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
3221
3222 *pLen = 0;
3223 return (SK_PNMI_ERR_UNKNOWN_INST);
3224 }
3225
3226 Index = (unsigned int)Instance -1;
3227 Limit = (unsigned int)Instance;
3228 }
3229 else {
3230 Index = 0;
3231 Limit = (unsigned int) pAC->I2c.MaxSens;
3232 }
3233
3234 /*
3235 * Check action
3236 */
3237 if (Action != SK_PNMI_GET) {
3238
3239 *pLen = 0;
3240 return (SK_PNMI_ERR_READ_ONLY);
3241 }
3242
3243 /*
3244 * Check length
3245 */
3246 switch (Id) {
3247
3248 case OID_SKGE_SENSOR_VALUE:
3249 case OID_SKGE_SENSOR_WAR_THRES_LOW:
3250 case OID_SKGE_SENSOR_WAR_THRES_UPP:
3251 case OID_SKGE_SENSOR_ERR_THRES_LOW:
3252 case OID_SKGE_SENSOR_ERR_THRES_UPP:
3253 if (*pLen < (Limit - Index) * sizeof(SK_U32)) {
3254
3255 *pLen = (Limit - Index) * sizeof(SK_U32);
3256 return (SK_PNMI_ERR_TOO_SHORT);
3257 }
3258 break;
3259
3260 case OID_SKGE_SENSOR_DESCR:
3261 for (Offset = 0, i = Index; i < Limit; i ++) {
3262
3263 Len = (unsigned int)
3264 SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1;
3265 if (Len >= SK_PNMI_STRINGLEN2) {
3266
3267 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011,
3268 SK_PNMI_ERR011MSG);
3269
3270 *pLen = 0;
3271 return (SK_PNMI_ERR_GENERAL);
3272 }
3273 Offset += Len;
3274 }
3275 if (*pLen < Offset) {
3276
3277 *pLen = Offset;
3278 return (SK_PNMI_ERR_TOO_SHORT);
3279 }
3280 break;
3281
3282 case OID_SKGE_SENSOR_INDEX:
3283 case OID_SKGE_SENSOR_TYPE:
3284 case OID_SKGE_SENSOR_STATUS:
3285 if (*pLen < Limit - Index) {
3286
3287 *pLen = Limit - Index;
3288 return (SK_PNMI_ERR_TOO_SHORT);
3289 }
3290 break;
3291
3292 case OID_SKGE_SENSOR_WAR_CTS:
3293 case OID_SKGE_SENSOR_WAR_TIME:
3294 case OID_SKGE_SENSOR_ERR_CTS:
3295 case OID_SKGE_SENSOR_ERR_TIME:
3296 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
3297
3298 *pLen = (Limit - Index) * sizeof(SK_U64);
3299 return (SK_PNMI_ERR_TOO_SHORT);
3300 }
3301 break;
3302
3303 default:
3304 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
3305 SK_PNMI_ERR012MSG);
3306
3307 *pLen = 0;
3308 return (SK_PNMI_ERR_GENERAL);
3309
3310 }
3311
3312 /*
3313 * Get value
3314 */
3315 for (Offset = 0; Index < Limit; Index ++) {
3316
3317 switch (Id) {
3318
3319 case OID_SKGE_SENSOR_INDEX:
3320 *(pBuf + Offset) = (char)Index;
3321 Offset += sizeof(char);
3322 break;
3323
3324 case OID_SKGE_SENSOR_DESCR:
3325 Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
3326 SK_MEMCPY(pBuf + Offset + 1,
3327 pAC->I2c.SenTable[Index].SenDesc, Len);
3328 *(pBuf + Offset) = (char)Len;
3329 Offset += Len + 1;
3330 break;
3331
3332 case OID_SKGE_SENSOR_TYPE:
3333 *(pBuf + Offset) =
3334 (char)pAC->I2c.SenTable[Index].SenType;
3335 Offset += sizeof(char);
3336 break;
3337
3338 case OID_SKGE_SENSOR_VALUE:
3339 Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
3340 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3341 Offset += sizeof(SK_U32);
3342 break;
3343
3344 case OID_SKGE_SENSOR_WAR_THRES_LOW:
3345 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
3346 SenThreWarnLow;
3347 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3348 Offset += sizeof(SK_U32);
3349 break;
3350
3351 case OID_SKGE_SENSOR_WAR_THRES_UPP:
3352 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
3353 SenThreWarnHigh;
3354 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3355 Offset += sizeof(SK_U32);
3356 break;
3357
3358 case OID_SKGE_SENSOR_ERR_THRES_LOW:
3359 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
3360 SenThreErrLow;
3361 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3362 Offset += sizeof(SK_U32);
3363 break;
3364
3365 case OID_SKGE_SENSOR_ERR_THRES_UPP:
3366 Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
3367 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3368 Offset += sizeof(SK_U32);
3369 break;
3370
3371 case OID_SKGE_SENSOR_STATUS:
3372 *(pBuf + Offset) =
3373 (char)pAC->I2c.SenTable[Index].SenErrFlag;
3374 Offset += sizeof(char);
3375 break;
3376
3377 case OID_SKGE_SENSOR_WAR_CTS:
3378 Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
3379 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3380 Offset += sizeof(SK_U64);
3381 break;
3382
3383 case OID_SKGE_SENSOR_ERR_CTS:
3384 Val64 = pAC->I2c.SenTable[Index].SenErrCts;
3385 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3386 Offset += sizeof(SK_U64);
3387 break;
3388
3389 case OID_SKGE_SENSOR_WAR_TIME:
3390 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
3391 SenBegWarnTS);
3392 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3393 Offset += sizeof(SK_U64);
3394 break;
3395
3396 case OID_SKGE_SENSOR_ERR_TIME:
3397 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
3398 SenBegErrTS);
3399 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3400 Offset += sizeof(SK_U64);
3401 break;
3402
3403 default:
3404 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
3405 ("SensorStat: Unknown OID should be handled before"));
3406
3407 return (SK_PNMI_ERR_GENERAL);
3408 }
3409 }
3410
3411 /*
3412 * Store used buffer space
3413 */
3414 *pLen = Offset;
3415
3416 return (SK_PNMI_ERR_OK);
3417}
3418
3419/*****************************************************************************
3420 *
3421 * Vpd - OID handler function of OID_SKGE_VPD_XXX
3422 *
3423 * Description:
3424 * Get/preset/set of VPD data. As instance the name of a VPD key
3425 * can be passed. The Instance parameter is a SK_U32 and can be
3426 * used as a string buffer for the VPD key, because their maximum
3427 * length is 4 byte.
3428 *
3429 * Returns:
3430 * SK_PNMI_ERR_OK The request was successfully performed.
3431 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3432 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3433 * the correct data (e.g. a 32bit value is
3434 * needed, but a 16 bit value was passed).
3435 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
3436 * value range.
3437 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
3438 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3439 * exist (e.g. port instance 3 on a two port
3440 * adapter.
3441 */
3442PNMI_STATIC int Vpd(
3443SK_AC *pAC, /* Pointer to adapter context */
3444SK_IOC IoC, /* IO context handle */
3445int Action, /* Get/PreSet/Set action */
3446SK_U32 Id, /* Object ID that is to be processed */
3447char *pBuf, /* Buffer to which to mgmt data will be retrieved */
3448unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3449SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3450unsigned int TableIndex, /* Index to the Id table */
3451SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
3452{
3453 SK_VPD_STATUS *pVpdStatus;
3454 unsigned int BufLen;
3455 char Buf[256];
3456 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
3457 char KeyStr[SK_PNMI_VPD_KEY_SIZE];
3458 unsigned int KeyNo;
3459 unsigned int Offset;
3460 unsigned int Index;
3461 unsigned int FirstIndex;
3462 unsigned int LastIndex;
3463 unsigned int Len;
3464 int Ret;
3465 SK_U32 Val32;
3466
3467 /*
3468 * Get array of all currently stored VPD keys
3469 */
3470 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr),
3471 &KeyNo);
3472 if (Ret != SK_PNMI_ERR_OK) {
3473 *pLen = 0;
3474 return (Ret);
3475 }
3476
3477 /*
3478 * If instance is not -1, try to find the requested VPD key for
3479 * the multiple instance variables. The other OIDs as for example
3480 * OID VPD_ACTION are single instance variables and must be
3481 * handled separatly.
3482 */
3483 FirstIndex = 0;
3484 LastIndex = KeyNo;
3485
3486 if ((Instance != (SK_U32)(-1))) {
3487
3488 if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
3489 Id == OID_SKGE_VPD_ACCESS) {
3490
3491 SK_STRNCPY(KeyStr, (char *)&Instance, 4);
3492 KeyStr[4] = 0;
3493
3494 for (Index = 0; Index < KeyNo; Index ++) {
3495
3496 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3497 FirstIndex = Index;
3498 LastIndex = Index+1;
3499 break;
3500 }
3501 }
3502 if (Index == KeyNo) {
3503
3504 *pLen = 0;
3505 return (SK_PNMI_ERR_UNKNOWN_INST);
3506 }
3507 }
3508 else if (Instance != 1) {
3509
3510 *pLen = 0;
3511 return (SK_PNMI_ERR_UNKNOWN_INST);
3512 }
3513 }
3514
3515 /*
3516 * Get value, if a query should be performed
3517 */
3518 if (Action == SK_PNMI_GET) {
3519
3520 switch (Id) {
3521
3522 case OID_SKGE_VPD_FREE_BYTES:
3523 /* Check length of buffer */
3524 if (*pLen < sizeof(SK_U32)) {
3525
3526 *pLen = sizeof(SK_U32);
3527 return (SK_PNMI_ERR_TOO_SHORT);
3528 }
3529 /* Get number of free bytes */
3530 pVpdStatus = VpdStat(pAC, IoC);
3531 if (pVpdStatus == NULL) {
3532
3533 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
3534 SK_PNMI_ERR017MSG);
3535
3536 *pLen = 0;
3537 return (SK_PNMI_ERR_GENERAL);
3538 }
3539 if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
3540
3541 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
3542 SK_PNMI_ERR018MSG);
3543
3544 *pLen = 0;
3545 return (SK_PNMI_ERR_GENERAL);
3546 }
wdenk9c53f402003-10-15 23:53:47 +00003547
wdenkeb20ad32003-09-05 23:19:14 +00003548 Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
3549 SK_PNMI_STORE_U32(pBuf, Val32);
3550 *pLen = sizeof(SK_U32);
3551 break;
3552
3553 case OID_SKGE_VPD_ENTRIES_LIST:
3554 /* Check length */
3555 for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
3556
3557 Len += SK_STRLEN(KeyArr[Index]) + 1;
3558 }
3559 if (*pLen < Len) {
3560
3561 *pLen = Len;
3562 return (SK_PNMI_ERR_TOO_SHORT);
3563 }
3564
3565 /* Get value */
3566 *(pBuf) = (char)Len - 1;
3567 for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
3568
3569 Len = SK_STRLEN(KeyArr[Index]);
3570 SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
3571
3572 Offset += Len;
3573
3574 if (Index < KeyNo - 1) {
3575
3576 *(pBuf + Offset) = ' ';
3577 Offset ++;
3578 }
3579 }
3580 *pLen = Offset;
3581 break;
3582
3583 case OID_SKGE_VPD_ENTRIES_NUMBER:
3584 /* Check length */
3585 if (*pLen < sizeof(SK_U32)) {
3586
3587 *pLen = sizeof(SK_U32);
3588 return (SK_PNMI_ERR_TOO_SHORT);
3589 }
3590
3591 Val32 = (SK_U32)KeyNo;
3592 SK_PNMI_STORE_U32(pBuf, Val32);
3593 *pLen = sizeof(SK_U32);
3594 break;
3595
3596 case OID_SKGE_VPD_KEY:
3597 /* Check buffer length, if it is large enough */
3598 for (Len = 0, Index = FirstIndex;
3599 Index < LastIndex; Index ++) {
3600
3601 Len += SK_STRLEN(KeyArr[Index]) + 1;
3602 }
3603 if (*pLen < Len) {
3604
3605 *pLen = Len;
3606 return (SK_PNMI_ERR_TOO_SHORT);
3607 }
3608
3609 /*
3610 * Get the key to an intermediate buffer, because
3611 * we have to prepend a length byte.
3612 */
3613 for (Offset = 0, Index = FirstIndex;
3614 Index < LastIndex; Index ++) {
3615
3616 Len = SK_STRLEN(KeyArr[Index]);
3617
3618 *(pBuf + Offset) = (char)Len;
3619 SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
3620 Len);
3621 Offset += Len + 1;
3622 }
3623 *pLen = Offset;
3624 break;
3625
3626 case OID_SKGE_VPD_VALUE:
3627 /* Check the buffer length if it is large enough */
3628 for (Offset = 0, Index = FirstIndex;
3629 Index < LastIndex; Index ++) {
3630
3631 BufLen = 256;
3632 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3633 (int *)&BufLen) > 0 ||
3634 BufLen >= SK_PNMI_VPD_DATALEN) {
3635
3636 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3637 SK_PNMI_ERR021,
3638 SK_PNMI_ERR021MSG);
3639
3640 return (SK_PNMI_ERR_GENERAL);
3641 }
3642 Offset += BufLen + 1;
3643 }
3644 if (*pLen < Offset) {
3645
3646 *pLen = Offset;
3647 return (SK_PNMI_ERR_TOO_SHORT);
3648 }
3649
3650 /*
3651 * Get the value to an intermediate buffer, because
3652 * we have to prepend a length byte.
3653 */
3654 for (Offset = 0, Index = FirstIndex;
3655 Index < LastIndex; Index ++) {
3656
3657 BufLen = 256;
3658 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3659 (int *)&BufLen) > 0 ||
3660 BufLen >= SK_PNMI_VPD_DATALEN) {
3661
3662 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3663 SK_PNMI_ERR022,
3664 SK_PNMI_ERR022MSG);
3665
3666 *pLen = 0;
3667 return (SK_PNMI_ERR_GENERAL);
3668 }
3669
3670 *(pBuf + Offset) = (char)BufLen;
3671 SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
3672 Offset += BufLen + 1;
3673 }
3674 *pLen = Offset;
3675 break;
3676
3677 case OID_SKGE_VPD_ACCESS:
3678 if (*pLen < LastIndex - FirstIndex) {
3679
3680 *pLen = LastIndex - FirstIndex;
3681 return (SK_PNMI_ERR_TOO_SHORT);
3682 }
3683
3684 for (Offset = 0, Index = FirstIndex;
3685 Index < LastIndex; Index ++) {
3686
3687 if (VpdMayWrite(KeyArr[Index])) {
3688
3689 *(pBuf + Offset) = SK_PNMI_VPD_RW;
3690 }
3691 else {
3692 *(pBuf + Offset) = SK_PNMI_VPD_RO;
3693 }
3694 Offset ++;
3695 }
3696 *pLen = Offset;
3697 break;
3698
3699 case OID_SKGE_VPD_ACTION:
3700 Offset = LastIndex - FirstIndex;
3701 if (*pLen < Offset) {
3702
3703 *pLen = Offset;
3704 return (SK_PNMI_ERR_TOO_SHORT);
3705 }
3706 SK_MEMSET(pBuf, 0, Offset);
3707 *pLen = Offset;
3708 break;
3709
3710 default:
3711 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
3712 SK_PNMI_ERR023MSG);
3713
3714 *pLen = 0;
3715 return (SK_PNMI_ERR_GENERAL);
3716 }
wdenk9c53f402003-10-15 23:53:47 +00003717 }
wdenkeb20ad32003-09-05 23:19:14 +00003718 else {
3719 /* The only OID which can be set is VPD_ACTION */
3720 if (Id != OID_SKGE_VPD_ACTION) {
3721
3722 if (Id == OID_SKGE_VPD_FREE_BYTES ||
3723 Id == OID_SKGE_VPD_ENTRIES_LIST ||
3724 Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
3725 Id == OID_SKGE_VPD_KEY ||
3726 Id == OID_SKGE_VPD_VALUE ||
3727 Id == OID_SKGE_VPD_ACCESS) {
3728
3729 *pLen = 0;
3730 return (SK_PNMI_ERR_READ_ONLY);
3731 }
3732
3733 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
3734 SK_PNMI_ERR024MSG);
3735
3736 *pLen = 0;
3737 return (SK_PNMI_ERR_GENERAL);
3738 }
3739
3740 /*
3741 * From this point we handle VPD_ACTION. Check the buffer
3742 * length. It should at least have the size of one byte.
3743 */
3744 if (*pLen < 1) {
3745
3746 *pLen = 1;
3747 return (SK_PNMI_ERR_TOO_SHORT);
3748 }
3749
3750 /*
3751 * The first byte contains the VPD action type we should
3752 * perform.
3753 */
3754 switch (*pBuf) {
3755
3756 case SK_PNMI_VPD_IGNORE:
3757 /* Nothing to do */
3758 break;
3759
3760 case SK_PNMI_VPD_CREATE:
3761 /*
3762 * We have to create a new VPD entry or we modify
3763 * an existing one. Check first the buffer length.
3764 */
3765 if (*pLen < 4) {
3766
3767 *pLen = 4;
3768 return (SK_PNMI_ERR_TOO_SHORT);
3769 }
3770 KeyStr[0] = pBuf[1];
3771 KeyStr[1] = pBuf[2];
3772 KeyStr[2] = 0;
3773
3774 /*
3775 * Is the entry writable or does it belong to the
3776 * read-only area?
3777 */
3778 if (!VpdMayWrite(KeyStr)) {
3779
3780 *pLen = 0;
3781 return (SK_PNMI_ERR_BAD_VALUE);
3782 }
3783
3784 Offset = (int)pBuf[3] & 0xFF;
3785
3786 SK_MEMCPY(Buf, pBuf + 4, Offset);
3787 Buf[Offset] = 0;
3788
3789 /* A preset ends here */
3790 if (Action == SK_PNMI_PRESET) {
3791
3792 return (SK_PNMI_ERR_OK);
3793 }
3794
3795 /* Write the new entry or modify an existing one */
3796 Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
3797 if (Ret == SK_PNMI_VPD_NOWRITE ) {
3798
3799 *pLen = 0;
3800 return (SK_PNMI_ERR_BAD_VALUE);
3801 }
3802 else if (Ret != SK_PNMI_VPD_OK) {
3803
3804 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
3805 SK_PNMI_ERR025MSG);
3806
3807 *pLen = 0;
3808 return (SK_PNMI_ERR_GENERAL);
3809 }
3810
3811 /*
3812 * Perform an update of the VPD data. This is
3813 * not mandantory, but just to be sure.
3814 */
3815 Ret = VpdUpdate(pAC, IoC);
3816 if (Ret != SK_PNMI_VPD_OK) {
3817
3818 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
3819 SK_PNMI_ERR026MSG);
3820
3821 *pLen = 0;
3822 return (SK_PNMI_ERR_GENERAL);
3823 }
3824 break;
3825
3826 case SK_PNMI_VPD_DELETE:
3827 /* Check if the buffer size is plausible */
3828 if (*pLen < 3) {
3829
3830 *pLen = 3;
3831 return (SK_PNMI_ERR_TOO_SHORT);
3832 }
3833 if (*pLen > 3) {
3834
3835 *pLen = 0;
3836 return (SK_PNMI_ERR_BAD_VALUE);
3837 }
3838 KeyStr[0] = pBuf[1];
3839 KeyStr[1] = pBuf[2];
3840 KeyStr[2] = 0;
3841
3842 /* Find the passed key in the array */
3843 for (Index = 0; Index < KeyNo; Index ++) {
3844
3845 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3846
3847 break;
3848 }
3849 }
3850 /*
3851 * If we cannot find the key it is wrong, so we
3852 * return an appropriate error value.
3853 */
3854 if (Index == KeyNo) {
3855
3856 *pLen = 0;
3857 return (SK_PNMI_ERR_BAD_VALUE);
3858 }
3859
3860 if (Action == SK_PNMI_PRESET) {
3861
3862 return (SK_PNMI_ERR_OK);
3863 }
3864
3865 /* Ok, you wanted it and you will get it */
3866 Ret = VpdDelete(pAC, IoC, KeyStr);
3867 if (Ret != SK_PNMI_VPD_OK) {
3868
3869 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
3870 SK_PNMI_ERR027MSG);
3871
3872 *pLen = 0;
3873 return (SK_PNMI_ERR_GENERAL);
3874 }
3875
3876 /*
3877 * Perform an update of the VPD data. This is
3878 * not mandantory, but just to be sure.
3879 */
3880 Ret = VpdUpdate(pAC, IoC);
3881 if (Ret != SK_PNMI_VPD_OK) {
3882
3883 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
3884 SK_PNMI_ERR028MSG);
3885
3886 *pLen = 0;
3887 return (SK_PNMI_ERR_GENERAL);
3888 }
3889 break;
3890
3891 default:
3892 *pLen = 0;
3893 return (SK_PNMI_ERR_BAD_VALUE);
3894 }
3895 }
3896
3897 return (SK_PNMI_ERR_OK);
3898}
3899
3900/*****************************************************************************
3901 *
3902 * General - OID handler function of various single instance OIDs
3903 *
3904 * Description:
3905 * The code is simple. No description necessary.
3906 *
3907 * Returns:
3908 * SK_PNMI_ERR_OK The request was successfully performed.
3909 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3910 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3911 * the correct data (e.g. a 32bit value is
3912 * needed, but a 16 bit value was passed).
3913 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3914 * exist (e.g. port instance 3 on a two port
3915 * adapter.
3916 */
3917PNMI_STATIC int General(
3918SK_AC *pAC, /* Pointer to adapter context */
3919SK_IOC IoC, /* IO context handle */
3920int Action, /* Get/PreSet/Set action */
3921SK_U32 Id, /* Object ID that is to be processed */
3922char *pBuf, /* Buffer to which to mgmt data will be retrieved */
3923unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3924SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3925unsigned int TableIndex, /* Index to the Id table */
3926SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
3927{
3928 int Ret;
3929 unsigned int Index;
3930 unsigned int Len;
3931 unsigned int Offset;
3932 unsigned int Val;
3933 SK_U8 Val8;
3934 SK_U16 Val16;
3935 SK_U32 Val32;
3936 SK_U64 Val64;
3937 SK_U64 Val64RxHwErrs = 0;
3938 SK_U64 Val64TxHwErrs = 0;
3939 SK_BOOL Is64BitReq = SK_FALSE;
3940 char Buf[256];
3941 int MacType;
3942
3943 /*
3944 * Check instance. We only handle single instance variables
3945 */
3946 if (Instance != (SK_U32)(-1) && Instance != 1) {
3947
3948 *pLen = 0;
3949 return (SK_PNMI_ERR_UNKNOWN_INST);
3950 }
3951
3952 /*
3953 * Check action. We only allow get requests.
3954 */
3955 if (Action != SK_PNMI_GET) {
3956
3957 *pLen = 0;
3958 return (SK_PNMI_ERR_READ_ONLY);
3959 }
wdenk9c53f402003-10-15 23:53:47 +00003960
wdenkeb20ad32003-09-05 23:19:14 +00003961 MacType = pAC->GIni.GIMacType;
wdenk9c53f402003-10-15 23:53:47 +00003962
wdenkeb20ad32003-09-05 23:19:14 +00003963 /*
3964 * Check length for the various supported OIDs
3965 */
3966 switch (Id) {
3967
3968 case OID_GEN_XMIT_ERROR:
3969 case OID_GEN_RCV_ERROR:
3970 case OID_GEN_RCV_NO_BUFFER:
3971#ifndef SK_NDIS_64BIT_CTR
3972 if (*pLen < sizeof(SK_U32)) {
3973 *pLen = sizeof(SK_U32);
3974 return (SK_PNMI_ERR_TOO_SHORT);
3975 }
3976
3977#else /* SK_NDIS_64BIT_CTR */
3978
3979 /*
3980 * for compatibility, at least 32bit are required for oid
3981 */
3982 if (*pLen < sizeof(SK_U32)) {
3983 /*
3984 * but indicate handling for 64bit values,
3985 * if insufficient space is provided
3986 */
3987 *pLen = sizeof(SK_U64);
3988 return (SK_PNMI_ERR_TOO_SHORT);
3989 }
3990
3991 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
3992#endif /* SK_NDIS_64BIT_CTR */
3993 break;
3994
3995 case OID_SKGE_PORT_NUMBER:
3996 case OID_SKGE_DEVICE_TYPE:
3997 case OID_SKGE_RESULT:
3998 case OID_SKGE_RLMT_MONITOR_NUMBER:
3999 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
4000 case OID_SKGE_TRAP_NUMBER:
4001 case OID_SKGE_MDB_VERSION:
4002 if (*pLen < sizeof(SK_U32)) {
4003
4004 *pLen = sizeof(SK_U32);
4005 return (SK_PNMI_ERR_TOO_SHORT);
4006 }
4007 break;
4008
4009 case OID_SKGE_CHIPSET:
4010 if (*pLen < sizeof(SK_U16)) {
4011
4012 *pLen = sizeof(SK_U16);
4013 return (SK_PNMI_ERR_TOO_SHORT);
4014 }
4015 break;
4016
4017 case OID_SKGE_BUS_TYPE:
4018 case OID_SKGE_BUS_SPEED:
4019 case OID_SKGE_BUS_WIDTH:
4020 case OID_SKGE_SENSOR_NUMBER:
4021 case OID_SKGE_CHKSM_NUMBER:
4022 if (*pLen < sizeof(SK_U8)) {
4023
4024 *pLen = sizeof(SK_U8);
4025 return (SK_PNMI_ERR_TOO_SHORT);
4026 }
4027 break;
4028
4029 case OID_SKGE_TX_SW_QUEUE_LEN:
4030 case OID_SKGE_TX_SW_QUEUE_MAX:
4031 case OID_SKGE_TX_RETRY:
4032 case OID_SKGE_RX_INTR_CTS:
4033 case OID_SKGE_TX_INTR_CTS:
4034 case OID_SKGE_RX_NO_BUF_CTS:
4035 case OID_SKGE_TX_NO_BUF_CTS:
4036 case OID_SKGE_TX_USED_DESCR_NO:
4037 case OID_SKGE_RX_DELIVERED_CTS:
4038 case OID_SKGE_RX_OCTETS_DELIV_CTS:
4039 case OID_SKGE_RX_HW_ERROR_CTS:
4040 case OID_SKGE_TX_HW_ERROR_CTS:
4041 case OID_SKGE_IN_ERRORS_CTS:
4042 case OID_SKGE_OUT_ERROR_CTS:
4043 case OID_SKGE_ERR_RECOVERY_CTS:
4044 case OID_SKGE_SYSUPTIME:
4045 if (*pLen < sizeof(SK_U64)) {
4046
4047 *pLen = sizeof(SK_U64);
4048 return (SK_PNMI_ERR_TOO_SHORT);
4049 }
4050 break;
4051
4052 default:
4053 /* Checked later */
4054 break;
4055 }
4056
4057 /* Update statistic */
4058 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
4059 Id == OID_SKGE_TX_HW_ERROR_CTS ||
4060 Id == OID_SKGE_IN_ERRORS_CTS ||
4061 Id == OID_SKGE_OUT_ERROR_CTS ||
4062 Id == OID_GEN_XMIT_ERROR ||
4063 Id == OID_GEN_RCV_ERROR) {
4064
4065 /* Force the XMAC to update its statistic counters and
4066 * Increment semaphore to indicate that an update was
4067 * already done.
4068 */
4069 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
4070 if (Ret != SK_PNMI_ERR_OK) {
4071
4072 *pLen = 0;
4073 return (Ret);
4074 }
4075 pAC->Pnmi.MacUpdatedFlag ++;
4076
4077 /*
4078 * Some OIDs consist of multiple hardware counters. Those
4079 * values which are contained in all of them will be added
4080 * now.
4081 */
4082 switch (Id) {
4083
4084 case OID_SKGE_RX_HW_ERROR_CTS:
4085 case OID_SKGE_IN_ERRORS_CTS:
4086 case OID_GEN_RCV_ERROR:
4087 Val64RxHwErrs =
4088 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
4089 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
4090 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex)+
4091 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
4092 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
4093 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex)+
4094 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
4095 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
4096 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
4097 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
4098 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
4099 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
wdenk9c53f402003-10-15 23:53:47 +00004100 break;
wdenkeb20ad32003-09-05 23:19:14 +00004101
4102 case OID_SKGE_TX_HW_ERROR_CTS:
4103 case OID_SKGE_OUT_ERROR_CTS:
4104 case OID_GEN_XMIT_ERROR:
4105 Val64TxHwErrs =
4106 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
4107 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex)+
4108 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex)+
4109 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex);
4110 break;
4111 }
4112 }
4113
4114 /*
4115 * Retrieve value
4116 */
4117 switch (Id) {
4118
4119 case OID_SKGE_SUPPORTED_LIST:
4120 Len = ID_TABLE_SIZE * sizeof(SK_U32);
4121 if (*pLen < Len) {
4122
4123 *pLen = Len;
4124 return (SK_PNMI_ERR_TOO_SHORT);
4125 }
4126 for (Offset = 0, Index = 0; Offset < Len;
4127 Offset += sizeof(SK_U32), Index ++) {
4128
4129 Val32 = (SK_U32)IdTable[Index].Id;
4130 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4131 }
4132 *pLen = Len;
4133 break;
4134
4135 case OID_SKGE_PORT_NUMBER:
4136 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
4137 SK_PNMI_STORE_U32(pBuf, Val32);
4138 *pLen = sizeof(SK_U32);
4139 break;
4140
4141 case OID_SKGE_DEVICE_TYPE:
4142 Val32 = (SK_U32)pAC->Pnmi.DeviceType;
4143 SK_PNMI_STORE_U32(pBuf, Val32);
4144 *pLen = sizeof(SK_U32);
4145 break;
4146
4147 case OID_SKGE_DRIVER_DESCR:
4148 if (pAC->Pnmi.pDriverDescription == NULL) {
4149
4150 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
4151 SK_PNMI_ERR007MSG);
4152
4153 *pLen = 0;
4154 return (SK_PNMI_ERR_GENERAL);
4155 }
4156
4157 Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
4158 if (Len > SK_PNMI_STRINGLEN1) {
4159
4160 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
4161 SK_PNMI_ERR029MSG);
4162
4163 *pLen = 0;
4164 return (SK_PNMI_ERR_GENERAL);
4165 }
4166
4167 if (*pLen < Len) {
4168
4169 *pLen = Len;
4170 return (SK_PNMI_ERR_TOO_SHORT);
4171 }
4172 *pBuf = (char)(Len - 1);
4173 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
4174 *pLen = Len;
4175 break;
4176
4177 case OID_SKGE_DRIVER_VERSION:
4178 if (pAC->Pnmi.pDriverVersion == NULL) {
4179
4180 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
4181 SK_PNMI_ERR030MSG);
4182
4183 *pLen = 0;
4184 return (SK_PNMI_ERR_GENERAL);
4185 }
4186
4187 Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
4188 if (Len > SK_PNMI_STRINGLEN1) {
4189
4190 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
4191 SK_PNMI_ERR031MSG);
4192
4193 *pLen = 0;
4194 return (SK_PNMI_ERR_GENERAL);
4195 }
4196
4197 if (*pLen < Len) {
4198
4199 *pLen = Len;
4200 return (SK_PNMI_ERR_TOO_SHORT);
4201 }
4202 *pBuf = (char)(Len - 1);
4203 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
4204 *pLen = Len;
4205 break;
4206
4207 case OID_SKGE_HW_DESCR:
4208 /*
4209 * The hardware description is located in the VPD. This
4210 * query may move to the initialisation routine. But
4211 * the VPD data is cached and therefore a call here
4212 * will not make much difference.
4213 */
4214 Len = 256;
4215 if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
4216
4217 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
4218 SK_PNMI_ERR032MSG);
4219
4220 *pLen = 0;
4221 return (SK_PNMI_ERR_GENERAL);
4222 }
4223 Len ++;
4224 if (Len > SK_PNMI_STRINGLEN1) {
4225
4226 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
4227 SK_PNMI_ERR033MSG);
4228
4229 *pLen = 0;
4230 return (SK_PNMI_ERR_GENERAL);
4231 }
4232 if (*pLen < Len) {
4233
4234 *pLen = Len;
4235 return (SK_PNMI_ERR_TOO_SHORT);
4236 }
4237 *pBuf = (char)(Len - 1);
4238 SK_MEMCPY(pBuf + 1, Buf, Len - 1);
4239 *pLen = Len;
4240 break;
4241
4242 case OID_SKGE_HW_VERSION:
4243 /* Oh, I love to do some string manipulation */
4244 if (*pLen < 5) {
4245
4246 *pLen = 5;
4247 return (SK_PNMI_ERR_TOO_SHORT);
4248 }
4249 Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
4250 pBuf[0] = 4;
4251 pBuf[1] = 'v';
4252 pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
4253 pBuf[3] = '.';
4254 pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
4255 *pLen = 5;
4256 break;
4257
4258 case OID_SKGE_CHIPSET:
4259 Val16 = pAC->Pnmi.Chipset;
4260 SK_PNMI_STORE_U16(pBuf, Val16);
4261 *pLen = sizeof(SK_U16);
4262 break;
4263
4264 case OID_SKGE_BUS_TYPE:
4265 *pBuf = (char)SK_PNMI_BUS_PCI;
4266 *pLen = sizeof(char);
4267 break;
4268
4269 case OID_SKGE_BUS_SPEED:
4270 *pBuf = pAC->Pnmi.PciBusSpeed;
4271 *pLen = sizeof(char);
4272 break;
4273
4274 case OID_SKGE_BUS_WIDTH:
4275 *pBuf = pAC->Pnmi.PciBusWidth;
4276 *pLen = sizeof(char);
4277 break;
4278
4279 case OID_SKGE_RESULT:
4280 Val32 = pAC->Pnmi.TestResult;
4281 SK_PNMI_STORE_U32(pBuf, Val32);
4282 *pLen = sizeof(SK_U32);
4283 break;
4284
4285 case OID_SKGE_SENSOR_NUMBER:
4286 *pBuf = (char)pAC->I2c.MaxSens;
4287 *pLen = sizeof(char);
4288 break;
4289
4290 case OID_SKGE_CHKSM_NUMBER:
4291 *pBuf = SKCS_NUM_PROTOCOLS;
4292 *pLen = sizeof(char);
4293 break;
4294
4295 case OID_SKGE_TRAP_NUMBER:
4296 GetTrapQueueLen(pAC, &Len, &Val);
4297 Val32 = (SK_U32)Val;
4298 SK_PNMI_STORE_U32(pBuf, Val32);
4299 *pLen = sizeof(SK_U32);
4300 break;
4301
4302 case OID_SKGE_TRAP:
4303 GetTrapQueueLen(pAC, &Len, &Val);
4304 if (*pLen < Len) {
4305
4306 *pLen = Len;
4307 return (SK_PNMI_ERR_TOO_SHORT);
4308 }
4309 CopyTrapQueue(pAC, pBuf);
4310 *pLen = Len;
4311 break;
4312
4313 case OID_SKGE_RLMT_MONITOR_NUMBER:
4314/* XXX Not yet implemented by RLMT therefore we return zero elements */
4315 Val32 = 0;
4316 SK_PNMI_STORE_U32(pBuf, Val32);
4317 *pLen = sizeof(SK_U32);
4318 break;
4319
4320 case OID_SKGE_TX_SW_QUEUE_LEN:
4321 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4322 if (MacType == SK_MAC_XMAC) {
4323 /* Dual net mode */
4324 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4325 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
4326 }
4327 /* Single net mode */
4328 else {
4329 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
4330 pAC->Pnmi.BufPort[1].TxSwQueueLen;
wdenk9c53f402003-10-15 23:53:47 +00004331 }
wdenkeb20ad32003-09-05 23:19:14 +00004332 }
4333 else {
4334 /* Dual net mode */
4335 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4336 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
4337 }
4338 /* Single net mode */
4339 else {
4340 Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
4341 pAC->Pnmi.Port[1].TxSwQueueLen;
wdenk9c53f402003-10-15 23:53:47 +00004342 }
wdenkeb20ad32003-09-05 23:19:14 +00004343 }
4344 SK_PNMI_STORE_U64(pBuf, Val64);
4345 *pLen = sizeof(SK_U64);
4346 break;
4347
4348
4349 case OID_SKGE_TX_SW_QUEUE_MAX:
4350 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4351 if (MacType == SK_MAC_XMAC) {
4352 /* Dual net mode */
4353 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4354 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
4355 }
4356 /* Single net mode */
4357 else {
4358 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
4359 pAC->Pnmi.BufPort[1].TxSwQueueMax;
4360 }
4361 }
4362 else {
4363 /* Dual net mode */
4364 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4365 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
4366 }
4367 /* Single net mode */
4368 else {
4369 Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
4370 pAC->Pnmi.Port[1].TxSwQueueMax;
4371 }
4372 }
4373 SK_PNMI_STORE_U64(pBuf, Val64);
4374 *pLen = sizeof(SK_U64);
4375 break;
4376
4377 case OID_SKGE_TX_RETRY:
4378 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4379 if (MacType == SK_MAC_XMAC) {
4380 /* Dual net mode */
4381 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4382 Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
4383 }
4384 /* Single net mode */
4385 else {
4386 Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
4387 pAC->Pnmi.BufPort[1].TxRetryCts;
4388 }
4389 }
4390 else {
4391 /* Dual net mode */
4392 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4393 Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
4394 }
4395 /* Single net mode */
4396 else {
4397 Val64 = pAC->Pnmi.Port[0].TxRetryCts +
4398 pAC->Pnmi.Port[1].TxRetryCts;
4399 }
4400 }
4401 SK_PNMI_STORE_U64(pBuf, Val64);
4402 *pLen = sizeof(SK_U64);
4403 break;
4404
4405 case OID_SKGE_RX_INTR_CTS:
4406 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4407 if (MacType == SK_MAC_XMAC) {
4408 /* Dual net mode */
4409 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4410 Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
4411 }
4412 /* Single net mode */
4413 else {
4414 Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
4415 pAC->Pnmi.BufPort[1].RxIntrCts;
4416 }
4417 }
4418 else {
4419 /* Dual net mode */
4420 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4421 Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
4422 }
4423 /* Single net mode */
4424 else {
4425 Val64 = pAC->Pnmi.Port[0].RxIntrCts +
4426 pAC->Pnmi.Port[1].RxIntrCts;
4427 }
4428 }
4429 SK_PNMI_STORE_U64(pBuf, Val64);
4430 *pLen = sizeof(SK_U64);
4431 break;
4432
4433 case OID_SKGE_TX_INTR_CTS:
4434 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4435 if (MacType == SK_MAC_XMAC) {
4436 /* Dual net mode */
4437 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4438 Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
4439 }
4440 /* Single net mode */
4441 else {
4442 Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
4443 pAC->Pnmi.BufPort[1].TxIntrCts;
4444 }
4445 }
4446 else {
4447 /* Dual net mode */
4448 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4449 Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
4450 }
4451 /* Single net mode */
4452 else {
4453 Val64 = pAC->Pnmi.Port[0].TxIntrCts +
4454 pAC->Pnmi.Port[1].TxIntrCts;
4455 }
4456 }
4457 SK_PNMI_STORE_U64(pBuf, Val64);
4458 *pLen = sizeof(SK_U64);
4459 break;
4460
4461 case OID_SKGE_RX_NO_BUF_CTS:
4462 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4463 if (MacType == SK_MAC_XMAC) {
4464 /* Dual net mode */
4465 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4466 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4467 }
4468 /* Single net mode */
4469 else {
4470 Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
4471 pAC->Pnmi.BufPort[1].RxNoBufCts;
4472 }
4473 }
4474 else {
4475 /* Dual net mode */
4476 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4477 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4478 }
4479 /* Single net mode */
4480 else {
4481 Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
4482 pAC->Pnmi.Port[1].RxNoBufCts;
4483 }
4484 }
4485 SK_PNMI_STORE_U64(pBuf, Val64);
4486 *pLen = sizeof(SK_U64);
4487 break;
4488
4489 case OID_SKGE_TX_NO_BUF_CTS:
4490 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4491 if (MacType == SK_MAC_XMAC) {
4492 /* Dual net mode */
4493 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4494 Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4495 }
4496 /* Single net mode */
4497 else {
4498 Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
4499 pAC->Pnmi.BufPort[1].TxNoBufCts;
4500 }
4501 }
4502 else {
4503 /* Dual net mode */
4504 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4505 Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4506 }
4507 /* Single net mode */
4508 else {
4509 Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
4510 pAC->Pnmi.Port[1].TxNoBufCts;
4511 }
4512 }
4513 SK_PNMI_STORE_U64(pBuf, Val64);
4514 *pLen = sizeof(SK_U64);
4515 break;
4516
4517 case OID_SKGE_TX_USED_DESCR_NO:
4518 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4519 if (MacType == SK_MAC_XMAC) {
4520 /* Dual net mode */
4521 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4522 Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
4523 }
4524 /* Single net mode */
4525 else {
4526 Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
4527 pAC->Pnmi.BufPort[1].TxUsedDescrNo;
4528 }
4529 }
4530 else {
4531 /* Dual net mode */
4532 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4533 Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
4534 }
4535 /* Single net mode */
4536 else {
4537 Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
4538 pAC->Pnmi.Port[1].TxUsedDescrNo;
4539 }
4540 }
4541 SK_PNMI_STORE_U64(pBuf, Val64);
4542 *pLen = sizeof(SK_U64);
4543 break;
4544
4545 case OID_SKGE_RX_DELIVERED_CTS:
4546 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4547 if (MacType == SK_MAC_XMAC) {
4548 /* Dual net mode */
4549 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4550 Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
4551 }
4552 /* Single net mode */
4553 else {
4554 Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
4555 pAC->Pnmi.BufPort[1].RxDeliveredCts;
4556 }
4557 }
4558 else {
4559 /* Dual net mode */
4560 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4561 Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
4562 }
4563 /* Single net mode */
4564 else {
4565 Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
4566 pAC->Pnmi.Port[1].RxDeliveredCts;
4567 }
4568 }
4569 SK_PNMI_STORE_U64(pBuf, Val64);
4570 *pLen = sizeof(SK_U64);
4571 break;
4572
4573 case OID_SKGE_RX_OCTETS_DELIV_CTS:
4574 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4575 if (MacType == SK_MAC_XMAC) {
4576 /* Dual net mode */
4577 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4578 Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
4579 }
4580 /* Single net mode */
4581 else {
4582 Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
4583 pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
4584 }
4585 }
4586 else {
4587 /* Dual net mode */
4588 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4589 Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
4590 }
4591 /* Single net mode */
4592 else {
4593 Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
4594 pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
4595 }
4596 }
4597 SK_PNMI_STORE_U64(pBuf, Val64);
4598 *pLen = sizeof(SK_U64);
4599 break;
4600
4601 case OID_SKGE_RX_HW_ERROR_CTS:
4602 SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
4603 *pLen = sizeof(SK_U64);
4604 break;
4605
4606 case OID_SKGE_TX_HW_ERROR_CTS:
4607 SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
4608 *pLen = sizeof(SK_U64);
4609 break;
4610
4611 case OID_SKGE_IN_ERRORS_CTS:
4612 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4613 if (MacType == SK_MAC_XMAC) {
4614 /* Dual net mode */
4615 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4616 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4617 }
4618 /* Single net mode */
4619 else {
wdenk9c53f402003-10-15 23:53:47 +00004620 Val64 = Val64RxHwErrs +
wdenkeb20ad32003-09-05 23:19:14 +00004621 pAC->Pnmi.BufPort[0].RxNoBufCts +
4622 pAC->Pnmi.BufPort[1].RxNoBufCts;
4623 }
4624 }
4625 else {
4626 /* Dual net mode */
4627 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4628 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4629 }
4630 /* Single net mode */
4631 else {
wdenk9c53f402003-10-15 23:53:47 +00004632 Val64 = Val64RxHwErrs +
wdenkeb20ad32003-09-05 23:19:14 +00004633 pAC->Pnmi.Port[0].RxNoBufCts +
4634 pAC->Pnmi.Port[1].RxNoBufCts;
4635 }
4636 }
4637 SK_PNMI_STORE_U64(pBuf, Val64);
4638 *pLen = sizeof(SK_U64);
4639 break;
4640
4641 case OID_SKGE_OUT_ERROR_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 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4647 }
4648 /* Single net mode */
4649 else {
wdenk9c53f402003-10-15 23:53:47 +00004650 Val64 = Val64TxHwErrs +
wdenkeb20ad32003-09-05 23:19:14 +00004651 pAC->Pnmi.BufPort[0].TxNoBufCts +
4652 pAC->Pnmi.BufPort[1].TxNoBufCts;
4653 }
4654 }
4655 else {
4656 /* Dual net mode */
4657 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4658 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4659 }
4660 /* Single net mode */
4661 else {
wdenk9c53f402003-10-15 23:53:47 +00004662 Val64 = Val64TxHwErrs +
wdenkeb20ad32003-09-05 23:19:14 +00004663 pAC->Pnmi.Port[0].TxNoBufCts +
4664 pAC->Pnmi.Port[1].TxNoBufCts;
4665 }
4666 }
4667 SK_PNMI_STORE_U64(pBuf, Val64);
4668 *pLen = sizeof(SK_U64);
4669 break;
4670
4671 case OID_SKGE_ERR_RECOVERY_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 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
4677 }
4678 /* Single net mode */
4679 else {
4680 Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
4681 pAC->Pnmi.BufPort[1].ErrRecoveryCts;
4682 }
4683 }
4684 else {
4685 /* Dual net mode */
4686 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4687 Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
4688 }
4689 /* Single net mode */
4690 else {
4691 Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
4692 pAC->Pnmi.Port[1].ErrRecoveryCts;
4693 }
4694 }
4695 SK_PNMI_STORE_U64(pBuf, Val64);
4696 *pLen = sizeof(SK_U64);
4697 break;
4698
4699 case OID_SKGE_SYSUPTIME:
4700 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
4701 Val64 -= pAC->Pnmi.StartUpTime;
4702 SK_PNMI_STORE_U64(pBuf, Val64);
4703 *pLen = sizeof(SK_U64);
4704 break;
4705
4706 case OID_SKGE_MDB_VERSION:
4707 Val32 = SK_PNMI_MDB_VERSION;
4708 SK_PNMI_STORE_U32(pBuf, Val32);
4709 *pLen = sizeof(SK_U32);
4710 break;
4711
4712 case OID_GEN_RCV_ERROR:
4713 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4714 if (MacType == SK_MAC_XMAC) {
4715 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4716 }
4717 else {
4718 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4719 }
4720
4721 /*
4722 * by default 32bit values are evaluated
4723 */
4724 if (!Is64BitReq) {
4725 Val32 = (SK_U32)Val64;
4726 SK_PNMI_STORE_U32(pBuf, Val32);
4727 *pLen = sizeof(SK_U32);
4728 }
4729 else {
4730 SK_PNMI_STORE_U64(pBuf, Val64);
4731 *pLen = sizeof(SK_U64);
4732 }
4733 break;
4734
4735 case OID_GEN_XMIT_ERROR:
4736 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4737 if (MacType == SK_MAC_XMAC) {
4738 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4739 }
4740 else {
4741 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4742 }
4743
4744 /*
4745 * by default 32bit values are evaluated
4746 */
4747 if (!Is64BitReq) {
4748 Val32 = (SK_U32)Val64;
4749 SK_PNMI_STORE_U32(pBuf, Val32);
4750 *pLen = sizeof(SK_U32);
4751 }
4752 else {
4753 SK_PNMI_STORE_U64(pBuf, Val64);
4754 *pLen = sizeof(SK_U64);
4755 }
4756 break;
4757
4758 case OID_GEN_RCV_NO_BUFFER:
4759 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4760 if (MacType == SK_MAC_XMAC) {
4761 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4762 }
4763 else {
4764 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4765 }
4766
4767 /*
4768 * by default 32bit values are evaluated
4769 */
4770 if (!Is64BitReq) {
4771 Val32 = (SK_U32)Val64;
4772 SK_PNMI_STORE_U32(pBuf, Val32);
4773 *pLen = sizeof(SK_U32);
4774 }
4775 else {
4776 SK_PNMI_STORE_U64(pBuf, Val64);
4777 *pLen = sizeof(SK_U64);
4778 }
4779 break;
4780
4781 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
4782 Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
4783 SK_PNMI_STORE_U32(pBuf, Val32);
4784 *pLen = sizeof(SK_U32);
4785 break;
4786
4787 default:
4788 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
4789 SK_PNMI_ERR034MSG);
4790
4791 *pLen = 0;
4792 return (SK_PNMI_ERR_GENERAL);
4793 }
4794
4795 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
4796 Id == OID_SKGE_TX_HW_ERROR_CTS ||
4797 Id == OID_SKGE_IN_ERRORS_CTS ||
4798 Id == OID_SKGE_OUT_ERROR_CTS ||
4799 Id == OID_GEN_XMIT_ERROR ||
4800 Id == OID_GEN_RCV_ERROR) {
4801
4802 pAC->Pnmi.MacUpdatedFlag --;
4803 }
4804
4805 return (SK_PNMI_ERR_OK);
4806}
4807
4808/*****************************************************************************
4809 *
4810 * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
4811 *
4812 * Description:
4813 * Get/Presets/Sets the RLMT OIDs.
4814 *
4815 * Returns:
4816 * SK_PNMI_ERR_OK The request was successfully performed.
4817 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4818 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4819 * the correct data (e.g. a 32bit value is
4820 * needed, but a 16 bit value was passed).
4821 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
4822 * value range.
4823 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
4824 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4825 * exist (e.g. port instance 3 on a two port
4826 * adapter.
4827 */
4828PNMI_STATIC int Rlmt(
4829SK_AC *pAC, /* Pointer to adapter context */
4830SK_IOC IoC, /* IO context handle */
4831int Action, /* Get/PreSet/Set action */
4832SK_U32 Id, /* Object ID that is to be processed */
4833char *pBuf, /* Buffer to which to mgmt data will be retrieved */
4834unsigned int *pLen, /* On call: buffer length. On return: used buffer */
4835SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4836unsigned int TableIndex, /* Index to the Id table */
4837SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
4838{
4839 int Ret;
4840 unsigned int PhysPortIndex;
4841 unsigned int PhysPortMax;
4842 SK_EVPARA EventParam;
4843 SK_U32 Val32;
4844 SK_U64 Val64;
4845
4846
4847 /*
4848 * Check instance. Only single instance OIDs are allowed here.
4849 */
4850 if (Instance != (SK_U32)(-1) && Instance != 1) {
4851
4852 *pLen = 0;
4853 return (SK_PNMI_ERR_UNKNOWN_INST);
4854 }
4855
4856 /*
4857 * Perform the requested action
4858 */
4859 if (Action == SK_PNMI_GET) {
4860
4861 /*
4862 * Check if the buffer length is large enough.
4863 */
4864
4865 switch (Id) {
4866
4867 case OID_SKGE_RLMT_MODE:
4868 case OID_SKGE_RLMT_PORT_ACTIVE:
4869 case OID_SKGE_RLMT_PORT_PREFERRED:
4870 if (*pLen < sizeof(SK_U8)) {
4871
4872 *pLen = sizeof(SK_U8);
4873 return (SK_PNMI_ERR_TOO_SHORT);
4874 }
4875 break;
4876
4877 case OID_SKGE_RLMT_PORT_NUMBER:
4878 if (*pLen < sizeof(SK_U32)) {
4879
4880 *pLen = sizeof(SK_U32);
4881 return (SK_PNMI_ERR_TOO_SHORT);
4882 }
4883 break;
4884
4885 case OID_SKGE_RLMT_CHANGE_CTS:
4886 case OID_SKGE_RLMT_CHANGE_TIME:
4887 case OID_SKGE_RLMT_CHANGE_ESTIM:
4888 case OID_SKGE_RLMT_CHANGE_THRES:
4889 if (*pLen < sizeof(SK_U64)) {
4890
4891 *pLen = sizeof(SK_U64);
4892 return (SK_PNMI_ERR_TOO_SHORT);
4893 }
4894 break;
4895
4896 default:
4897 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
4898 SK_PNMI_ERR035MSG);
4899
4900 *pLen = 0;
4901 return (SK_PNMI_ERR_GENERAL);
4902 }
4903
4904 /*
4905 * Update RLMT statistic and increment semaphores to indicate
4906 * that an update was already done. Maybe RLMT will hold its
4907 * statistic always up to date some time. Then we can
4908 * remove this type of call.
4909 */
4910 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4911
4912 *pLen = 0;
4913 return (Ret);
4914 }
4915 pAC->Pnmi.RlmtUpdatedFlag ++;
4916
4917 /*
4918 * Retrieve Value
4919 */
4920 switch (Id) {
4921
4922 case OID_SKGE_RLMT_MODE:
4923 *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
4924 *pLen = sizeof(char);
4925 break;
4926
4927 case OID_SKGE_RLMT_PORT_NUMBER:
4928 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
4929 SK_PNMI_STORE_U32(pBuf, Val32);
4930 *pLen = sizeof(SK_U32);
4931 break;
4932
4933 case OID_SKGE_RLMT_PORT_ACTIVE:
4934 *pBuf = 0;
4935 /*
4936 * If multiple ports may become active this OID
4937 * doesn't make sense any more. A new variable in
4938 * the port structure should be created. However,
4939 * for this variable the first active port is
4940 * returned.
4941 */
4942 PhysPortMax = pAC->GIni.GIMacsFound;
4943
4944 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
4945 PhysPortIndex ++) {
4946
4947 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4948
4949 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
4950 break;
4951 }
4952 }
4953 *pLen = sizeof(char);
4954 break;
4955
4956 case OID_SKGE_RLMT_PORT_PREFERRED:
4957 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
4958 *pLen = sizeof(char);
4959 break;
4960
4961 case OID_SKGE_RLMT_CHANGE_CTS:
4962 Val64 = pAC->Pnmi.RlmtChangeCts;
4963 SK_PNMI_STORE_U64(pBuf, Val64);
4964 *pLen = sizeof(SK_U64);
4965 break;
4966
4967 case OID_SKGE_RLMT_CHANGE_TIME:
4968 Val64 = pAC->Pnmi.RlmtChangeTime;
4969 SK_PNMI_STORE_U64(pBuf, Val64);
4970 *pLen = sizeof(SK_U64);
4971 break;
4972
4973 case OID_SKGE_RLMT_CHANGE_ESTIM:
4974 Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
4975 SK_PNMI_STORE_U64(pBuf, Val64);
4976 *pLen = sizeof(SK_U64);
4977 break;
4978
4979 case OID_SKGE_RLMT_CHANGE_THRES:
4980 Val64 = pAC->Pnmi.RlmtChangeThreshold;
4981 SK_PNMI_STORE_U64(pBuf, Val64);
4982 *pLen = sizeof(SK_U64);
4983 break;
4984
4985 default:
4986 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
4987 ("Rlmt: Unknown OID should be handled before"));
4988
4989 pAC->Pnmi.RlmtUpdatedFlag --;
4990 *pLen = 0;
4991 return (SK_PNMI_ERR_GENERAL);
4992 }
4993
4994 pAC->Pnmi.RlmtUpdatedFlag --;
4995 }
4996 else {
4997 /* Perform a preset or set */
4998 switch (Id) {
4999
5000 case OID_SKGE_RLMT_MODE:
5001 /* Check if the buffer length is plausible */
5002 if (*pLen < sizeof(char)) {
5003
5004 *pLen = sizeof(char);
5005 return (SK_PNMI_ERR_TOO_SHORT);
5006 }
5007 /* Check if the value range is correct */
5008 if (*pLen != sizeof(char) ||
5009 (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
5010 *(SK_U8 *)pBuf > 15) {
5011
5012 *pLen = 0;
5013 return (SK_PNMI_ERR_BAD_VALUE);
5014 }
5015 /* The preset ends here */
5016 if (Action == SK_PNMI_PRESET) {
5017
5018 *pLen = 0;
5019 return (SK_PNMI_ERR_OK);
5020 }
5021 /* Send an event to RLMT to change the mode */
5022 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
5023 EventParam.Para32[0] |= (SK_U32)(*pBuf);
5024 EventParam.Para32[1] = 0;
5025 if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
5026 EventParam) > 0) {
5027
5028 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
5029 SK_PNMI_ERR037MSG);
5030
5031 *pLen = 0;
5032 return (SK_PNMI_ERR_GENERAL);
5033 }
5034 break;
5035
5036 case OID_SKGE_RLMT_PORT_PREFERRED:
5037 /* Check if the buffer length is plausible */
5038 if (*pLen < sizeof(char)) {
5039
5040 *pLen = sizeof(char);
5041 return (SK_PNMI_ERR_TOO_SHORT);
5042 }
5043 /* Check if the value range is correct */
5044 if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
5045 (SK_U8)pAC->GIni.GIMacsFound) {
5046
5047 *pLen = 0;
5048 return (SK_PNMI_ERR_BAD_VALUE);
5049 }
5050 /* The preset ends here */
5051 if (Action == SK_PNMI_PRESET) {
5052
5053 *pLen = 0;
5054 return (SK_PNMI_ERR_OK);
5055 }
5056
5057 /*
5058 * Send an event to RLMT change the preferred port.
5059 * A param of -1 means automatic mode. RLMT will
5060 * make the decision which is the preferred port.
5061 */
5062 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
5063 EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
5064 EventParam.Para32[1] = NetIndex;
5065 if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
5066 EventParam) > 0) {
5067
5068 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
5069 SK_PNMI_ERR038MSG);
5070
5071 *pLen = 0;
5072 return (SK_PNMI_ERR_GENERAL);
5073 }
5074 break;
5075
5076 case OID_SKGE_RLMT_CHANGE_THRES:
5077 /* Check if the buffer length is plausible */
5078 if (*pLen < sizeof(SK_U64)) {
5079
5080 *pLen = sizeof(SK_U64);
5081 return (SK_PNMI_ERR_TOO_SHORT);
5082 }
5083 /*
5084 * There are not many restrictions to the
5085 * value range.
5086 */
5087 if (*pLen != sizeof(SK_U64)) {
5088
5089 *pLen = 0;
5090 return (SK_PNMI_ERR_BAD_VALUE);
5091 }
5092 /* A preset ends here */
5093 if (Action == SK_PNMI_PRESET) {
5094
5095 *pLen = 0;
5096 return (SK_PNMI_ERR_OK);
5097 }
5098 /*
5099 * Store the new threshold, which will be taken
5100 * on the next timer event.
5101 */
5102 SK_PNMI_READ_U64(pBuf, Val64);
5103 pAC->Pnmi.RlmtChangeThreshold = Val64;
5104 break;
5105
5106 default:
5107 /* The other OIDs are not be able for set */
5108 *pLen = 0;
5109 return (SK_PNMI_ERR_READ_ONLY);
5110 }
5111 }
5112
5113 return (SK_PNMI_ERR_OK);
5114}
5115
5116/*****************************************************************************
5117 *
5118 * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
5119 *
5120 * Description:
5121 * Performs get requests on multiple instance variables.
5122 *
5123 * Returns:
5124 * SK_PNMI_ERR_OK The request was successfully performed.
5125 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
5126 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
5127 * the correct data (e.g. a 32bit value is
5128 * needed, but a 16 bit value was passed).
5129 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
5130 * exist (e.g. port instance 3 on a two port
5131 * adapter.
5132 */
5133PNMI_STATIC int RlmtStat(
5134SK_AC *pAC, /* Pointer to adapter context */
5135SK_IOC IoC, /* IO context handle */
5136int Action, /* Get/PreSet/Set action */
5137SK_U32 Id, /* Object ID that is to be processed */
5138char *pBuf, /* Buffer to which to mgmt data will be retrieved */
5139unsigned int *pLen, /* On call: buffer length. On return: used buffer */
5140SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5141unsigned int TableIndex, /* Index to the Id table */
5142SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
5143{
5144 unsigned int PhysPortMax;
5145 unsigned int PhysPortIndex;
5146 unsigned int Limit;
5147 unsigned int Offset;
5148 int Ret;
5149 SK_U32 Val32;
5150 SK_U64 Val64;
5151
5152 /*
5153 * Calculate the port indexes from the instance
5154 */
5155 PhysPortMax = pAC->GIni.GIMacsFound;
5156
5157 if ((Instance != (SK_U32)(-1))) {
5158 /* Check instance range */
5159 if ((Instance < 1) || (Instance > PhysPortMax)) {
5160
5161 *pLen = 0;
5162 return (SK_PNMI_ERR_UNKNOWN_INST);
5163 }
5164
5165 /* Single net mode */
5166 PhysPortIndex = Instance - 1;
5167
5168 /* Dual net mode */
5169 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
5170 PhysPortIndex = NetIndex;
5171 }
5172
5173 /* Both net modes */
5174 Limit = PhysPortIndex + 1;
5175 }
5176 else {
5177 /* Single net mode */
5178 PhysPortIndex = 0;
5179 Limit = PhysPortMax;
5180
5181 /* Dual net mode */
5182 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
5183 PhysPortIndex = NetIndex;
5184 Limit = PhysPortIndex + 1;
5185 }
5186 }
5187
5188 /*
5189 * Currently only get requests are allowed.
5190 */
5191 if (Action != SK_PNMI_GET) {
5192
5193 *pLen = 0;
5194 return (SK_PNMI_ERR_READ_ONLY);
5195 }
5196
5197 /*
5198 * Check if the buffer length is large enough.
5199 */
5200 switch (Id) {
5201
5202 case OID_SKGE_RLMT_PORT_INDEX:
5203 case OID_SKGE_RLMT_STATUS:
5204 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
5205
5206 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
5207 return (SK_PNMI_ERR_TOO_SHORT);
5208 }
5209 break;
5210
5211 case OID_SKGE_RLMT_TX_HELLO_CTS:
5212 case OID_SKGE_RLMT_RX_HELLO_CTS:
5213 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
5214 case OID_SKGE_RLMT_RX_SP_CTS:
5215 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
5216
5217 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
5218 return (SK_PNMI_ERR_TOO_SHORT);
5219 }
5220 break;
5221
5222 default:
5223 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
5224 SK_PNMI_ERR039MSG);
5225
5226 *pLen = 0;
5227 return (SK_PNMI_ERR_GENERAL);
5228
5229 }
5230
5231 /*
5232 * Update statistic and increment semaphores to indicate that
5233 * an update was already done.
5234 */
5235 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
5236
5237 *pLen = 0;
5238 return (Ret);
5239 }
5240 pAC->Pnmi.RlmtUpdatedFlag ++;
5241
5242 /*
5243 * Get value
5244 */
5245 Offset = 0;
5246 for (; PhysPortIndex < Limit; PhysPortIndex ++) {
5247
5248 switch (Id) {
5249
5250 case OID_SKGE_RLMT_PORT_INDEX:
5251 Val32 = PhysPortIndex;
5252 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
5253 Offset += sizeof(SK_U32);
5254 break;
5255
5256 case OID_SKGE_RLMT_STATUS:
5257 if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
5258 SK_RLMT_PS_INIT ||
5259 pAC->Rlmt.Port[PhysPortIndex].PortState ==
5260 SK_RLMT_PS_DOWN) {
5261
5262 Val32 = SK_PNMI_RLMT_STATUS_ERROR;
5263 }
5264 else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
5265
5266 Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
5267 }
5268 else {
5269 Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
5270 }
5271 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
5272 Offset += sizeof(SK_U32);
5273 break;
5274
5275 case OID_SKGE_RLMT_TX_HELLO_CTS:
5276 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
5277 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5278 Offset += sizeof(SK_U64);
5279 break;
5280
5281 case OID_SKGE_RLMT_RX_HELLO_CTS:
5282 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
5283 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5284 Offset += sizeof(SK_U64);
5285 break;
5286
5287 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
5288 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
5289 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5290 Offset += sizeof(SK_U64);
5291 break;
5292
5293 case OID_SKGE_RLMT_RX_SP_CTS:
5294 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
5295 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5296 Offset += sizeof(SK_U64);
5297 break;
5298
5299 default:
5300 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5301 ("RlmtStat: Unknown OID should be errored before"));
5302
5303 pAC->Pnmi.RlmtUpdatedFlag --;
5304 *pLen = 0;
5305 return (SK_PNMI_ERR_GENERAL);
5306 }
5307 }
5308 *pLen = Offset;
5309
5310 pAC->Pnmi.RlmtUpdatedFlag --;
5311
5312 return (SK_PNMI_ERR_OK);
5313}
5314
5315/*****************************************************************************
5316 *
5317 * MacPrivateConf - OID handler function of OIDs concerning the configuration
5318 *
5319 * Description:
5320 * Get/Presets/Sets the OIDs concerning the configuration.
5321 *
5322 * Returns:
5323 * SK_PNMI_ERR_OK The request was successfully performed.
5324 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
5325 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
5326 * the correct data (e.g. a 32bit value is
5327 * needed, but a 16 bit value was passed).
5328 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
5329 * value range.
5330 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
5331 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
5332 * exist (e.g. port instance 3 on a two port
5333 * adapter.
5334 */
5335PNMI_STATIC int MacPrivateConf(
5336SK_AC *pAC, /* Pointer to adapter context */
5337SK_IOC IoC, /* IO context handle */
5338int Action, /* Get/PreSet/Set action */
5339SK_U32 Id, /* Object ID that is to be processed */
5340char *pBuf, /* Buffer to which to mgmt data will be retrieved */
5341unsigned int *pLen, /* On call: buffer length. On return: used buffer */
5342SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5343unsigned int TableIndex, /* Index to the Id table */
5344SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
5345{
5346 unsigned int PhysPortMax;
5347 unsigned int PhysPortIndex;
5348 unsigned int LogPortMax;
5349 unsigned int LogPortIndex;
5350 unsigned int Limit;
5351 unsigned int Offset;
5352 char Val8;
5353 int Ret;
5354 SK_EVPARA EventParam;
5355 SK_U32 Val32;
5356
5357
5358 /*
5359 * Calculate instance if wished. MAC index 0 is the virtual
5360 * MAC.
5361 */
5362 PhysPortMax = pAC->GIni.GIMacsFound;
5363 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
5364
5365 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
5366 LogPortMax--;
5367 }
5368
5369 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
5370 /* Check instance range */
5371 if ((Instance < 1) || (Instance > LogPortMax)) {
5372
5373 *pLen = 0;
5374 return (SK_PNMI_ERR_UNKNOWN_INST);
5375 }
5376 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
5377 Limit = LogPortIndex + 1;
5378 }
5379
5380 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
5381
5382 LogPortIndex = 0;
5383 Limit = LogPortMax;
5384 }
5385
5386 /*
5387 * Perform action
5388 */
5389 if (Action == SK_PNMI_GET) {
5390
5391 /*
5392 * Check length
5393 */
5394 switch (Id) {
5395
5396 case OID_SKGE_PMD:
5397 case OID_SKGE_CONNECTOR:
5398 case OID_SKGE_LINK_CAP:
5399 case OID_SKGE_LINK_MODE:
5400 case OID_SKGE_LINK_MODE_STATUS:
5401 case OID_SKGE_LINK_STATUS:
5402 case OID_SKGE_FLOWCTRL_CAP:
5403 case OID_SKGE_FLOWCTRL_MODE:
5404 case OID_SKGE_FLOWCTRL_STATUS:
5405 case OID_SKGE_PHY_OPERATION_CAP:
5406 case OID_SKGE_PHY_OPERATION_MODE:
5407 case OID_SKGE_PHY_OPERATION_STATUS:
5408 case OID_SKGE_SPEED_CAP:
5409 case OID_SKGE_SPEED_MODE:
5410 case OID_SKGE_SPEED_STATUS:
5411 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
5412
5413 *pLen = (Limit - LogPortIndex) *
5414 sizeof(SK_U8);
5415 return (SK_PNMI_ERR_TOO_SHORT);
5416 }
5417 break;
5418
wdenk9c53f402003-10-15 23:53:47 +00005419 case OID_SKGE_MTU:
wdenkeb20ad32003-09-05 23:19:14 +00005420 if (*pLen < sizeof(SK_U32)) {
5421
5422 *pLen = sizeof(SK_U32);
5423 return (SK_PNMI_ERR_TOO_SHORT);
5424 }
5425 break;
5426
5427 default:
5428 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
5429 SK_PNMI_ERR041MSG);
5430 *pLen = 0;
5431 return (SK_PNMI_ERR_GENERAL);
5432 }
5433
5434 /*
5435 * Update statistic and increment semaphore to indicate
5436 * that an update was already done.
5437 */
5438 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
5439
5440 *pLen = 0;
5441 return (Ret);
5442 }
5443 pAC->Pnmi.SirqUpdatedFlag ++;
5444
5445 /*
5446 * Get value
5447 */
5448 Offset = 0;
5449 for (; LogPortIndex < Limit; LogPortIndex ++) {
5450
5451 switch (Id) {
5452
5453 case OID_SKGE_PMD:
5454 *(pBuf + Offset) = pAC->Pnmi.PMD;
5455 Offset += sizeof(char);
5456 break;
5457
5458 case OID_SKGE_CONNECTOR:
5459 *(pBuf + Offset) = pAC->Pnmi.Connector;
5460 Offset += sizeof(char);
5461 break;
5462
5463 case OID_SKGE_LINK_CAP:
5464 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5465 if (LogPortIndex == 0) {
wdenk9c53f402003-10-15 23:53:47 +00005466
wdenkeb20ad32003-09-05 23:19:14 +00005467 /* Get value for virtual port */
5468 VirtualConf(pAC, IoC, Id, pBuf +
5469 Offset);
5470 }
5471 else {
5472 /* Get value for physical ports */
5473 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5474 pAC, LogPortIndex);
5475
5476 *(pBuf + Offset) = pAC->GIni.GP[
5477 PhysPortIndex].PLinkCap;
5478 }
5479 Offset += sizeof(char);
5480 }
5481 else { /* DualNetMode */
wdenk9c53f402003-10-15 23:53:47 +00005482
wdenkeb20ad32003-09-05 23:19:14 +00005483 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkCap;
5484 Offset += sizeof(char);
5485 }
5486 break;
5487
5488 case OID_SKGE_LINK_MODE:
5489 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5490 if (LogPortIndex == 0) {
wdenk9c53f402003-10-15 23:53:47 +00005491
wdenkeb20ad32003-09-05 23:19:14 +00005492 /* Get value for virtual port */
5493 VirtualConf(pAC, IoC, Id, pBuf +
5494 Offset);
5495 }
5496 else {
5497 /* Get value for physical ports */
5498 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5499 pAC, LogPortIndex);
5500
5501 *(pBuf + Offset) = pAC->GIni.GP[
5502 PhysPortIndex].PLinkModeConf;
5503 }
5504 Offset += sizeof(char);
5505 }
wdenk9c53f402003-10-15 23:53:47 +00005506 else { /* DualNetMode */
5507
wdenkeb20ad32003-09-05 23:19:14 +00005508 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkModeConf;
5509 Offset += sizeof(char);
5510 }
5511 break;
5512
5513 case OID_SKGE_LINK_MODE_STATUS:
5514 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5515 if (LogPortIndex == 0) {
wdenk9c53f402003-10-15 23:53:47 +00005516
wdenkeb20ad32003-09-05 23:19:14 +00005517 /* Get value for virtual port */
5518 VirtualConf(pAC, IoC, Id, pBuf +
5519 Offset);
5520 }
5521 else {
5522 /* Get value for physical port */
5523 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5524 pAC, LogPortIndex);
5525
5526 *(pBuf + Offset) =
5527 CalculateLinkModeStatus(pAC,
5528 IoC, PhysPortIndex);
5529 }
5530 Offset += sizeof(char);
5531 }
5532 else { /* DualNetMode */
5533 *(pBuf + Offset) = CalculateLinkModeStatus(pAC, IoC, NetIndex);
5534 Offset += sizeof(char);
5535 }
5536 break;
5537
5538 case OID_SKGE_LINK_STATUS:
5539 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5540 if (LogPortIndex == 0) {
wdenk9c53f402003-10-15 23:53:47 +00005541
wdenkeb20ad32003-09-05 23:19:14 +00005542 /* Get value for virtual port */
5543 VirtualConf(pAC, IoC, Id, pBuf +
5544 Offset);
5545 }
5546 else {
5547 /* Get value for physical ports */
5548 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5549 pAC, LogPortIndex);
wdenk9c53f402003-10-15 23:53:47 +00005550
wdenkeb20ad32003-09-05 23:19:14 +00005551 *(pBuf + Offset) =
5552 CalculateLinkStatus(pAC,
5553 IoC, PhysPortIndex);
5554 }
5555 Offset += sizeof(char);
5556 }
5557 else { /* DualNetMode */
5558
5559 *(pBuf + Offset) = CalculateLinkStatus(pAC, IoC, NetIndex);
5560 Offset += sizeof(char);
5561 }
5562 break;
5563
5564 case OID_SKGE_FLOWCTRL_CAP:
5565 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5566 if (LogPortIndex == 0) {
wdenk9c53f402003-10-15 23:53:47 +00005567
wdenkeb20ad32003-09-05 23:19:14 +00005568 /* Get value for virtual port */
5569 VirtualConf(pAC, IoC, Id, pBuf +
5570 Offset);
5571 }
5572 else {
5573 /* Get value for physical ports */
5574 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5575 pAC, LogPortIndex);
wdenk9c53f402003-10-15 23:53:47 +00005576
wdenkeb20ad32003-09-05 23:19:14 +00005577 *(pBuf + Offset) = pAC->GIni.GP[
5578 PhysPortIndex].PFlowCtrlCap;
5579 }
5580 Offset += sizeof(char);
5581 }
5582 else { /* DualNetMode */
wdenk9c53f402003-10-15 23:53:47 +00005583
wdenkeb20ad32003-09-05 23:19:14 +00005584 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
5585 Offset += sizeof(char);
5586 }
5587 break;
5588
5589 case OID_SKGE_FLOWCTRL_MODE:
5590 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5591 if (LogPortIndex == 0) {
wdenk9c53f402003-10-15 23:53:47 +00005592
wdenkeb20ad32003-09-05 23:19:14 +00005593 /* Get value for virtual port */
5594 VirtualConf(pAC, IoC, Id, pBuf +
5595 Offset);
5596 }
5597 else {
5598 /* Get value for physical port */
5599 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5600 pAC, LogPortIndex);
wdenk9c53f402003-10-15 23:53:47 +00005601
wdenkeb20ad32003-09-05 23:19:14 +00005602 *(pBuf + Offset) = pAC->GIni.GP[
5603 PhysPortIndex].PFlowCtrlMode;
5604 }
5605 Offset += sizeof(char);
5606 }
5607 else { /* DualNetMode */
5608
5609 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
5610 Offset += sizeof(char);
5611 }
5612 break;
5613
5614 case OID_SKGE_FLOWCTRL_STATUS:
5615 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5616 if (LogPortIndex == 0) {
wdenk9c53f402003-10-15 23:53:47 +00005617
wdenkeb20ad32003-09-05 23:19:14 +00005618 /* Get value for virtual port */
5619 VirtualConf(pAC, IoC, Id, pBuf +
5620 Offset);
5621 }
5622 else {
5623 /* Get value for physical port */
5624 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5625 pAC, LogPortIndex);
wdenk9c53f402003-10-15 23:53:47 +00005626
wdenkeb20ad32003-09-05 23:19:14 +00005627 *(pBuf + Offset) = pAC->GIni.GP[
5628 PhysPortIndex].PFlowCtrlStatus;
5629 }
5630 Offset += sizeof(char);
5631 }
5632 else { /* DualNetMode */
5633
5634 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
5635 Offset += sizeof(char);
5636 }
5637 break;
5638
5639 case OID_SKGE_PHY_OPERATION_CAP:
5640 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5641 if (LogPortIndex == 0) {
wdenk9c53f402003-10-15 23:53:47 +00005642
wdenkeb20ad32003-09-05 23:19:14 +00005643 /* Get value for virtual port */
5644 VirtualConf(pAC, IoC, Id, pBuf +
5645 Offset);
5646 }
5647 else {
5648 /* Get value for physical ports */
5649 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5650 pAC, LogPortIndex);
wdenk9c53f402003-10-15 23:53:47 +00005651
wdenkeb20ad32003-09-05 23:19:14 +00005652 *(pBuf + Offset) = pAC->GIni.GP[
5653 PhysPortIndex].PMSCap;
5654 }
5655 Offset += sizeof(char);
5656 }
5657 else { /* DualNetMode */
wdenk9c53f402003-10-15 23:53:47 +00005658
wdenkeb20ad32003-09-05 23:19:14 +00005659 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSCap;
5660 Offset += sizeof(char);
5661 }
5662 break;
5663
5664 case OID_SKGE_PHY_OPERATION_MODE:
5665 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5666 if (LogPortIndex == 0) {
5667
5668 /* Get value for virtual port */
5669 VirtualConf(pAC, IoC, Id, pBuf + Offset);
5670 }
5671 else {
5672 /* Get value for physical port */
5673 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5674 pAC, LogPortIndex);
5675
5676 *(pBuf + Offset) = pAC->GIni.GP[
5677 PhysPortIndex].PMSMode;
5678 }
5679 Offset += sizeof(char);
5680 }
5681 else { /* DualNetMode */
wdenk9c53f402003-10-15 23:53:47 +00005682
wdenkeb20ad32003-09-05 23:19:14 +00005683 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSMode;
5684 Offset += sizeof(char);
5685 }
5686 break;
5687
5688 case OID_SKGE_PHY_OPERATION_STATUS:
5689 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5690 if (LogPortIndex == 0) {
5691
5692 /* Get value for virtual port */
5693 VirtualConf(pAC, IoC, Id, pBuf + Offset);
5694 }
5695 else {
5696 /* Get value for physical port */
5697 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5698 pAC, LogPortIndex);
wdenk9c53f402003-10-15 23:53:47 +00005699
wdenkeb20ad32003-09-05 23:19:14 +00005700 *(pBuf + Offset) = pAC->GIni.GP[
5701 PhysPortIndex].PMSStatus;
5702 }
5703 Offset += sizeof(char);
5704 }
5705 else {
wdenk9c53f402003-10-15 23:53:47 +00005706
wdenkeb20ad32003-09-05 23:19:14 +00005707 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSStatus;
5708 Offset += sizeof(char);
5709 }
5710 break;
5711
5712 case OID_SKGE_SPEED_CAP:
5713 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5714 if (LogPortIndex == 0) {
wdenk9c53f402003-10-15 23:53:47 +00005715
wdenkeb20ad32003-09-05 23:19:14 +00005716 /* Get value for virtual port */
5717 VirtualConf(pAC, IoC, Id, pBuf +
5718 Offset);
5719 }
5720 else {
5721 /* Get value for physical ports */
5722 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5723 pAC, LogPortIndex);
wdenk9c53f402003-10-15 23:53:47 +00005724
wdenkeb20ad32003-09-05 23:19:14 +00005725 *(pBuf + Offset) = pAC->GIni.GP[
5726 PhysPortIndex].PLinkSpeedCap;
5727 }
5728 Offset += sizeof(char);
5729 }
5730 else { /* DualNetMode */
wdenk9c53f402003-10-15 23:53:47 +00005731
wdenkeb20ad32003-09-05 23:19:14 +00005732 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
5733 Offset += sizeof(char);
5734 }
5735 break;
5736
5737 case OID_SKGE_SPEED_MODE:
5738 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5739 if (LogPortIndex == 0) {
wdenk9c53f402003-10-15 23:53:47 +00005740
wdenkeb20ad32003-09-05 23:19:14 +00005741 /* Get value for virtual port */
5742 VirtualConf(pAC, IoC, Id, pBuf + Offset);
5743 }
5744 else {
5745 /* Get value for physical port */
5746 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5747 pAC, LogPortIndex);
wdenk9c53f402003-10-15 23:53:47 +00005748
wdenkeb20ad32003-09-05 23:19:14 +00005749 *(pBuf + Offset) = pAC->GIni.GP[
5750 PhysPortIndex].PLinkSpeed;
5751 }
5752 Offset += sizeof(char);
5753 }
5754 else { /* DualNetMode */
5755
5756 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeed;
5757 Offset += sizeof(char);
5758 }
5759 break;
5760
5761 case OID_SKGE_SPEED_STATUS:
5762 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5763 if (LogPortIndex == 0) {
wdenk9c53f402003-10-15 23:53:47 +00005764
wdenkeb20ad32003-09-05 23:19:14 +00005765 /* Get value for virtual port */
5766 VirtualConf(pAC, IoC, Id, pBuf + Offset);
5767 }
5768 else {
5769 /* Get value for physical port */
5770 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5771 pAC, LogPortIndex);
wdenk9c53f402003-10-15 23:53:47 +00005772
wdenkeb20ad32003-09-05 23:19:14 +00005773 *(pBuf + Offset) = pAC->GIni.GP[
5774 PhysPortIndex].PLinkSpeedUsed;
5775 }
5776 Offset += sizeof(char);
5777 }
5778 else { /* DualNetMode */
5779
5780 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
5781 Offset += sizeof(char);
5782 }
5783 break;
wdenk9c53f402003-10-15 23:53:47 +00005784
wdenkeb20ad32003-09-05 23:19:14 +00005785 case OID_SKGE_MTU:
5786 Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
5787 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
5788 Offset += sizeof(SK_U32);
5789 break;
5790
5791 default:
5792 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5793 ("MacPrivateConf: Unknown OID should be handled before"));
5794
5795 pAC->Pnmi.SirqUpdatedFlag --;
5796 return (SK_PNMI_ERR_GENERAL);
5797 }
5798 }
5799 *pLen = Offset;
5800 pAC->Pnmi.SirqUpdatedFlag --;
5801
5802 return (SK_PNMI_ERR_OK);
5803 }
5804
5805 /*
5806 * From here SET or PRESET action. Check if the passed
5807 * buffer length is plausible.
5808 */
5809 switch (Id) {
5810
5811 case OID_SKGE_LINK_MODE:
5812 case OID_SKGE_FLOWCTRL_MODE:
5813 case OID_SKGE_PHY_OPERATION_MODE:
5814 case OID_SKGE_SPEED_MODE:
5815 if (*pLen < Limit - LogPortIndex) {
5816
5817 *pLen = Limit - LogPortIndex;
5818 return (SK_PNMI_ERR_TOO_SHORT);
5819 }
5820 if (*pLen != Limit - LogPortIndex) {
5821
5822 *pLen = 0;
5823 return (SK_PNMI_ERR_BAD_VALUE);
5824 }
5825 break;
5826
5827 case OID_SKGE_MTU:
5828 if (*pLen < sizeof(SK_U32)) {
5829
5830 *pLen = sizeof(SK_U32);
5831 return (SK_PNMI_ERR_TOO_SHORT);
5832 }
5833 if (*pLen != sizeof(SK_U32)) {
5834
5835 *pLen = 0;
5836 return (SK_PNMI_ERR_BAD_VALUE);
5837 }
5838 break;
5839
5840 default:
5841 *pLen = 0;
5842 return (SK_PNMI_ERR_READ_ONLY);
5843 }
5844
5845 /*
5846 * Perform preset or set
5847 */
5848 Offset = 0;
5849 for (; LogPortIndex < Limit; LogPortIndex ++) {
5850
5851 switch (Id) {
5852
5853 case OID_SKGE_LINK_MODE:
5854 /* Check the value range */
5855 Val8 = *(pBuf + Offset);
5856 if (Val8 == 0) {
5857
5858 Offset += sizeof(char);
5859 break;
5860 }
5861 if (Val8 < SK_LMODE_HALF ||
5862 (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
5863 (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
5864
5865 *pLen = 0;
5866 return (SK_PNMI_ERR_BAD_VALUE);
5867 }
5868
5869 /* The preset ends here */
5870 if (Action == SK_PNMI_PRESET) {
5871
5872 return (SK_PNMI_ERR_OK);
5873 }
5874
5875 if (LogPortIndex == 0) {
5876
5877 /*
5878 * The virtual port consists of all currently
5879 * active ports. Find them and send an event
5880 * with the new link mode to SIRQ.
5881 */
5882 for (PhysPortIndex = 0;
5883 PhysPortIndex < PhysPortMax;
5884 PhysPortIndex ++) {
5885
5886 if (!pAC->Pnmi.Port[PhysPortIndex].
5887 ActiveFlag) {
5888
5889 continue;
5890 }
5891
5892 EventParam.Para32[0] = PhysPortIndex;
5893 EventParam.Para32[1] = (SK_U32)Val8;
5894 if (SkGeSirqEvent(pAC, IoC,
5895 SK_HWEV_SET_LMODE,
5896 EventParam) > 0) {
5897
5898 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5899 SK_PNMI_ERR043,
5900 SK_PNMI_ERR043MSG);
5901
5902 *pLen = 0;
5903 return (SK_PNMI_ERR_GENERAL);
5904 }
5905 }
5906 }
5907 else {
5908 /*
5909 * Send an event with the new link mode to
5910 * the SIRQ module.
5911 */
5912 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5913 pAC, LogPortIndex);
5914 EventParam.Para32[1] = (SK_U32)Val8;
5915 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
5916 EventParam) > 0) {
5917
5918 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5919 SK_PNMI_ERR043,
5920 SK_PNMI_ERR043MSG);
5921
5922 *pLen = 0;
5923 return (SK_PNMI_ERR_GENERAL);
5924 }
5925 }
5926 Offset += sizeof(char);
5927 break;
5928
5929 case OID_SKGE_FLOWCTRL_MODE:
5930 /* Check the value range */
5931 Val8 = *(pBuf + Offset);
5932 if (Val8 == 0) {
5933
5934 Offset += sizeof(char);
5935 break;
5936 }
5937 if (Val8 < SK_FLOW_MODE_NONE ||
5938 (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
5939 (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
5940
5941 *pLen = 0;
5942 return (SK_PNMI_ERR_BAD_VALUE);
5943 }
5944
5945 /* The preset ends here */
5946 if (Action == SK_PNMI_PRESET) {
5947
5948 return (SK_PNMI_ERR_OK);
5949 }
5950
5951 if (LogPortIndex == 0) {
5952
5953 /*
5954 * The virtual port consists of all currently
5955 * active ports. Find them and send an event
5956 * with the new flow control mode to SIRQ.
5957 */
5958 for (PhysPortIndex = 0;
5959 PhysPortIndex < PhysPortMax;
5960 PhysPortIndex ++) {
5961
5962 if (!pAC->Pnmi.Port[PhysPortIndex].
5963 ActiveFlag) {
5964
5965 continue;
5966 }
5967
5968 EventParam.Para32[0] = PhysPortIndex;
5969 EventParam.Para32[1] = (SK_U32)Val8;
5970 if (SkGeSirqEvent(pAC, IoC,
5971 SK_HWEV_SET_FLOWMODE,
5972 EventParam) > 0) {
5973
5974 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5975 SK_PNMI_ERR044,
5976 SK_PNMI_ERR044MSG);
5977
5978 *pLen = 0;
5979 return (SK_PNMI_ERR_GENERAL);
5980 }
5981 }
5982 }
5983 else {
5984 /*
5985 * Send an event with the new flow control
5986 * mode to the SIRQ module.
5987 */
5988 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5989 pAC, LogPortIndex);
5990 EventParam.Para32[1] = (SK_U32)Val8;
5991 if (SkGeSirqEvent(pAC, IoC,
5992 SK_HWEV_SET_FLOWMODE, EventParam)
5993 > 0) {
5994
5995 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5996 SK_PNMI_ERR044,
5997 SK_PNMI_ERR044MSG);
5998
5999 *pLen = 0;
6000 return (SK_PNMI_ERR_GENERAL);
6001 }
6002 }
6003 Offset += sizeof(char);
6004 break;
6005
6006 case OID_SKGE_PHY_OPERATION_MODE :
6007 /* Check the value range */
6008 Val8 = *(pBuf + Offset);
6009 if (Val8 == 0) {
6010 /* mode of this port remains unchanged */
6011 Offset += sizeof(char);
6012 break;
6013 }
6014 if (Val8 < SK_MS_MODE_AUTO ||
6015 (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
6016 (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
6017
6018 *pLen = 0;
6019 return (SK_PNMI_ERR_BAD_VALUE);
6020 }
6021
6022 /* The preset ends here */
6023 if (Action == SK_PNMI_PRESET) {
6024
6025 return (SK_PNMI_ERR_OK);
6026 }
6027
6028 if (LogPortIndex == 0) {
6029
6030 /*
6031 * The virtual port consists of all currently
6032 * active ports. Find them and send an event
6033 * with new master/slave (role) mode to SIRQ.
6034 */
6035 for (PhysPortIndex = 0;
6036 PhysPortIndex < PhysPortMax;
6037 PhysPortIndex ++) {
6038
6039 if (!pAC->Pnmi.Port[PhysPortIndex].
6040 ActiveFlag) {
6041
6042 continue;
6043 }
6044
6045 EventParam.Para32[0] = PhysPortIndex;
6046 EventParam.Para32[1] = (SK_U32)Val8;
6047 if (SkGeSirqEvent(pAC, IoC,
6048 SK_HWEV_SET_ROLE,
6049 EventParam) > 0) {
6050
6051 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6052 SK_PNMI_ERR042,
6053 SK_PNMI_ERR042MSG);
6054
6055 *pLen = 0;
6056 return (SK_PNMI_ERR_GENERAL);
6057 }
6058 }
6059 }
6060 else {
6061 /*
6062 * Send an event with the new master/slave
6063 * (role) mode to the SIRQ module.
6064 */
6065 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
6066 pAC, LogPortIndex);
6067 EventParam.Para32[1] = (SK_U32)Val8;
6068 if (SkGeSirqEvent(pAC, IoC,
6069 SK_HWEV_SET_ROLE, EventParam) > 0) {
6070
6071 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6072 SK_PNMI_ERR042,
6073 SK_PNMI_ERR042MSG);
6074
6075 *pLen = 0;
6076 return (SK_PNMI_ERR_GENERAL);
6077 }
6078 }
6079
6080 Offset += sizeof(char);
6081 break;
6082
6083 case OID_SKGE_SPEED_MODE:
6084 /* Check the value range */
6085 Val8 = *(pBuf + Offset);
6086 if (Val8 == 0) {
6087
6088 Offset += sizeof(char);
6089 break;
6090 }
6091 if (Val8 < (SK_LSPEED_AUTO) ||
6092 (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) ||
6093 (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) {
6094
6095 *pLen = 0;
6096 return (SK_PNMI_ERR_BAD_VALUE);
6097 }
6098
6099 /* The preset ends here */
6100 if (Action == SK_PNMI_PRESET) {
6101
6102 return (SK_PNMI_ERR_OK);
6103 }
6104
6105 if (LogPortIndex == 0) {
6106
6107 /*
6108 * The virtual port consists of all currently
6109 * active ports. Find them and send an event
6110 * with the new flow control mode to SIRQ.
6111 */
6112 for (PhysPortIndex = 0;
6113 PhysPortIndex < PhysPortMax;
6114 PhysPortIndex ++) {
6115
6116 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6117
6118 continue;
6119 }
6120
6121 EventParam.Para32[0] = PhysPortIndex;
6122 EventParam.Para32[1] = (SK_U32)Val8;
6123 if (SkGeSirqEvent(pAC, IoC,
6124 SK_HWEV_SET_SPEED,
6125 EventParam) > 0) {
6126
6127 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6128 SK_PNMI_ERR045,
6129 SK_PNMI_ERR045MSG);
6130
6131 *pLen = 0;
6132 return (SK_PNMI_ERR_GENERAL);
6133 }
6134 }
6135 }
6136 else {
6137 /*
6138 * Send an event with the new flow control
6139 * mode to the SIRQ module.
6140 */
6141 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
6142 pAC, LogPortIndex);
6143 EventParam.Para32[1] = (SK_U32)Val8;
6144 if (SkGeSirqEvent(pAC, IoC,
6145 SK_HWEV_SET_SPEED,
6146 EventParam) > 0) {
6147
6148 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6149 SK_PNMI_ERR045,
6150 SK_PNMI_ERR045MSG);
6151
6152 *pLen = 0;
6153 return (SK_PNMI_ERR_GENERAL);
6154 }
6155 }
6156 Offset += sizeof(char);
6157 break;
6158
6159 case OID_SKGE_MTU :
6160 /* Check the value range */
6161 Val32 = *(SK_U32*)(pBuf + Offset);
6162 if (Val32 == 0) {
6163 /* mtu of this port remains unchanged */
6164 Offset += sizeof(SK_U32);
6165 break;
6166 }
6167 if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
6168 *pLen = 0;
6169 return (SK_PNMI_ERR_BAD_VALUE);
6170 }
6171
6172 /* The preset ends here */
6173 if (Action == SK_PNMI_PRESET) {
6174 return (SK_PNMI_ERR_OK);
6175 }
6176
6177 if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
6178 return (SK_PNMI_ERR_GENERAL);
6179 }
6180
6181 Offset += sizeof(SK_U32);
6182 break;
6183
6184 default:
wdenk9c53f402003-10-15 23:53:47 +00006185 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
6186 ("MacPrivateConf: Unknown OID should be handled before set"));
wdenkeb20ad32003-09-05 23:19:14 +00006187
6188 *pLen = 0;
6189 return (SK_PNMI_ERR_GENERAL);
6190 }
6191 }
6192
6193 return (SK_PNMI_ERR_OK);
6194}
6195
6196/*****************************************************************************
6197 *
6198 * Monitor - OID handler function for RLMT_MONITOR_XXX
6199 *
6200 * Description:
6201 * Because RLMT currently does not support the monitoring of
6202 * remote adapter cards, we return always an empty table.
6203 *
6204 * Returns:
6205 * SK_PNMI_ERR_OK The request was successfully performed.
6206 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
6207 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
6208 * the correct data (e.g. a 32bit value is
6209 * needed, but a 16 bit value was passed).
6210 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
6211 * value range.
6212 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
6213 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
6214 * exist (e.g. port instance 3 on a two port
6215 * adapter.
6216 */
6217PNMI_STATIC int Monitor(
6218SK_AC *pAC, /* Pointer to adapter context */
6219SK_IOC IoC, /* IO context handle */
6220int Action, /* Get/PreSet/Set action */
6221SK_U32 Id, /* Object ID that is to be processed */
6222char *pBuf, /* Buffer to which to mgmt data will be retrieved */
6223unsigned int *pLen, /* On call: buffer length. On return: used buffer */
6224SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
6225unsigned int TableIndex, /* Index to the Id table */
6226SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6227{
6228 unsigned int Index;
6229 unsigned int Limit;
6230 unsigned int Offset;
6231 unsigned int Entries;
6232
wdenk9c53f402003-10-15 23:53:47 +00006233
wdenkeb20ad32003-09-05 23:19:14 +00006234 /*
6235 * Calculate instance if wished.
6236 */
6237/* XXX Not yet implemented. Return always an empty table. */
6238 Entries = 0;
6239
6240 if ((Instance != (SK_U32)(-1))) {
6241
6242 if ((Instance < 1) || (Instance > Entries)) {
6243
6244 *pLen = 0;
6245 return (SK_PNMI_ERR_UNKNOWN_INST);
6246 }
6247
6248 Index = (unsigned int)Instance - 1;
6249 Limit = (unsigned int)Instance;
6250 }
6251 else {
6252 Index = 0;
6253 Limit = Entries;
6254 }
6255
6256 /*
6257 * Get/Set value
6258 */
6259 if (Action == SK_PNMI_GET) {
6260
6261 for (Offset=0; Index < Limit; Index ++) {
6262
6263 switch (Id) {
6264
6265 case OID_SKGE_RLMT_MONITOR_INDEX:
6266 case OID_SKGE_RLMT_MONITOR_ADDR:
6267 case OID_SKGE_RLMT_MONITOR_ERRS:
6268 case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
6269 case OID_SKGE_RLMT_MONITOR_ADMIN:
6270 break;
6271
6272 default:
6273 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
6274 SK_PNMI_ERR046MSG);
6275
6276 *pLen = 0;
6277 return (SK_PNMI_ERR_GENERAL);
6278 }
6279 }
6280 *pLen = Offset;
6281 }
6282 else {
6283 /* Only MONITOR_ADMIN can be set */
6284 if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
6285
6286 *pLen = 0;
6287 return (SK_PNMI_ERR_READ_ONLY);
6288 }
6289
6290 /* Check if the length is plausible */
6291 if (*pLen < (Limit - Index)) {
6292
6293 return (SK_PNMI_ERR_TOO_SHORT);
6294 }
6295 /* Okay, we have a wide value range */
6296 if (*pLen != (Limit - Index)) {
6297
6298 *pLen = 0;
6299 return (SK_PNMI_ERR_BAD_VALUE);
6300 }
6301/*
6302 for (Offset=0; Index < Limit; Index ++) {
6303 }
6304*/
6305/*
6306 * XXX Not yet implemented. Return always BAD_VALUE, because the table
6307 * is empty.
6308 */
6309 *pLen = 0;
6310 return (SK_PNMI_ERR_BAD_VALUE);
6311 }
6312
6313 return (SK_PNMI_ERR_OK);
6314}
6315
6316/*****************************************************************************
6317 *
6318 * VirtualConf - Calculates the values of configuration OIDs for virtual port
6319 *
6320 * Description:
6321 * We handle here the get of the configuration group OIDs, which are
6322 * a little bit complicated. The virtual port consists of all currently
6323 * active physical ports. If multiple ports are active and configured
6324 * differently we get in some trouble to return a single value. So we
6325 * get the value of the first active port and compare it with that of
6326 * the other active ports. If they are not the same, we return a value
6327 * that indicates that the state is indeterminated.
6328 *
6329 * Returns:
6330 * Nothing
6331 */
6332PNMI_STATIC void VirtualConf(
6333SK_AC *pAC, /* Pointer to adapter context */
6334SK_IOC IoC, /* IO context handle */
6335SK_U32 Id, /* Object ID that is to be processed */
6336char *pBuf) /* Buffer to which to mgmt data will be retrieved */
6337{
6338 unsigned int PhysPortMax;
6339 unsigned int PhysPortIndex;
6340 SK_U8 Val8;
6341 SK_BOOL PortActiveFlag;
6342
6343
6344 *pBuf = 0;
6345 PortActiveFlag = SK_FALSE;
6346 PhysPortMax = pAC->GIni.GIMacsFound;
6347
6348 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
6349 PhysPortIndex ++) {
6350
6351 /* Check if the physical port is active */
6352 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6353
6354 continue;
6355 }
6356
6357 PortActiveFlag = SK_TRUE;
6358
6359 switch (Id) {
6360
6361 case OID_SKGE_LINK_CAP:
6362
6363 /*
6364 * Different capabilities should not happen, but
6365 * in the case of the cases OR them all together.
6366 * From a curious point of view the virtual port
6367 * is capable of all found capabilities.
6368 */
6369 *pBuf |= pAC->GIni.GP[PhysPortIndex].PLinkCap;
6370 break;
6371
6372 case OID_SKGE_LINK_MODE:
6373 /* Check if it is the first active port */
6374 if (*pBuf == 0) {
6375
6376 *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
6377 continue;
6378 }
6379
6380 /*
6381 * If we find an active port with a different link
6382 * mode than the first one we return a value that
6383 * indicates that the link mode is indeterminated.
6384 */
6385 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkModeConf
6386 ) {
6387
6388 *pBuf = SK_LMODE_INDETERMINATED;
6389 }
6390 break;
6391
6392 case OID_SKGE_LINK_MODE_STATUS:
6393 /* Get the link mode of the physical port */
6394 Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
6395
6396 /* Check if it is the first active port */
6397 if (*pBuf == 0) {
6398
6399 *pBuf = Val8;
6400 continue;
6401 }
6402
6403 /*
6404 * If we find an active port with a different link
6405 * mode status than the first one we return a value
6406 * that indicates that the link mode status is
6407 * indeterminated.
6408 */
6409 if (*pBuf != Val8) {
6410
6411 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6412 }
6413 break;
6414
6415 case OID_SKGE_LINK_STATUS:
6416 /* Get the link status of the physical port */
6417 Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
6418
6419 /* Check if it is the first active port */
6420 if (*pBuf == 0) {
6421
6422 *pBuf = Val8;
6423 continue;
6424 }
6425
6426 /*
6427 * If we find an active port with a different link
6428 * status than the first one, we return a value
6429 * that indicates that the link status is
6430 * indeterminated.
6431 */
6432 if (*pBuf != Val8) {
6433
6434 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6435 }
6436 break;
6437
6438 case OID_SKGE_FLOWCTRL_CAP:
6439 /* Check if it is the first active port */
6440 if (*pBuf == 0) {
6441
6442 *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
6443 continue;
6444 }
6445
6446 /*
6447 * From a curious point of view the virtual port
6448 * is capable of all found capabilities.
6449 */
6450 *pBuf |= pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
6451 break;
6452
6453 case OID_SKGE_FLOWCTRL_MODE:
6454 /* Check if it is the first active port */
6455 if (*pBuf == 0) {
6456
6457 *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
6458 continue;
6459 }
6460
6461 /*
6462 * If we find an active port with a different flow
6463 * control mode than the first one, we return a value
6464 * that indicates that the mode is indeterminated.
6465 */
6466 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode) {
6467
6468 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6469 }
6470 break;
6471
6472 case OID_SKGE_FLOWCTRL_STATUS:
6473 /* Check if it is the first active port */
6474 if (*pBuf == 0) {
6475
6476 *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
6477 continue;
6478 }
6479
6480 /*
6481 * If we find an active port with a different flow
6482 * control status than the first one, we return a
6483 * value that indicates that the status is
6484 * indeterminated.
6485 */
6486 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus) {
6487
6488 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6489 }
6490 break;
wdenk9c53f402003-10-15 23:53:47 +00006491
wdenkeb20ad32003-09-05 23:19:14 +00006492 case OID_SKGE_PHY_OPERATION_CAP:
6493 /* Check if it is the first active port */
6494 if (*pBuf == 0) {
6495
6496 *pBuf = pAC->GIni.GP[PhysPortIndex].PMSCap;
6497 continue;
6498 }
6499
6500 /*
6501 * From a curious point of view the virtual port
6502 * is capable of all found capabilities.
6503 */
6504 *pBuf |= pAC->GIni.GP[PhysPortIndex].PMSCap;
6505 break;
6506
6507 case OID_SKGE_PHY_OPERATION_MODE:
6508 /* Check if it is the first active port */
6509 if (*pBuf == 0) {
6510
6511 *pBuf = pAC->GIni.GP[PhysPortIndex].PMSMode;
6512 continue;
6513 }
6514
6515 /*
6516 * If we find an active port with a different master/
6517 * slave mode than the first one, we return a value
6518 * that indicates that the mode is indeterminated.
6519 */
6520 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PMSMode) {
6521
6522 *pBuf = SK_MS_MODE_INDETERMINATED;
6523 }
6524 break;
6525
6526 case OID_SKGE_PHY_OPERATION_STATUS:
6527 /* Check if it is the first active port */
6528 if (*pBuf == 0) {
6529
6530 *pBuf = pAC->GIni.GP[PhysPortIndex].PMSStatus;
6531 continue;
6532 }
6533
6534 /*
6535 * If we find an active port with a different master/
6536 * slave status than the first one, we return a
6537 * value that indicates that the status is
6538 * indeterminated.
6539 */
6540 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PMSStatus) {
6541
6542 *pBuf = SK_MS_STAT_INDETERMINATED;
6543 }
6544 break;
wdenk9c53f402003-10-15 23:53:47 +00006545
wdenkeb20ad32003-09-05 23:19:14 +00006546 case OID_SKGE_SPEED_MODE:
6547 /* Check if it is the first active port */
6548 if (*pBuf == 0) {
6549
6550 *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
6551 continue;
6552 }
6553
6554 /*
6555 * If we find an active port with a different flow
6556 * control mode than the first one, we return a value
6557 * that indicates that the mode is indeterminated.
6558 */
6559 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkSpeed) {
6560
6561 *pBuf = SK_LSPEED_INDETERMINATED;
6562 }
6563 break;
wdenk9c53f402003-10-15 23:53:47 +00006564
wdenkeb20ad32003-09-05 23:19:14 +00006565 case OID_SKGE_SPEED_STATUS:
6566 /* Check if it is the first active port */
6567 if (*pBuf == 0) {
6568
6569 *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
6570 continue;
6571 }
6572
6573 /*
6574 * If we find an active port with a different flow
6575 * control status than the first one, we return a
6576 * value that indicates that the status is
6577 * indeterminated.
6578 */
6579 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed) {
6580
6581 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6582 }
6583 break;
6584 }
6585 }
6586
6587 /*
6588 * If no port is active return an indeterminated answer
6589 */
6590 if (!PortActiveFlag) {
6591
6592 switch (Id) {
6593
6594 case OID_SKGE_LINK_CAP:
6595 *pBuf = SK_LMODE_CAP_INDETERMINATED;
6596 break;
6597
6598 case OID_SKGE_LINK_MODE:
6599 *pBuf = SK_LMODE_INDETERMINATED;
6600 break;
6601
6602 case OID_SKGE_LINK_MODE_STATUS:
6603 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6604 break;
6605
6606 case OID_SKGE_LINK_STATUS:
6607 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6608 break;
6609
6610 case OID_SKGE_FLOWCTRL_CAP:
6611 case OID_SKGE_FLOWCTRL_MODE:
6612 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6613 break;
6614
6615 case OID_SKGE_FLOWCTRL_STATUS:
6616 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6617 break;
wdenk9c53f402003-10-15 23:53:47 +00006618
wdenkeb20ad32003-09-05 23:19:14 +00006619 case OID_SKGE_PHY_OPERATION_CAP:
6620 *pBuf = SK_MS_CAP_INDETERMINATED;
6621 break;
6622
6623 case OID_SKGE_PHY_OPERATION_MODE:
6624 *pBuf = SK_MS_MODE_INDETERMINATED;
6625 break;
6626
6627 case OID_SKGE_PHY_OPERATION_STATUS:
6628 *pBuf = SK_MS_STAT_INDETERMINATED;
6629 break;
6630 case OID_SKGE_SPEED_CAP:
6631 *pBuf = SK_LSPEED_CAP_INDETERMINATED;
6632 break;
6633
6634 case OID_SKGE_SPEED_MODE:
6635 *pBuf = SK_LSPEED_INDETERMINATED;
6636 break;
6637
6638 case OID_SKGE_SPEED_STATUS:
6639 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6640 break;
6641 }
6642 }
6643}
6644
6645/*****************************************************************************
6646 *
6647 * CalculateLinkStatus - Determins the link status of a physical port
6648 *
6649 * Description:
6650 * Determins the link status the following way:
6651 * LSTAT_PHY_DOWN: Link is down
6652 * LSTAT_AUTONEG: Auto-negotiation failed
6653 * LSTAT_LOG_DOWN: Link is up but RLMT did not yet put the port
6654 * logically up.
6655 * LSTAT_LOG_UP: RLMT marked the port as up
6656 *
6657 * Returns:
6658 * Link status of physical port
6659 */
6660PNMI_STATIC SK_U8 CalculateLinkStatus(
6661SK_AC *pAC, /* Pointer to adapter context */
6662SK_IOC IoC, /* IO context handle */
6663unsigned int PhysPortIndex) /* Physical port index */
6664{
6665 SK_U8 Result;
6666
6667
6668 if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
6669
6670 Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
6671 }
6672 else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
6673
6674 Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
6675 }
6676 else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
6677
6678 Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
6679 }
6680 else {
6681 Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
6682 }
6683
6684 return (Result);
6685}
6686
6687/*****************************************************************************
6688 *
6689 * CalculateLinkModeStatus - Determins the link mode status of a phys. port
6690 *
6691 * Description:
6692 * The COMMON module only tells us if the mode is half or full duplex.
6693 * But in the decade of auto sensing it is usefull for the user to
6694 * know if the mode was negotiated or forced. Therefore we have a
6695 * look to the mode, which was last used by the negotiation process.
6696 *
6697 * Returns:
6698 * The link mode status
6699 */
6700PNMI_STATIC SK_U8 CalculateLinkModeStatus(
6701SK_AC *pAC, /* Pointer to adapter context */
6702SK_IOC IoC, /* IO context handle */
6703unsigned int PhysPortIndex) /* Physical port index */
6704{
6705 SK_U8 Result;
6706
6707
6708 /* Get the current mode, which can be full or half duplex */
6709 Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
6710
6711 /* Check if no valid mode could be found (link is down) */
6712 if (Result < SK_LMODE_STAT_HALF) {
6713
6714 Result = SK_LMODE_STAT_UNKNOWN;
wdenk9c53f402003-10-15 23:53:47 +00006715 }
wdenkeb20ad32003-09-05 23:19:14 +00006716 else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
6717
6718 /*
6719 * Auto-negotiation was used to bring up the link. Change
6720 * the already found duplex status that it indicates
6721 * auto-negotiation was involved.
6722 */
6723 if (Result == SK_LMODE_STAT_HALF) {
6724
6725 Result = SK_LMODE_STAT_AUTOHALF;
6726 }
6727 else if (Result == SK_LMODE_STAT_FULL) {
6728
6729 Result = SK_LMODE_STAT_AUTOFULL;
6730 }
6731 }
6732
6733 return (Result);
6734}
6735
6736/*****************************************************************************
6737 *
6738 * GetVpdKeyArr - Obtain an array of VPD keys
6739 *
6740 * Description:
6741 * Read the VPD keys and build an array of VPD keys, which are
6742 * easy to access.
6743 *
6744 * Returns:
6745 * SK_PNMI_ERR_OK Task successfully performed.
6746 * SK_PNMI_ERR_GENERAL Something went wrong.
6747 */
6748PNMI_STATIC int GetVpdKeyArr(
6749SK_AC *pAC, /* Pointer to adapter context */
6750SK_IOC IoC, /* IO context handle */
6751char *pKeyArr, /* Ptr KeyArray */
6752unsigned int KeyArrLen, /* Length of array in bytes */
6753unsigned int *pKeyNo) /* Number of keys */
6754{
6755 unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE;
6756 char BufKeys[SK_PNMI_VPD_BUFSIZE];
6757 unsigned int StartOffset;
6758 unsigned int Offset;
6759 int Index;
6760 int Ret;
6761
6762
6763 SK_MEMSET(pKeyArr, 0, KeyArrLen);
6764
6765 /*
6766 * Get VPD key list
6767 */
6768 Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
6769 (int *)pKeyNo);
6770 if (Ret > 0) {
6771
6772 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
6773 SK_PNMI_ERR014MSG);
6774
6775 return (SK_PNMI_ERR_GENERAL);
6776 }
6777 /* If no keys are available return now */
6778 if (*pKeyNo == 0 || BufKeysLen == 0) {
6779
6780 return (SK_PNMI_ERR_OK);
6781 }
6782 /*
6783 * If the key list is too long for us trunc it and give a
6784 * errorlog notification. This case should not happen because
6785 * the maximum number of keys is limited due to RAM limitations
6786 */
6787 if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
6788
6789 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
6790 SK_PNMI_ERR015MSG);
6791
6792 *pKeyNo = SK_PNMI_VPD_ENTRIES;
6793 }
6794
6795 /*
6796 * Now build an array of fixed string length size and copy
6797 * the keys together.
6798 */
6799 for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
6800 Offset ++) {
6801
6802 if (BufKeys[Offset] != 0) {
6803
6804 continue;
6805 }
6806
6807 if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
6808
6809 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
6810 SK_PNMI_ERR016MSG);
6811 return (SK_PNMI_ERR_GENERAL);
6812 }
6813
6814 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6815 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6816
6817 Index ++;
6818 StartOffset = Offset + 1;
6819 }
6820
6821 /* Last key not zero terminated? Get it anyway */
6822 if (StartOffset < Offset) {
6823
6824 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6825 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6826 }
6827
6828 return (SK_PNMI_ERR_OK);
6829}
6830
6831/*****************************************************************************
6832 *
6833 * SirqUpdate - Let the SIRQ update its internal values
6834 *
6835 * Description:
6836 * Just to be sure that the SIRQ module holds its internal data
6837 * structures up to date, we send an update event before we make
6838 * any access.
6839 *
6840 * Returns:
6841 * SK_PNMI_ERR_OK Task successfully performed.
6842 * SK_PNMI_ERR_GENERAL Something went wrong.
6843 */
6844PNMI_STATIC int SirqUpdate(
6845SK_AC *pAC, /* Pointer to adapter context */
6846SK_IOC IoC) /* IO context handle */
6847{
6848 SK_EVPARA EventParam;
6849
6850
6851 /* Was the module already updated during the current PNMI call? */
6852 if (pAC->Pnmi.SirqUpdatedFlag > 0) {
6853
6854 return (SK_PNMI_ERR_OK);
6855 }
6856
6857 /* Send an synchronuous update event to the module */
6858 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6859 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
6860
6861 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
6862 SK_PNMI_ERR047MSG);
6863
6864 return (SK_PNMI_ERR_GENERAL);
6865 }
6866
6867 return (SK_PNMI_ERR_OK);
6868}
6869
6870/*****************************************************************************
6871 *
6872 * RlmtUpdate - Let the RLMT update its internal values
6873 *
6874 * Description:
6875 * Just to be sure that the RLMT module holds its internal data
6876 * structures up to date, we send an update event before we make
6877 * any access.
6878 *
6879 * Returns:
6880 * SK_PNMI_ERR_OK Task successfully performed.
6881 * SK_PNMI_ERR_GENERAL Something went wrong.
6882 */
6883PNMI_STATIC int RlmtUpdate(
6884SK_AC *pAC, /* Pointer to adapter context */
6885SK_IOC IoC, /* IO context handle */
6886SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6887{
6888 SK_EVPARA EventParam;
6889
6890
6891 /* Was the module already updated during the current PNMI call? */
6892 if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
6893
6894 return (SK_PNMI_ERR_OK);
6895 }
6896
6897 /* Send an synchronuous update event to the module */
6898 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6899 EventParam.Para32[0] = NetIndex;
6900 EventParam.Para32[1] = (SK_U32)-1;
6901 if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
6902
6903 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
6904 SK_PNMI_ERR048MSG);
6905
6906 return (SK_PNMI_ERR_GENERAL);
6907 }
6908
6909 return (SK_PNMI_ERR_OK);
6910}
6911
6912/*****************************************************************************
6913 *
6914 * MacUpdate - Force the XMAC to output the current statistic
6915 *
6916 * Description:
6917 * The XMAC holds its statistic internally. To obtain the current
6918 * values we send a command so that the statistic data will
wdenk9c53f402003-10-15 23:53:47 +00006919 * be written to apredefined memory area on the adapter.
wdenkeb20ad32003-09-05 23:19:14 +00006920 *
6921 * Returns:
6922 * SK_PNMI_ERR_OK Task successfully performed.
6923 * SK_PNMI_ERR_GENERAL Something went wrong.
6924 */
6925PNMI_STATIC int MacUpdate(
6926SK_AC *pAC, /* Pointer to adapter context */
6927SK_IOC IoC, /* IO context handle */
6928unsigned int FirstMac, /* Index of the first Mac to be updated */
6929unsigned int LastMac) /* Index of the last Mac to be updated */
6930{
6931 unsigned int MacIndex;
6932
6933 /*
6934 * Were the statistics already updated during the
6935 * current PNMI call?
6936 */
6937 if (pAC->Pnmi.MacUpdatedFlag > 0) {
6938
6939 return (SK_PNMI_ERR_OK);
6940 }
6941
6942 /* Send an update command to all MACs specified */
6943 for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
6944
6945 /*
wdenk9c53f402003-10-15 23:53:47 +00006946 * 2002-09-13 pweber: Freeze the current sw counters.
6947 * (That should be done as close as
6948 * possible to the update of the
wdenkeb20ad32003-09-05 23:19:14 +00006949 * hw counters)
6950 */
6951 if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
6952 pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
6953 }
wdenk9c53f402003-10-15 23:53:47 +00006954
wdenkeb20ad32003-09-05 23:19:14 +00006955 /* 2002-09-13 pweber: Update the hw counter */
6956 if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
6957
6958 return (SK_PNMI_ERR_GENERAL);
6959 }
6960 }
6961
6962 return (SK_PNMI_ERR_OK);
6963}
6964
6965/*****************************************************************************
6966 *
6967 * GetStatVal - Retrieve an XMAC statistic counter
6968 *
6969 * Description:
6970 * Retrieves the statistic counter of a virtual or physical port. The
6971 * virtual port is identified by the index 0. It consists of all
6972 * currently active ports. To obtain the counter value for this port
6973 * we must add the statistic counter of all active ports. To grant
6974 * continuous counter values for the virtual port even when port
6975 * switches occur we must additionally add a delta value, which was
6976 * calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
6977 *
6978 * Returns:
6979 * Requested statistic value
6980 */
6981PNMI_STATIC SK_U64 GetStatVal(
6982SK_AC *pAC, /* Pointer to adapter context */
6983SK_IOC IoC, /* IO context handle */
6984unsigned int LogPortIndex, /* Index of the logical Port to be processed */
6985unsigned int StatIndex, /* Index to statistic value */
6986SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6987{
6988 unsigned int PhysPortIndex;
6989 unsigned int PhysPortMax;
6990 SK_U64 Val = 0;
6991
6992
6993 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
6994
6995 PhysPortIndex = NetIndex;
6996 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6997 }
6998 else { /* Single Net mode */
6999
7000 if (LogPortIndex == 0) {
7001
7002 PhysPortMax = pAC->GIni.GIMacsFound;
7003
7004 /* Add counter of all active ports */
7005 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
7006 PhysPortIndex ++) {
7007
7008 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
7009
7010 Val += GetPhysStatVal(pAC, IoC, PhysPortIndex,
7011 StatIndex);
7012 }
7013 }
7014
7015 /* Correct value because of port switches */
7016 Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
7017 }
7018 else {
7019 /* Get counter value of physical port */
7020 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
7021 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
7022 }
7023 }
7024 return (Val);
7025}
7026
7027/*****************************************************************************
7028 *
7029 * GetPhysStatVal - Get counter value for physical port
7030 *
7031 * Description:
7032 * Builds a 64bit counter value. Except for the octet counters
7033 * the lower 32bit are counted in hardware and the upper 32bit
7034 * in software by monitoring counter overflow interrupts in the
7035 * event handler. To grant continous counter values during XMAC
7036 * resets (caused by a workaround) we must add a delta value.
7037 * The delta was calculated in the event handler when a
7038 * SK_PNMI_EVT_XMAC_RESET was received.
7039 *
7040 * Returns:
7041 * Counter value
7042 */
7043PNMI_STATIC SK_U64 GetPhysStatVal(
7044SK_AC *pAC, /* Pointer to adapter context */
7045SK_IOC IoC, /* IO context handle */
7046unsigned int PhysPortIndex, /* Index of the logical Port to be processed */
7047unsigned int StatIndex) /* Index to statistic value */
7048{
7049 SK_U64 Val = 0;
7050 SK_U32 LowVal = 0;
7051 SK_U32 HighVal = 0;
7052 SK_U16 Word;
7053 int MacType;
wdenk9c53f402003-10-15 23:53:47 +00007054
wdenkeb20ad32003-09-05 23:19:14 +00007055 SK_PNMI_PORT *pPnmiPrt;
7056 SK_GEMACFUNC *pFnMac;
wdenk9c53f402003-10-15 23:53:47 +00007057
wdenkeb20ad32003-09-05 23:19:14 +00007058 MacType = pAC->GIni.GIMacType;
wdenk9c53f402003-10-15 23:53:47 +00007059
wdenkeb20ad32003-09-05 23:19:14 +00007060 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
7061 if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
7062 pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
7063 }
7064 else {
7065 pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex];
7066 }
wdenk9c53f402003-10-15 23:53:47 +00007067
wdenkeb20ad32003-09-05 23:19:14 +00007068 pFnMac = &pAC->GIni.GIFunc;
7069
7070 switch (StatIndex) {
7071 case SK_PNMI_HTX:
7072 case SK_PNMI_HRX:
7073 /* Not supported by GMAC */
7074 if (MacType == SK_MAC_GMAC) {
wdenk9c53f402003-10-15 23:53:47 +00007075 return (Val);
wdenkeb20ad32003-09-05 23:19:14 +00007076 }
wdenk9c53f402003-10-15 23:53:47 +00007077
wdenkeb20ad32003-09-05 23:19:14 +00007078 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7079 StatAddr[StatIndex][MacType].Reg,
7080 &LowVal);
7081 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7082 break;
7083
7084 case SK_PNMI_HTX_OCTET:
7085 case SK_PNMI_HRX_OCTET:
7086 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7087 StatAddr[StatIndex][MacType].Reg,
7088 &HighVal);
7089 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7090 StatAddr[StatIndex + 1][MacType].Reg,
7091 &LowVal);
7092 break;
7093
7094 case SK_PNMI_HTX_BURST:
7095 case SK_PNMI_HTX_EXCESS_DEF:
7096 case SK_PNMI_HTX_CARRIER:
7097 /* Not supported by GMAC */
7098 if (MacType == SK_MAC_GMAC) {
7099 return (Val);
7100 }
7101
7102 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7103 StatAddr[StatIndex][MacType].Reg,
7104 &LowVal);
7105 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7106 break;
7107
7108 case SK_PNMI_HTX_MACC:
7109 /* GMAC only supports PAUSE MAC control frames */
7110 if (MacType == SK_MAC_GMAC) {
7111 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, SK_PNMI_HTX_PMACC);
7112
wdenk9c53f402003-10-15 23:53:47 +00007113 return (Val);
wdenkeb20ad32003-09-05 23:19:14 +00007114 }
7115
7116 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7117 StatAddr[StatIndex][MacType].Reg,
7118 &LowVal);
7119 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7120 break;
7121
7122 case SK_PNMI_HTX_COL:
7123 case SK_PNMI_HRX_UNDERSIZE:
7124 /* Not supported by XMAC */
7125 if (MacType == SK_MAC_XMAC) {
7126 return (Val);
7127 }
7128
7129 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7130 StatAddr[StatIndex][MacType].Reg,
7131 &LowVal);
7132 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7133 break;
7134
7135
wdenkeb20ad32003-09-05 23:19:14 +00007136 case SK_PNMI_HTX_DEFFERAL:
7137 /* Not supported by GMAC */
7138 if (MacType == SK_MAC_GMAC) {
wdenk9c53f402003-10-15 23:53:47 +00007139 return (Val);
wdenkeb20ad32003-09-05 23:19:14 +00007140 }
wdenk9c53f402003-10-15 23:53:47 +00007141
wdenkeb20ad32003-09-05 23:19:14 +00007142 /*
7143 * XMAC counts frames with deferred transmission
7144 * even in full-duplex mode.
7145 *
7146 * In full-duplex mode the counter remains constant!
7147 */
7148 if ((pAC->GIni.GP[PhysPortIndex].PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) ||
7149 (pAC->GIni.GP[PhysPortIndex].PLinkModeStatus == SK_LMODE_STAT_FULL)) {
7150
7151 LowVal = 0;
7152 HighVal = 0;
7153 }
7154 else {
7155 /* Otherwise get contents of hardware register. */
7156 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7157 StatAddr[SK_PNMI_HTX_DEFFERAL][MacType].Reg,
7158 &LowVal);
7159 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7160 }
7161 break;
7162
7163 case SK_PNMI_HRX_BADOCTET:
7164 /* Not supported by XMAC */
7165 if (MacType == SK_MAC_XMAC) {
7166 return (Val);
7167 }
7168
7169 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7170 StatAddr[StatIndex][MacType].Reg,
7171 &HighVal);
7172 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7173 StatAddr[StatIndex + 1][MacType].Reg,
wdenk9c53f402003-10-15 23:53:47 +00007174 &LowVal);
wdenkeb20ad32003-09-05 23:19:14 +00007175 break;
7176
7177 case SK_PNMI_HTX_OCTETLOW:
7178 case SK_PNMI_HRX_OCTETLOW:
7179 case SK_PNMI_HRX_BADOCTETLOW:
7180 return (Val);
7181
7182 case SK_PNMI_HRX_LONGFRAMES:
7183 /* For XMAC the SW counter is managed by PNMI */
7184 if (MacType == SK_MAC_XMAC) {
wdenk9c53f402003-10-15 23:53:47 +00007185 return (pPnmiPrt->StatRxLongFrameCts);
wdenkeb20ad32003-09-05 23:19:14 +00007186 }
wdenk9c53f402003-10-15 23:53:47 +00007187
wdenkeb20ad32003-09-05 23:19:14 +00007188 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7189 StatAddr[StatIndex][MacType].Reg,
7190 &LowVal);
7191 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7192 break;
wdenk9c53f402003-10-15 23:53:47 +00007193
wdenkeb20ad32003-09-05 23:19:14 +00007194 case SK_PNMI_HRX_TOO_LONG:
7195 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7196 StatAddr[StatIndex][MacType].Reg,
7197 &LowVal);
7198 HighVal = pPnmiPrt->CounterHigh[StatIndex];
wdenk9c53f402003-10-15 23:53:47 +00007199
wdenkeb20ad32003-09-05 23:19:14 +00007200 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7201
7202 switch (MacType) {
7203 case SK_MAC_GMAC:
7204 /* For GMAC the SW counter is additionally managed by PNMI */
7205 Val += pPnmiPrt->StatRxFrameTooLongCts;
7206 break;
7207
7208 case SK_MAC_XMAC:
7209 /*
7210 * Frames longer than IEEE 802.3 frame max size are counted
7211 * by XMAC in frame_too_long counter even reception of long
7212 * frames was enabled and the frame was correct.
7213 * So correct the value by subtracting RxLongFrame counter.
7214 */
7215 Val -= pPnmiPrt->StatRxLongFrameCts;
7216 break;
7217
7218 default:
7219 break;
7220 }
7221
7222 LowVal = (SK_U32)Val;
7223 HighVal = (SK_U32)(Val >> 32);
7224 break;
wdenk9c53f402003-10-15 23:53:47 +00007225
wdenkeb20ad32003-09-05 23:19:14 +00007226 case SK_PNMI_HRX_SHORTS:
7227 /* Not supported by GMAC */
7228 if (MacType == SK_MAC_GMAC) {
7229 /* GM_RXE_FRAG?? */
wdenk9c53f402003-10-15 23:53:47 +00007230 return (Val);
wdenkeb20ad32003-09-05 23:19:14 +00007231 }
wdenk9c53f402003-10-15 23:53:47 +00007232
wdenkeb20ad32003-09-05 23:19:14 +00007233 /*
7234 * XMAC counts short frame errors even if link down (#10620)
7235 *
7236 * If link-down the counter remains constant
7237 */
7238 if (pAC->GIni.GP[PhysPortIndex].PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
7239
7240 /* Otherwise get incremental difference */
7241 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7242 StatAddr[StatIndex][MacType].Reg,
7243 &LowVal);
7244 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7245
7246 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7247 Val -= pPnmiPrt->RxShortZeroMark;
7248
7249 LowVal = (SK_U32)Val;
7250 HighVal = (SK_U32)(Val >> 32);
7251 }
7252 break;
7253
7254 case SK_PNMI_HRX_MACC:
7255 case SK_PNMI_HRX_MACC_UNKWN:
7256 case SK_PNMI_HRX_BURST:
7257 case SK_PNMI_HRX_MISSED:
7258 case SK_PNMI_HRX_FRAMING:
7259 case SK_PNMI_HRX_CARRIER:
7260 case SK_PNMI_HRX_IRLENGTH:
7261 case SK_PNMI_HRX_SYMBOL:
7262 case SK_PNMI_HRX_CEXT:
7263 /* Not supported by GMAC */
7264 if (MacType == SK_MAC_GMAC) {
7265 /* GM_RXE_FRAG?? */
wdenk9c53f402003-10-15 23:53:47 +00007266 return (Val);
wdenkeb20ad32003-09-05 23:19:14 +00007267 }
7268
7269 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7270 StatAddr[StatIndex][MacType].Reg,
7271 &LowVal);
7272 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7273 break;
7274
7275 case SK_PNMI_HRX_PMACC_ERR:
7276 /* For GMAC the SW counter is managed by PNMI */
7277 if (MacType == SK_MAC_GMAC) {
wdenk9c53f402003-10-15 23:53:47 +00007278 return (pPnmiPrt->StatRxPMaccErr);
wdenkeb20ad32003-09-05 23:19:14 +00007279 }
wdenk9c53f402003-10-15 23:53:47 +00007280
wdenkeb20ad32003-09-05 23:19:14 +00007281 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7282 StatAddr[StatIndex][MacType].Reg,
7283 &LowVal);
7284 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7285 break;
7286
7287 /* SW counter managed by PNMI */
7288 case SK_PNMI_HTX_SYNC:
7289 LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
7290 HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
7291 break;
7292
7293 /* SW counter managed by PNMI */
7294 case SK_PNMI_HTX_SYNC_OCTET:
7295 LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
7296 HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
7297 break;
7298
7299 case SK_PNMI_HRX_FCS:
wdenk9c53f402003-10-15 23:53:47 +00007300 /*
7301 * Broadcom filters fcs errors and counts it in
wdenkeb20ad32003-09-05 23:19:14 +00007302 * Receive Error Counter register
7303 */
7304 if (pAC->GIni.GP[PhysPortIndex].PhyType == SK_PHY_BCOM) {
7305 /* do not read while not initialized (PHY_READ hangs!)*/
7306 if (pAC->GIni.GP[PhysPortIndex].PState) {
7307 PHY_READ(IoC, &pAC->GIni.GP[PhysPortIndex],
7308 PhysPortIndex, PHY_BCOM_RE_CTR,
7309 &Word);
wdenk9c53f402003-10-15 23:53:47 +00007310
wdenkeb20ad32003-09-05 23:19:14 +00007311 LowVal = Word;
7312 }
7313 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7314 }
7315 else {
7316 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7317 StatAddr[StatIndex][MacType].Reg,
7318 &LowVal);
7319 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7320 }
7321 break;
7322
7323 default:
7324 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7325 StatAddr[StatIndex][MacType].Reg,
7326 &LowVal);
7327 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7328 break;
7329 }
7330
7331 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7332
7333 /* Correct value because of possible XMAC reset. XMAC Errata #2 */
7334 Val += pPnmiPrt->CounterOffset[StatIndex];
7335
7336 return (Val);
7337}
7338
7339/*****************************************************************************
7340 *
7341 * ResetCounter - Set all counters and timestamps to zero
7342 *
7343 * Description:
7344 * Notifies other common modules which store statistic data to
7345 * reset their counters and finally reset our own counters.
7346 *
7347 * Returns:
7348 * Nothing
7349 */
7350PNMI_STATIC void ResetCounter(
7351SK_AC *pAC, /* Pointer to adapter context */
7352SK_IOC IoC, /* IO context handle */
7353SK_U32 NetIndex)
7354{
7355 unsigned int PhysPortIndex;
7356 SK_EVPARA EventParam;
7357
7358
7359 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
7360
7361 /* Notify sensor module */
7362 SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
7363
7364 /* Notify RLMT module */
7365 EventParam.Para32[0] = NetIndex;
7366 EventParam.Para32[1] = (SK_U32)-1;
7367 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
7368 EventParam.Para32[1] = 0;
7369
7370 /* Notify SIRQ module */
7371 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
7372
7373 /* Notify CSUM module */
7374#ifdef SK_USE_CSUM
7375 EventParam.Para32[0] = NetIndex;
7376 EventParam.Para32[1] = (SK_U32)-1;
7377 SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
7378 EventParam);
7379#endif
7380
7381 /* Clear XMAC statistic */
7382 for (PhysPortIndex = 0; PhysPortIndex <
7383 (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
7384
7385 (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex);
7386
7387 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
7388 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
7389 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7390 CounterOffset, 0, sizeof(pAC->Pnmi.Port[
7391 PhysPortIndex].CounterOffset));
7392 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
7393 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
7394 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7395 StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
7396 PhysPortIndex].StatSyncOctetsCts));
7397 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7398 StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
7399 PhysPortIndex].StatRxLongFrameCts));
7400 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7401 StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[
7402 PhysPortIndex].StatRxFrameTooLongCts));
7403 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7404 StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[
7405 PhysPortIndex].StatRxPMaccErr));
7406 }
7407
7408 /*
7409 * Clear local statistics
7410 */
7411 SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
7412 sizeof(pAC->Pnmi.VirtualCounterOffset));
7413 pAC->Pnmi.RlmtChangeCts = 0;
7414 pAC->Pnmi.RlmtChangeTime = 0;
7415 SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
7416 sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
7417 pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
7418 pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
7419 pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
7420 pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
7421 pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
7422 pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
7423 pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
7424 pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
7425 pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
7426 pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
7427 pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
7428 pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
7429}
7430
7431/*****************************************************************************
7432 *
7433 * GetTrapEntry - Get an entry in the trap buffer
7434 *
7435 * Description:
7436 * The trap buffer stores various events. A user application somehow
7437 * gets notified that an event occured and retrieves the trap buffer
7438 * contens (or simply polls the buffer). The buffer is organized as
7439 * a ring which stores the newest traps at the beginning. The oldest
7440 * traps are overwritten by the newest ones. Each trap entry has a
7441 * unique number, so that applications may detect new trap entries.
7442 *
7443 * Returns:
7444 * A pointer to the trap entry
7445 */
7446PNMI_STATIC char* GetTrapEntry(
7447SK_AC *pAC, /* Pointer to adapter context */
7448SK_U32 TrapId, /* SNMP ID of the trap */
7449unsigned int Size) /* Space needed for trap entry */
7450{
7451 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7452 unsigned int BufFree = pAC->Pnmi.TrapBufFree;
7453 unsigned int Beg = pAC->Pnmi.TrapQueueBeg;
7454 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7455 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7456 int Wrap;
7457 unsigned int NeededSpace;
7458 unsigned int EntrySize;
7459 SK_U32 Val32;
7460 SK_U64 Val64;
7461
7462
7463 /* Last byte of entry will get a copy of the entry length */
7464 Size ++;
7465
7466 /*
7467 * Calculate needed buffer space */
7468 if (Beg >= Size) {
7469
7470 NeededSpace = Size;
7471 Wrap = SK_FALSE;
7472 }
7473 else {
7474 NeededSpace = Beg + Size;
7475 Wrap = SK_TRUE;
7476 }
7477
7478 /*
7479 * Check if enough buffer space is provided. Otherwise
7480 * free some entries. Leave one byte space between begin
7481 * and end of buffer to make it possible to detect whether
7482 * the buffer is full or empty
7483 */
7484 while (BufFree < NeededSpace + 1) {
7485
7486 if (End == 0) {
7487
7488 End = SK_PNMI_TRAP_QUEUE_LEN;
7489 }
7490
7491 EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
7492 BufFree += EntrySize;
7493 End -= EntrySize;
7494#ifdef DEBUG
7495 SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
7496#endif
7497 if (End == BufPad) {
7498#ifdef DEBUG
7499 SK_MEMSET(pBuf, (char)(-1), End);
7500#endif
7501 BufFree += End;
7502 End = 0;
7503 BufPad = 0;
7504 }
7505 }
7506
wdenk9c53f402003-10-15 23:53:47 +00007507 /*
wdenkeb20ad32003-09-05 23:19:14 +00007508 * Insert new entry as first entry. Newest entries are
7509 * stored at the beginning of the queue.
7510 */
7511 if (Wrap) {
7512
7513 BufPad = Beg;
7514 Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
7515 }
7516 else {
7517 Beg = Beg - Size;
7518 }
7519 BufFree -= NeededSpace;
7520
7521 /* Save the current offsets */
7522 pAC->Pnmi.TrapQueueBeg = Beg;
7523 pAC->Pnmi.TrapQueueEnd = End;
7524 pAC->Pnmi.TrapBufPad = BufPad;
7525 pAC->Pnmi.TrapBufFree = BufFree;
7526
7527 /* Initialize the trap entry */
7528 *(pBuf + Beg + Size - 1) = (char)Size;
7529 *(pBuf + Beg) = (char)Size;
7530 Val32 = (pAC->Pnmi.TrapUnique) ++;
7531 SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
7532 SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
7533 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
7534 SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
7535
7536 return (pBuf + Beg);
7537}
7538
7539/*****************************************************************************
7540 *
7541 * CopyTrapQueue - Copies the trap buffer for the TRAP OID
7542 *
7543 * Description:
7544 * On a query of the TRAP OID the trap buffer contents will be
7545 * copied continuously to the request buffer, which must be large
7546 * enough. No length check is performed.
7547 *
7548 * Returns:
7549 * Nothing
7550 */
7551PNMI_STATIC void CopyTrapQueue(
7552SK_AC *pAC, /* Pointer to adapter context */
7553char *pDstBuf) /* Buffer to which the queued traps will be copied */
7554{
7555 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7556 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7557 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7558 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7559 unsigned int Len;
7560 unsigned int DstOff = 0;
7561
7562
7563 while (Trap != End) {
7564
7565 Len = (unsigned int)*(pBuf + Trap);
7566
7567 /*
7568 * Last byte containing a copy of the length will
7569 * not be copied.
7570 */
7571 *(pDstBuf + DstOff) = (char)(Len - 1);
7572 SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
7573 DstOff += Len - 1;
7574
7575 Trap += Len;
7576 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7577
7578 Trap = BufPad;
7579 }
7580 }
7581}
7582
7583/*****************************************************************************
7584 *
7585 * GetTrapQueueLen - Get the length of the trap buffer
7586 *
7587 * Description:
7588 * Evaluates the number of currently stored traps and the needed
7589 * buffer size to retrieve them.
7590 *
7591 * Returns:
7592 * Nothing
7593 */
7594PNMI_STATIC void GetTrapQueueLen(
7595SK_AC *pAC, /* Pointer to adapter context */
7596unsigned int *pLen, /* Length in Bytes of all queued traps */
7597unsigned int *pEntries) /* Returns number of trapes stored in queue */
7598{
7599 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7600 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7601 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7602 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7603 unsigned int Len;
7604 unsigned int Entries = 0;
7605 unsigned int TotalLen = 0;
7606
7607
7608 while (Trap != End) {
7609
7610 Len = (unsigned int)*(pBuf + Trap);
7611 TotalLen += Len - 1;
7612 Entries ++;
7613
7614 Trap += Len;
7615 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7616
7617 Trap = BufPad;
7618 }
7619 }
7620
7621 *pEntries = Entries;
7622 *pLen = TotalLen;
7623}
7624
7625/*****************************************************************************
7626 *
7627 * QueueSimpleTrap - Store a simple trap to the trap buffer
7628 *
7629 * Description:
7630 * A simple trap is a trap with now additional data. It consists
7631 * simply of a trap code.
7632 *
7633 * Returns:
7634 * Nothing
7635 */
7636PNMI_STATIC void QueueSimpleTrap(
7637SK_AC *pAC, /* Pointer to adapter context */
7638SK_U32 TrapId) /* Type of sensor trap */
7639{
7640 GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
7641}
7642
7643/*****************************************************************************
7644 *
7645 * QueueSensorTrap - Stores a sensor trap in the trap buffer
7646 *
7647 * Description:
7648 * Gets an entry in the trap buffer and fills it with sensor related
7649 * data.
7650 *
7651 * Returns:
7652 * Nothing
7653 */
7654PNMI_STATIC void QueueSensorTrap(
7655SK_AC *pAC, /* Pointer to adapter context */
7656SK_U32 TrapId, /* Type of sensor trap */
7657unsigned int SensorIndex) /* Index of sensor which caused the trap */
7658{
7659 char *pBuf;
7660 unsigned int Offset;
7661 unsigned int DescrLen;
7662 SK_U32 Val32;
7663
7664
7665 /* Get trap buffer entry */
7666 DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
7667 pBuf = GetTrapEntry(pAC, TrapId,
7668 SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
7669 Offset = SK_PNMI_TRAP_SIMPLE_LEN;
7670
7671 /* Store additionally sensor trap related data */
7672 Val32 = OID_SKGE_SENSOR_INDEX;
7673 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7674 *(pBuf + Offset + 4) = 4;
7675 Val32 = (SK_U32)SensorIndex;
7676 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7677 Offset += 9;
wdenk9c53f402003-10-15 23:53:47 +00007678
wdenkeb20ad32003-09-05 23:19:14 +00007679 Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
7680 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7681 *(pBuf + Offset + 4) = (char)DescrLen;
7682 SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
7683 DescrLen);
7684 Offset += DescrLen + 5;
7685
7686 Val32 = OID_SKGE_SENSOR_TYPE;
7687 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7688 *(pBuf + Offset + 4) = 1;
7689 *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
7690 Offset += 6;
7691
7692 Val32 = OID_SKGE_SENSOR_VALUE;
7693 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7694 *(pBuf + Offset + 4) = 4;
7695 Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
7696 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7697}
7698
7699/*****************************************************************************
7700 *
7701 * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
7702 *
7703 * Description:
7704 * Nothing further to explain.
7705 *
7706 * Returns:
7707 * Nothing
7708 */
7709PNMI_STATIC void QueueRlmtNewMacTrap(
7710SK_AC *pAC, /* Pointer to adapter context */
7711unsigned int ActiveMac) /* Index (0..n) of the currently active port */
7712{
7713 char *pBuf;
7714 SK_U32 Val32;
7715
7716
7717 pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
7718 SK_PNMI_TRAP_RLMT_CHANGE_LEN);
7719
7720 Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
7721 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7722 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7723 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
7724}
7725
7726/*****************************************************************************
7727 *
7728 * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
7729 *
7730 * Description:
7731 * Nothing further to explain.
7732 *
7733 * Returns:
7734 * Nothing
7735 */
7736PNMI_STATIC void QueueRlmtPortTrap(
7737SK_AC *pAC, /* Pointer to adapter context */
7738SK_U32 TrapId, /* Type of RLMT port trap */
7739unsigned int PortIndex) /* Index of the port, which changed its state */
7740{
7741 char *pBuf;
7742 SK_U32 Val32;
7743
7744
7745 pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
7746
7747 Val32 = OID_SKGE_RLMT_PORT_INDEX;
7748 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7749 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7750 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
7751}
7752
7753/*****************************************************************************
7754 *
7755 * CopyMac - Copies a MAC address
7756 *
7757 * Description:
7758 * Nothing further to explain.
7759 *
7760 * Returns:
7761 * Nothing
7762 */
7763PNMI_STATIC void CopyMac(
7764char *pDst, /* Pointer to destination buffer */
7765SK_MAC_ADDR *pMac) /* Pointer of Source */
7766{
7767 int i;
7768
7769
7770 for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
7771
7772 *(pDst + i) = pMac->a[i];
7773 }
7774}
7775
7776
7777#ifdef SK_POWER_MGMT
7778/*****************************************************************************
7779 *
7780 * PowerManagement - OID handler function of PowerManagement OIDs
7781 *
7782 * Description:
7783 * The code is simple. No description necessary.
7784 *
7785 * Returns:
7786 * SK_PNMI_ERR_OK The request was successfully performed.
7787 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7788 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7789 * the correct data (e.g. a 32bit value is
7790 * needed, but a 16 bit value was passed).
7791 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7792 * exist (e.g. port instance 3 on a two port
7793 * adapter.
7794 */
7795
7796PNMI_STATIC int PowerManagement(
7797SK_AC *pAC, /* Pointer to adapter context */
7798SK_IOC IoC, /* IO context handle */
7799int Action, /* Get/PreSet/Set action */
7800SK_U32 Id, /* Object ID that is to be processed */
7801char *pBuf, /* Buffer to which to mgmt data will be retrieved */
7802unsigned int *pLen, /* On call: buffer length. On return: used buffer */
7803SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7804unsigned int TableIndex, /* Index to the Id table */
7805SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
7806{
wdenk9c53f402003-10-15 23:53:47 +00007807
wdenkeb20ad32003-09-05 23:19:14 +00007808 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7809
7810 /*
7811 * Check instance. We only handle single instance variables
7812 */
7813 if (Instance != (SK_U32)(-1) && Instance != 1) {
7814
7815 *pLen = 0;
7816 return (SK_PNMI_ERR_UNKNOWN_INST);
7817 }
7818
7819 /*
7820 * Perform action
7821 */
7822 if (Action == SK_PNMI_GET) {
7823
7824 /*
7825 * Check length
7826 */
7827 switch (Id) {
7828
7829 case OID_PNP_CAPABILITIES:
7830 if (*pLen < sizeof(SK_PNP_CAPABILITIES)) {
7831
7832 *pLen = sizeof(SK_PNP_CAPABILITIES);
7833 return (SK_PNMI_ERR_TOO_SHORT);
7834 }
7835 break;
7836
7837 case OID_PNP_QUERY_POWER:
7838 case OID_PNP_ENABLE_WAKE_UP:
7839 if (*pLen < sizeof(SK_U32)) {
7840
7841 *pLen = sizeof(SK_U32);
7842 return (SK_PNMI_ERR_TOO_SHORT);
7843 }
7844 break;
7845
7846 case OID_PNP_SET_POWER:
7847 case OID_PNP_ADD_WAKE_UP_PATTERN:
7848 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7849 break;
wdenk9c53f402003-10-15 23:53:47 +00007850
wdenkeb20ad32003-09-05 23:19:14 +00007851 default:
7852 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040,
7853 SK_PNMI_ERR040MSG);
7854 *pLen = 0;
7855 return (SK_PNMI_ERR_GENERAL);
7856 }
7857
7858 /*
7859 * Get value
7860 */
7861 switch (Id) {
7862
7863 case OID_PNP_CAPABILITIES:
7864 RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen);
7865 break;
7866
7867 case OID_PNP_QUERY_POWER:
7868 /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
wdenk9c53f402003-10-15 23:53:47 +00007869 the miniport to indicate whether it can transition its NIC
7870 to the low-power state.
wdenkeb20ad32003-09-05 23:19:14 +00007871 A miniport driver must always return NDIS_STATUS_SUCCESS
7872 to a query of OID_PNP_QUERY_POWER. */
7873 RetCode = SK_PNMI_ERR_OK;
7874 break;
7875
7876 /* NDIS handles these OIDs as write-only.
7877 * So in case of get action the buffer with written length = 0
7878 * is returned
7879 */
7880 case OID_PNP_SET_POWER:
7881 case OID_PNP_ADD_WAKE_UP_PATTERN:
7882 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
wdenk9c53f402003-10-15 23:53:47 +00007883 *pLen = 0;
wdenkeb20ad32003-09-05 23:19:14 +00007884 RetCode = SK_PNMI_ERR_OK;
7885 break;
7886
7887 case OID_PNP_ENABLE_WAKE_UP:
7888 RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen);
7889 break;
7890
7891 default:
7892 RetCode = SK_PNMI_ERR_GENERAL;
7893 break;
7894 }
7895
wdenk9c53f402003-10-15 23:53:47 +00007896 return (RetCode);
wdenkeb20ad32003-09-05 23:19:14 +00007897 }
wdenk9c53f402003-10-15 23:53:47 +00007898
wdenkeb20ad32003-09-05 23:19:14 +00007899 /*
7900 * From here SET or PRESET action. Check if the passed
7901 * buffer length is plausible.
7902 */
7903 switch (Id) {
7904 case OID_PNP_SET_POWER:
7905 case OID_PNP_ENABLE_WAKE_UP:
7906 if (*pLen < sizeof(SK_U32)) {
7907
7908 *pLen = sizeof(SK_U32);
7909 return (SK_PNMI_ERR_TOO_SHORT);
7910 }
7911 if (*pLen != sizeof(SK_U32)) {
7912
7913 *pLen = 0;
7914 return (SK_PNMI_ERR_BAD_VALUE);
7915 }
7916 break;
7917
7918 case OID_PNP_ADD_WAKE_UP_PATTERN:
7919 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7920 if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) {
7921
7922 *pLen = 0;
wdenk9c53f402003-10-15 23:53:47 +00007923 return (SK_PNMI_ERR_BAD_VALUE);
wdenkeb20ad32003-09-05 23:19:14 +00007924 }
7925 break;
7926
7927 default:
7928 *pLen = 0;
7929 return (SK_PNMI_ERR_READ_ONLY);
7930 }
7931
7932 /*
7933 * Perform preset or set
7934 */
wdenk9c53f402003-10-15 23:53:47 +00007935
wdenkeb20ad32003-09-05 23:19:14 +00007936 /* POWER module does not support PRESET action */
7937 if (Action == SK_PNMI_PRESET) {
wdenk9c53f402003-10-15 23:53:47 +00007938 return (SK_PNMI_ERR_OK);
wdenkeb20ad32003-09-05 23:19:14 +00007939 }
7940
7941 switch (Id) {
7942 case OID_PNP_SET_POWER:
wdenk9c53f402003-10-15 23:53:47 +00007943 RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen);
wdenkeb20ad32003-09-05 23:19:14 +00007944 break;
7945
7946 case OID_PNP_ADD_WAKE_UP_PATTERN:
wdenk9c53f402003-10-15 23:53:47 +00007947 RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen);
wdenkeb20ad32003-09-05 23:19:14 +00007948 break;
wdenk9c53f402003-10-15 23:53:47 +00007949
wdenkeb20ad32003-09-05 23:19:14 +00007950 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
wdenk9c53f402003-10-15 23:53:47 +00007951 RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen);
wdenkeb20ad32003-09-05 23:19:14 +00007952 break;
wdenk9c53f402003-10-15 23:53:47 +00007953
wdenkeb20ad32003-09-05 23:19:14 +00007954 case OID_PNP_ENABLE_WAKE_UP:
7955 RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen);
7956 break;
wdenk9c53f402003-10-15 23:53:47 +00007957
wdenkeb20ad32003-09-05 23:19:14 +00007958 default:
7959 RetCode = SK_PNMI_ERR_GENERAL;
7960 }
wdenk9c53f402003-10-15 23:53:47 +00007961
wdenkeb20ad32003-09-05 23:19:14 +00007962 return (RetCode);
7963}
7964#endif /* SK_POWER_MGMT */
7965
7966
7967/*****************************************************************************
7968 *
7969 * Vct - OID handler function of OIDs
7970 *
7971 * Description:
7972 * The code is simple. No description necessary.
7973 *
7974 * Returns:
7975 * SK_PNMI_ERR_OK The request was performed successfully.
7976 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7977 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7978 * the correct data (e.g. a 32bit value is
7979 * needed, but a 16 bit value was passed).
7980 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7981 * exist (e.g. port instance 3 on a two port
7982 * adapter).
7983 * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed.
7984 *
7985 */
7986
7987PNMI_STATIC int Vct(
7988SK_AC *pAC, /* Pointer to adapter context */
7989SK_IOC IoC, /* IO context handle */
7990int Action, /* Get/PreSet/Set action */
7991SK_U32 Id, /* Object ID that is to be processed */
7992char *pBuf, /* Buffer to which the mgmt data will be copied */
7993unsigned int *pLen, /* On call: buffer length. On return: used buffer */
7994SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */
7995unsigned int TableIndex, /* Index to the Id table */
7996SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
7997{
7998 SK_GEPORT *pPrt;
7999 SK_PNMI_VCT *pVctBackupData;
8000 SK_U32 LogPortMax;
8001 SK_U32 PhysPortMax;
8002 SK_U32 PhysPortIndex;
8003 SK_U32 Limit;
8004 SK_U32 Offset;
8005 SK_BOOL Link;
8006 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
8007 int i;
8008 SK_EVPARA Para;
8009 SK_U32 CableLength;
wdenk9c53f402003-10-15 23:53:47 +00008010
wdenkeb20ad32003-09-05 23:19:14 +00008011 /*
8012 * Calculate the port indexes from the instance.
8013 */
8014 PhysPortMax = pAC->GIni.GIMacsFound;
8015 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
wdenk9c53f402003-10-15 23:53:47 +00008016
wdenkeb20ad32003-09-05 23:19:14 +00008017 /* Dual net mode? */
8018 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
8019 LogPortMax--;
8020 }
wdenk9c53f402003-10-15 23:53:47 +00008021
wdenkeb20ad32003-09-05 23:19:14 +00008022 if ((Instance != (SK_U32) (-1))) {
8023 /* Check instance range. */
8024 if ((Instance < 2) || (Instance > LogPortMax)) {
8025 *pLen = 0;
8026 return (SK_PNMI_ERR_UNKNOWN_INST);
8027 }
wdenk9c53f402003-10-15 23:53:47 +00008028
wdenkeb20ad32003-09-05 23:19:14 +00008029 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
8030 PhysPortIndex = NetIndex;
8031 }
8032 else {
8033 PhysPortIndex = Instance - 2;
8034 }
8035 Limit = PhysPortIndex + 1;
8036 }
8037 else { /*
8038 * Instance == (SK_U32) (-1), get all Instances of that OID.
8039 *
8040 * Not implemented yet. May be used in future releases.
8041 */
8042 PhysPortIndex = 0;
8043 Limit = PhysPortMax;
8044 }
wdenk9c53f402003-10-15 23:53:47 +00008045
wdenkeb20ad32003-09-05 23:19:14 +00008046 pPrt = &pAC->GIni.GP[PhysPortIndex];
8047 if (pPrt->PHWLinkUp) {
8048 Link = SK_TRUE;
8049 }
8050 else {
8051 Link = SK_FALSE;
8052 }
wdenk9c53f402003-10-15 23:53:47 +00008053
wdenkeb20ad32003-09-05 23:19:14 +00008054 /*
8055 * Check MAC type.
8056 */
8057 if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
8058 *pLen = 0;
8059 return (SK_PNMI_ERR_GENERAL);
8060 }
wdenk9c53f402003-10-15 23:53:47 +00008061
wdenkeb20ad32003-09-05 23:19:14 +00008062 /* Initialize backup data pointer. */
8063 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
wdenk9c53f402003-10-15 23:53:47 +00008064
wdenkeb20ad32003-09-05 23:19:14 +00008065 /*
8066 * Check action type.
8067 */
8068 if (Action == SK_PNMI_GET) {
8069 /*
8070 * Check length.
8071 */
8072 switch (Id) {
wdenk9c53f402003-10-15 23:53:47 +00008073
wdenkeb20ad32003-09-05 23:19:14 +00008074 case OID_SKGE_VCT_GET:
8075 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
8076 *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
8077 return (SK_PNMI_ERR_TOO_SHORT);
8078 }
8079 break;
wdenk9c53f402003-10-15 23:53:47 +00008080
wdenkeb20ad32003-09-05 23:19:14 +00008081 case OID_SKGE_VCT_STATUS:
8082 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
8083 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
8084 return (SK_PNMI_ERR_TOO_SHORT);
8085 }
8086 break;
wdenk9c53f402003-10-15 23:53:47 +00008087
wdenkeb20ad32003-09-05 23:19:14 +00008088 default:
8089 *pLen = 0;
8090 return (SK_PNMI_ERR_GENERAL);
wdenk9c53f402003-10-15 23:53:47 +00008091 }
8092
wdenkeb20ad32003-09-05 23:19:14 +00008093 /*
8094 * Get value.
8095 */
8096 Offset = 0;
8097 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8098 switch (Id) {
wdenk9c53f402003-10-15 23:53:47 +00008099
8100 case OID_SKGE_VCT_GET:
wdenkeb20ad32003-09-05 23:19:14 +00008101 if ((Link == SK_FALSE) &&
8102 (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
8103 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
8104 if (RetCode == 0) {
8105 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
8106 pAC->Pnmi.VctStatus[PhysPortIndex] |=
8107 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
wdenk9c53f402003-10-15 23:53:47 +00008108
wdenkeb20ad32003-09-05 23:19:14 +00008109 /* Copy results for later use to PNMI struct. */
8110 for (i = 0; i < 4; i++) {
8111 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
8112 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
8113 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
8114 }
8115 }
8116 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
8117 CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
8118 }
8119 else {
8120 CableLength = 0;
8121 }
8122 pVctBackupData->PMdiPairLen[i] = CableLength;
8123 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
8124 }
8125
8126 Para.Para32[0] = PhysPortIndex;
8127 Para.Para32[1] = -1;
8128 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
8129 SkEventDispatcher(pAC, IoC);
8130 }
8131 else {
8132 ; /* VCT test is running. */
8133 }
8134 }
wdenk9c53f402003-10-15 23:53:47 +00008135
wdenkeb20ad32003-09-05 23:19:14 +00008136 /* Get all results. */
8137 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
8138 Offset += sizeof(SK_U8);
8139 *(pBuf + Offset) = pPrt->PCableLen;
8140 Offset += sizeof(SK_U8);
8141 for (i = 0; i < 4; i++) {
8142 SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
8143 Offset += sizeof(SK_U32);
8144 }
8145 for (i = 0; i < 4; i++) {
8146 *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
8147 Offset += sizeof(SK_U8);
8148 }
wdenk9c53f402003-10-15 23:53:47 +00008149
wdenkeb20ad32003-09-05 23:19:14 +00008150 RetCode = SK_PNMI_ERR_OK;
8151 break;
wdenk9c53f402003-10-15 23:53:47 +00008152
wdenkeb20ad32003-09-05 23:19:14 +00008153 case OID_SKGE_VCT_STATUS:
8154 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
8155 Offset += sizeof(SK_U8);
8156 RetCode = SK_PNMI_ERR_OK;
8157 break;
wdenk9c53f402003-10-15 23:53:47 +00008158
wdenkeb20ad32003-09-05 23:19:14 +00008159 default:
8160 *pLen = 0;
8161 return (SK_PNMI_ERR_GENERAL);
8162 }
8163 } /* for */
8164 *pLen = Offset;
8165 return (RetCode);
wdenk9c53f402003-10-15 23:53:47 +00008166
wdenkeb20ad32003-09-05 23:19:14 +00008167 } /* if SK_PNMI_GET */
wdenk9c53f402003-10-15 23:53:47 +00008168
wdenkeb20ad32003-09-05 23:19:14 +00008169 /*
8170 * From here SET or PRESET action. Check if the passed
8171 * buffer length is plausible.
8172 */
wdenk9c53f402003-10-15 23:53:47 +00008173
wdenkeb20ad32003-09-05 23:19:14 +00008174 /*
8175 * Check length.
8176 */
8177 switch (Id) {
8178 case OID_SKGE_VCT_SET:
8179 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
8180 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
8181 return (SK_PNMI_ERR_TOO_SHORT);
8182 }
8183 break;
wdenk9c53f402003-10-15 23:53:47 +00008184
wdenkeb20ad32003-09-05 23:19:14 +00008185 default:
8186 *pLen = 0;
8187 return (SK_PNMI_ERR_GENERAL);
8188 }
wdenk9c53f402003-10-15 23:53:47 +00008189
wdenkeb20ad32003-09-05 23:19:14 +00008190 /*
8191 * Perform preset or set.
8192 */
wdenk9c53f402003-10-15 23:53:47 +00008193
wdenkeb20ad32003-09-05 23:19:14 +00008194 /* VCT does not support PRESET action. */
8195 if (Action == SK_PNMI_PRESET) {
8196 return (SK_PNMI_ERR_OK);
8197 }
wdenk9c53f402003-10-15 23:53:47 +00008198
wdenkeb20ad32003-09-05 23:19:14 +00008199 Offset = 0;
8200 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8201 switch (Id) {
8202 case OID_SKGE_VCT_SET: /* Start VCT test. */
8203 if (Link == SK_FALSE) {
8204 SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
wdenk9c53f402003-10-15 23:53:47 +00008205
wdenkeb20ad32003-09-05 23:19:14 +00008206 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
8207 if (RetCode == 0) { /* RetCode: 0 => Start! */
8208 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
8209 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8210 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
wdenk9c53f402003-10-15 23:53:47 +00008211
wdenkeb20ad32003-09-05 23:19:14 +00008212 /*
8213 * Start VCT timer counter.
8214 */
8215 SK_MEMSET((char *) &Para, 0, sizeof(Para));
8216 Para.Para32[0] = PhysPortIndex;
8217 Para.Para32[1] = -1;
8218 SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
8219 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
8220 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8221 RetCode = SK_PNMI_ERR_OK;
8222 }
8223 else { /* RetCode: 2 => Running! */
8224 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8225 RetCode = SK_PNMI_ERR_OK;
8226 }
8227 }
8228 else { /* RetCode: 4 => Link! */
8229 RetCode = 4;
8230 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8231 RetCode = SK_PNMI_ERR_OK;
8232 }
8233 Offset += sizeof(SK_U32);
8234 break;
wdenk9c53f402003-10-15 23:53:47 +00008235
wdenkeb20ad32003-09-05 23:19:14 +00008236 default:
8237 *pLen = 0;
8238 return (SK_PNMI_ERR_GENERAL);
8239 }
8240 } /* for */
8241 *pLen = Offset;
8242 return (RetCode);
8243
8244} /* Vct */
8245
8246
8247PNMI_STATIC void CheckVctStatus(
8248SK_AC *pAC,
8249SK_IOC IoC,
8250char *pBuf,
8251SK_U32 Offset,
8252SK_U32 PhysPortIndex)
8253{
Wolfgang Denka1be4762008-05-20 16:00:29 +02008254 SK_GEPORT *pPrt;
wdenkeb20ad32003-09-05 23:19:14 +00008255 SK_PNMI_VCT *pVctData;
8256 SK_U32 RetCode;
8257 SK_U8 LinkSpeedUsed;
wdenk9c53f402003-10-15 23:53:47 +00008258
wdenkeb20ad32003-09-05 23:19:14 +00008259 pPrt = &pAC->GIni.GP[PhysPortIndex];
wdenk9c53f402003-10-15 23:53:47 +00008260
wdenkeb20ad32003-09-05 23:19:14 +00008261 pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
8262 pVctData->VctStatus = SK_PNMI_VCT_NONE;
wdenk9c53f402003-10-15 23:53:47 +00008263
wdenkeb20ad32003-09-05 23:19:14 +00008264 if (!pPrt->PHWLinkUp) {
wdenk9c53f402003-10-15 23:53:47 +00008265
wdenkeb20ad32003-09-05 23:19:14 +00008266 /* Was a VCT test ever made before? */
8267 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8268 if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
8269 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8270 }
8271 else {
8272 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8273 }
8274 }
wdenk9c53f402003-10-15 23:53:47 +00008275
wdenkeb20ad32003-09-05 23:19:14 +00008276 /* Check VCT test status. */
8277 RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
8278 if (RetCode == 2) { /* VCT test is running. */
8279 pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
8280 }
8281 else { /* VCT data was copied to pAC here. Check PENDING state. */
8282 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
8283 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8284 }
8285 }
wdenk9c53f402003-10-15 23:53:47 +00008286
wdenkeb20ad32003-09-05 23:19:14 +00008287 if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
8288 pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
8289 }
8290 }
8291 else {
wdenk9c53f402003-10-15 23:53:47 +00008292
wdenkeb20ad32003-09-05 23:19:14 +00008293 /* Was a VCT test ever made before? */
8294 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8295 pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8296 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8297 }
wdenk9c53f402003-10-15 23:53:47 +00008298
wdenkeb20ad32003-09-05 23:19:14 +00008299 /* DSP only valid in 100/1000 modes. */
8300 LinkSpeedUsed = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
wdenk9c53f402003-10-15 23:53:47 +00008301 if (LinkSpeedUsed != SK_LSPEED_STAT_10MBPS) {
wdenkeb20ad32003-09-05 23:19:14 +00008302 pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
8303 }
8304 }
8305
8306} /* CheckVctStatus */