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