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