|
@@ -0,0 +1,8305 @@
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * Name: skgepnmi.c
|
|
|
+ * Project: GEnesis, PCI Gigabit Ethernet Adapter
|
|
|
+ * Version: $Revision: 1.102 $
|
|
|
+ * Date: $Date: 2002/12/16 14:03:24 $
|
|
|
+ * Purpose: Private Network Management Interface
|
|
|
+ *
|
|
|
+ ****************************************************************************/
|
|
|
+
|
|
|
+/******************************************************************************
|
|
|
+ *
|
|
|
+ * (C)Copyright 1998-2002 SysKonnect GmbH.
|
|
|
+ *
|
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
|
+ * (at your option) any later version.
|
|
|
+ *
|
|
|
+ * The information in this file is provided "AS IS" without warranty.
|
|
|
+ *
|
|
|
+ ******************************************************************************/
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * History:
|
|
|
+ *
|
|
|
+ * $Log: skgepnmi.c,v $
|
|
|
+ * Revision 1.102 2002/12/16 14:03:24 tschilli
|
|
|
+ * VCT code in Vct() changed.
|
|
|
+ *
|
|
|
+ * Revision 1.101 2002/12/16 09:04:10 tschilli
|
|
|
+ * Code for VCT handling added.
|
|
|
+ *
|
|
|
+ * Revision 1.100 2002/09/26 14:28:13 tschilli
|
|
|
+ * For XMAC the values in the SK_PNMI_PORT Port struct are copied to
|
|
|
+ * the new SK_PNMI_PORT BufPort struct during a MacUpdate() call.
|
|
|
+ * These values are used when GetPhysStatVal() is called. With this
|
|
|
+ * mechanism you get the best results when software corrections for
|
|
|
+ * counters are needed. Example: RX_LONGFRAMES.
|
|
|
+ *
|
|
|
+ * Revision 1.99 2002/09/17 12:31:19 tschilli
|
|
|
+ * OID_SKGE_TX_HW_ERROR_CTS, OID_SKGE_OUT_ERROR_CTS, OID_GEN_XMIT_ERROR:
|
|
|
+ * Double count of SK_PNMI_HTX_EXCESS_COL in function General() removed.
|
|
|
+ * OID_PNP_CAPABILITIES: sizeof(SK_PM_WAKE_UP_CAPABILITIES) changed to
|
|
|
+ * sizeof(SK_PNP_CAPABILITIES) in function PowerManagement().
|
|
|
+ *
|
|
|
+ * Revision 1.98 2002/09/10 09:00:03 rwahl
|
|
|
+ * Adapted boolean definitions according sktypes.
|
|
|
+ *
|
|
|
+ * Revision 1.97 2002/09/05 15:07:03 rwahl
|
|
|
+ * Editorial changes.
|
|
|
+ *
|
|
|
+ * Revision 1.96 2002/09/05 11:04:14 rwahl
|
|
|
+ * - Rx/Tx packets statistics of virtual port were zero on link down (#10750)
|
|
|
+ * - For GMAC the overflow IRQ for Rx longframe counter was not counted.
|
|
|
+ * - Incorrect calculation for oids OID_SKGE_RX_HW_ERROR_CTS,
|
|
|
+ * OID_SKGE_IN_ERRORS_CTS, OID_GEN_RCV_ERROR.
|
|
|
+ * - Moved correction for OID_SKGE_STAT_RX_TOO_LONG to GetPhysStatVal().
|
|
|
+ * - Editorial changes.
|
|
|
+ *
|
|
|
+ * Revision 1.95 2002/09/04 08:53:37 rwahl
|
|
|
+ * - Incorrect statistics for Rx_too_long counter with jumbo frame (#10751)
|
|
|
+ * - StatRxFrameTooLong & StatRxPMaccErr counters were not reset.
|
|
|
+ * - Fixed compiler warning for debug msg arg types.
|
|
|
+ *
|
|
|
+ * Revision 1.94 2002/08/09 15:42:14 rwahl
|
|
|
+ * - Fixed StatAddr table for GMAC.
|
|
|
+ * - VirtualConf(): returned indeterminated status for speed oids if no
|
|
|
+ * active port.
|
|
|
+ *
|
|
|
+ * Revision 1.93 2002/08/09 11:04:59 rwahl
|
|
|
+ * Added handler for link speed caps.
|
|
|
+ *
|
|
|
+ * Revision 1.92 2002/08/09 09:43:03 rwahl
|
|
|
+ * - Added handler for NDIS OID_PNP_xxx ids.
|
|
|
+ *
|
|
|
+ * Revision 1.91 2002/07/17 19:53:03 rwahl
|
|
|
+ * - Added StatOvrflwBit table for XMAC & GMAC.
|
|
|
+ * - Extended StatAddr table for GMAC. Added check of number of counters
|
|
|
+ * in enumeration and size of StatAddr table on init level.
|
|
|
+ * - Added use of GIFunc table.
|
|
|
+ * - ChipSet is not static anymore,
|
|
|
+ * - Extended SIRQ event handler for both mac types.
|
|
|
+ * - Fixed rx short counter bug (#10620)
|
|
|
+ * - Added handler for oids SKGE_SPEED_MODE & SKGE_SPEED_STATUS.
|
|
|
+ * - Extendet GetPhysStatVal() for GMAC.
|
|
|
+ * - Editorial changes.
|
|
|
+ *
|
|
|
+ * Revision 1.90 2002/05/22 08:56:25 rwahl
|
|
|
+ * - Moved OID table to separate source file.
|
|
|
+ * - Fix: TX_DEFFERAL counter incremented in full-duplex mode.
|
|
|
+ * - Use string definitions for error msgs.
|
|
|
+ *
|
|
|
+ * Revision 1.89 2001/09/18 10:01:30 mkunz
|
|
|
+ * some OID's fixed for dualnetmode
|
|
|
+ *
|
|
|
+ * Revision 1.88 2001/08/02 07:58:08 rwahl
|
|
|
+ * - Fixed NetIndex to csum module at ResetCounter().
|
|
|
+ *
|
|
|
+ * Revision 1.87 2001/04/06 13:35:09 mkunz
|
|
|
+ * -Bugs fixed in handling of OID_SKGE_MTU and the VPD OID's
|
|
|
+ *
|
|
|
+ * Revision 1.86 2001/03/09 09:18:03 mkunz
|
|
|
+ * Changes in SK_DBG_MSG
|
|
|
+ *
|
|
|
+ * Revision 1.85 2001/03/08 09:37:31 mkunz
|
|
|
+ * Bugfix in ResetCounter for Pnmi.Port structure
|
|
|
+ *
|
|
|
+ * Revision 1.84 2001/03/06 09:04:55 mkunz
|
|
|
+ * Made some changes in instance calculation
|
|
|
+ *
|
|
|
+ * Revision 1.83 2001/02/15 09:15:32 mkunz
|
|
|
+ * Necessary changes for dual net mode added
|
|
|
+ *
|
|
|
+ * Revision 1.82 2001/02/07 08:24:19 mkunz
|
|
|
+ * -Made changes in handling of OID_SKGE_MTU
|
|
|
+ *
|
|
|
+ * Revision 1.81 2001/02/06 09:58:00 mkunz
|
|
|
+ * -Vpd bug fixed
|
|
|
+ * -OID_SKGE_MTU added
|
|
|
+ * -pnmi support for dual net mode. Interface function and macros extended
|
|
|
+ *
|
|
|
+ * Revision 1.80 2001/01/22 13:41:35 rassmann
|
|
|
+ * Supporting two nets on dual-port adapters.
|
|
|
+ *
|
|
|
+ * Revision 1.79 2000/12/05 14:57:40 cgoos
|
|
|
+ * SetStruct failed before first Link Up (link mode of virtual
|
|
|
+ * port "INDETERMINATED").
|
|
|
+ *
|
|
|
+ * Revision 1.78 2000/09/12 10:44:58 cgoos
|
|
|
+ * Fixed SK_PNMI_STORE_U32 calls with typecasted argument.
|
|
|
+ *
|
|
|
+ * Revision 1.77 2000/09/07 08:10:19 rwahl
|
|
|
+ * - Modified algorithm for 64bit NDIS statistic counters;
|
|
|
+ * returns 64bit or 32bit value depending on passed buffer
|
|
|
+ * size. Indicate capability for 64bit NDIS counter, if passed
|
|
|
+ * buffer size is zero. OID_GEN_XMIT_ERROR, OID_GEN_RCV_ERROR,
|
|
|
+ * and OID_GEN_RCV_NO_BUFFER handled as 64bit counter, too.
|
|
|
+ * - corrected OID_SKGE_RLMT_PORT_PREFERRED.
|
|
|
+ *
|
|
|
+ * Revision 1.76 2000/08/03 15:23:39 rwahl
|
|
|
+ * - Correction for FrameTooLong counter has to be moved to OID handling
|
|
|
+ * routines (instead of statistic counter routine).
|
|
|
+ * - Fix in XMAC Reset Event handling: Only offset counter for hardware
|
|
|
+ * statistic registers are updated.
|
|
|
+ *
|
|
|
+ * Revision 1.75 2000/08/01 16:46:05 rwahl
|
|
|
+ * - Added StatRxLongFrames counter and correction of FrameTooLong counter.
|
|
|
+ * - Added directive to control width (default = 32bit) of NDIS statistic
|
|
|
+ * counters (SK_NDIS_64BIT_CTR).
|
|
|
+ *
|
|
|
+ * Revision 1.74 2000/07/04 11:41:53 rwahl
|
|
|
+ * - Added volition connector type.
|
|
|
+ *
|
|
|
+ * Revision 1.73 2000/03/15 16:33:10 rwahl
|
|
|
+ * Fixed bug 10510; wrong reset of virtual port statistic counters.
|
|
|
+ *
|
|
|
+ * Revision 1.72 1999/12/06 16:15:53 rwahl
|
|
|
+ * Fixed problem of instance range for current and factory MAC address.
|
|
|
+ *
|
|
|
+ * Revision 1.71 1999/12/06 10:14:20 rwahl
|
|
|
+ * Fixed bug 10476; set operation for PHY_OPERATION_MODE.
|
|
|
+ *
|
|
|
+ * Revision 1.70 1999/11/22 13:33:34 cgoos
|
|
|
+ * Changed license header to GPL.
|
|
|
+ *
|
|
|
+ * Revision 1.69 1999/10/18 11:42:15 rwahl
|
|
|
+ * Added typecasts for checking event dependent param (debug only).
|
|
|
+ *
|
|
|
+ * Revision 1.68 1999/10/06 09:35:59 cgoos
|
|
|
+ * Added state check to PHY_READ call (hanged if called during startup).
|
|
|
+ *
|
|
|
+ * Revision 1.67 1999/09/22 09:53:20 rwahl
|
|
|
+ * - Read Broadcom register for updating fcs error counter (1000Base-T).
|
|
|
+ *
|
|
|
+ * Revision 1.66 1999/08/26 13:47:56 rwahl
|
|
|
+ * Added SK_DRIVER_SENDEVENT when queueing RLMT_CHANGE_THRES trap.
|
|
|
+ *
|
|
|
+ * Revision 1.65 1999/07/26 07:49:35 cgoos
|
|
|
+ * Added two typecasts to avoid compiler warnings.
|
|
|
+ *
|
|
|
+ * Revision 1.64 1999/05/20 09:24:12 cgoos
|
|
|
+ * Changes for 1000Base-T (sensors, Master/Slave).
|
|
|
+ *
|
|
|
+ * Revision 1.63 1999/04/13 15:11:58 mhaveman
|
|
|
+ * Moved include of rlmt.h to header skgepnmi.h because some macros
|
|
|
+ * are needed there.
|
|
|
+ *
|
|
|
+ * Revision 1.62 1999/04/13 15:08:07 mhaveman
|
|
|
+ * Replaced again SK_RLMT_CHECK_LINK with SK_PNMI_RLMT_MODE_CHK_LINK
|
|
|
+ * to grant unified interface by only using the PNMI header file.
|
|
|
+ * SK_PNMI_RLMT_MODE_CHK_LINK is defined the same as SK_RLMT_CHECK_LINK.
|
|
|
+ *
|
|
|
+ * Revision 1.61 1999/04/13 15:02:48 mhaveman
|
|
|
+ * Changes caused by review:
|
|
|
+ * -Changed some comments
|
|
|
+ * -Removed redundant check for OID_SKGE_PHYS_FAC_ADDR
|
|
|
+ * -Optimized PRESET check.
|
|
|
+ * -Meaning of error SK_ADDR_DUPLICATE_ADDRESS changed. Set of same
|
|
|
+ * address will now not cause this error. Removed corresponding check.
|
|
|
+ *
|
|
|
+ * Revision 1.60 1999/03/23 10:41:23 mhaveman
|
|
|
+ * Added comments.
|
|
|
+ *
|
|
|
+ * Revision 1.59 1999/02/19 08:01:28 mhaveman
|
|
|
+ * Fixed bug 10372 that after counter reset all ports were displayed
|
|
|
+ * as inactive.
|
|
|
+ *
|
|
|
+ * Revision 1.58 1999/02/16 18:04:47 mhaveman
|
|
|
+ * Fixed problem of twisted OIDs SENSOR_WAR_TIME and SENSOR_ERR_TIME.
|
|
|
+ *
|
|
|
+ * Revision 1.56 1999/01/27 12:29:11 mhaveman
|
|
|
+ * SkTimerStart was called with time value in milli seconds but needs
|
|
|
+ * micro seconds.
|
|
|
+ *
|
|
|
+ * Revision 1.55 1999/01/25 15:00:38 mhaveman
|
|
|
+ * Added support to allow multiple ports to be active. If this feature in
|
|
|
+ * future will be used, the Management Data Base variables PORT_ACTIVE
|
|
|
+ * and PORT_PREFERED should be moved to the port specific part of RLMT.
|
|
|
+ * Currently they return the values of the first active physical port
|
|
|
+ * found. A set to the virtual port will actually change all active
|
|
|
+ * physical ports. A get returns the melted values of all active physical
|
|
|
+ * ports. If the port values differ a return value INDETERMINATED will
|
|
|
+ * be returned. This effects especially the CONF group.
|
|
|
+ *
|
|
|
+ * Revision 1.54 1999/01/19 10:10:22 mhaveman
|
|
|
+ * -Fixed bug 10354: Counter values of virtual port were wrong after port
|
|
|
+ * switches
|
|
|
+ * -Added check if a switch to the same port is notified.
|
|
|
+ *
|
|
|
+ * Revision 1.53 1999/01/07 09:25:21 mhaveman
|
|
|
+ * Forgot to initialize a variable.
|
|
|
+ *
|
|
|
+ * Revision 1.52 1999/01/05 10:34:33 mhaveman
|
|
|
+ * Fixed little error in RlmtChangeEstimate calculation.
|
|
|
+ *
|
|
|
+ * Revision 1.51 1999/01/05 09:59:07 mhaveman
|
|
|
+ * -Moved timer start to init level 2
|
|
|
+ * -Redesigned port switch average calculation to avoid 64bit
|
|
|
+ * arithmetic.
|
|
|
+ *
|
|
|
+ * Revision 1.50 1998/12/10 15:13:59 mhaveman
|
|
|
+ * -Fixed: PHYS_CUR_ADDR returned wrong addresses
|
|
|
+ * -Fixed: RLMT_PORT_PREFERED and RLMT_CHANGE_THRES preset returned
|
|
|
+ * always BAD_VALUE.
|
|
|
+ * -Fixed: TRAP buffer seemed to sometimes suddenly empty
|
|
|
+ *
|
|
|
+ * Revision 1.49 1998/12/09 16:17:07 mhaveman
|
|
|
+ * Fixed: Couldnot delete VPD keys on UNIX.
|
|
|
+ *
|
|
|
+ * Revision 1.48 1998/12/09 14:11:10 mhaveman
|
|
|
+ * -Add: Debugmessage for XMAC_RESET supressed to minimize output.
|
|
|
+ * -Fixed: RlmtChangeThreshold will now be initialized.
|
|
|
+ * -Fixed: VPD_ENTRIES_LIST extended value with unnecessary space char.
|
|
|
+ * -Fixed: On VPD key creation an invalid key name could be created
|
|
|
+ * (e.g. A5)
|
|
|
+ * -Some minor changes in comments and code.
|
|
|
+ *
|
|
|
+ * Revision 1.47 1998/12/08 16:00:31 mhaveman
|
|
|
+ * -Fixed: For RLMT_PORT_ACTIVE will now be returned a 0 if no port
|
|
|
+ * is active.
|
|
|
+ * -Fixed: For the RLMT statistics group only the last value was
|
|
|
+ * returned and the rest of the buffer was filled with 0xff
|
|
|
+ * -Fixed: Mysteriously the preset on RLMT_MODE still returned
|
|
|
+ * BAD_VALUE.
|
|
|
+ * Revision 1.46 1998/12/08 10:04:56 mhaveman
|
|
|
+ * -Fixed: Preset on RLMT_MODE returned always BAD_VALUE error.
|
|
|
+ * -Fixed: Alignment error in GetStruct
|
|
|
+ * -Fixed: If for Get/Preset/SetStruct the buffer size is equal or
|
|
|
+ * larger than SK_PNMI_MIN_STRUCT_SIZE the return value is stored
|
|
|
+ * to the buffer. In this case the caller should always return
|
|
|
+ * ok to its upper routines. Only if the buffer size is less
|
|
|
+ * than SK_PNMI_MIN_STRUCT_SIZE and the return value is unequal
|
|
|
+ * to 0, an error should be returned by the caller.
|
|
|
+ * -Fixed: Wrong number of instances with RLMT statistic.
|
|
|
+ * -Fixed: Return now SK_LMODE_STAT_UNKNOWN if the LinkModeStatus is 0.
|
|
|
+ *
|
|
|
+ * Revision 1.45 1998/12/03 17:17:24 mhaveman
|
|
|
+ * -Removed for VPD create action the buffer size limitation to 4 bytes.
|
|
|
+ * -Pass now physical/active physical port to ADDR for CUR_ADDR set
|
|
|
+ *
|
|
|
+ * Revision 1.44 1998/12/03 15:14:35 mhaveman
|
|
|
+ * Another change to Vpd instance evaluation.
|
|
|
+ *
|
|
|
+ * Revision 1.43 1998/12/03 14:18:10 mhaveman
|
|
|
+ * -Fixed problem in PnmiSetStruct. It was impossible to set any value.
|
|
|
+ * -Removed VPD key evaluation for VPD_FREE_BYTES and VPD_ACTION.
|
|
|
+ *
|
|
|
+ * Revision 1.42 1998/12/03 11:31:47 mhaveman
|
|
|
+ * Inserted cast to satisfy lint.
|
|
|
+ *
|
|
|
+ * Revision 1.41 1998/12/03 11:28:16 mhaveman
|
|
|
+ * Removed SK_PNMI_CHECKPTR
|
|
|
+ *
|
|
|
+ * Revision 1.40 1998/12/03 11:19:07 mhaveman
|
|
|
+ * Fixed problems
|
|
|
+ * -A set to virtual port will now be ignored. A set with broadcast
|
|
|
+ * address to any port will be ignored.
|
|
|
+ * -GetStruct function made VPD instance calculation wrong.
|
|
|
+ * -Prefered port returned -1 instead of 0.
|
|
|
+ *
|
|
|
+ * Revision 1.39 1998/11/26 15:30:29 mhaveman
|
|
|
+ * Added sense mode to link mode.
|
|
|
+ *
|
|
|
+ * Revision 1.38 1998/11/23 15:34:00 mhaveman
|
|
|
+ * -Fixed bug for RX counters. On an RX overflow interrupt the high
|
|
|
+ * words of all RX counters were incremented.
|
|
|
+ * -SET operations on FLOWCTRL_MODE and LINK_MODE accept now the
|
|
|
+ * value 0, which has no effect. It is usefull for multiple instance
|
|
|
+ * SETs.
|
|
|
+ *
|
|
|
+ * Revision 1.37 1998/11/20 08:02:04 mhaveman
|
|
|
+ * -Fixed: Ports were compared with MAX_SENSORS
|
|
|
+ * -Fixed: Crash in GetTrapEntry with MEMSET macro
|
|
|
+ * -Fixed: Conversions between physical, logical port index and instance
|
|
|
+ *
|
|
|
+ * Revision 1.36 1998/11/16 07:48:53 mhaveman
|
|
|
+ * Casted SK_DRIVER_SENDEVENT with (void) to eleminate compiler warnings
|
|
|
+ * on Solaris.
|
|
|
+ *
|
|
|
+ * Revision 1.35 1998/11/16 07:45:34 mhaveman
|
|
|
+ * SkAddrOverride now returns value and will be checked.
|
|
|
+ *
|
|
|
+ * Revision 1.34 1998/11/10 13:40:37 mhaveman
|
|
|
+ * Needed to change interface, because NT driver needs a return value
|
|
|
+ * of needed buffer space on TOO_SHORT errors. Therefore all
|
|
|
+ * SkPnmiGet/Preset/Set functions now have a pointer to the length
|
|
|
+ * parameter, where the needed space on error is returned.
|
|
|
+ *
|
|
|
+ * Revision 1.33 1998/11/03 13:52:46 mhaveman
|
|
|
+ * Made file lint conform.
|
|
|
+ *
|
|
|
+ * Revision 1.32 1998/11/03 13:19:07 mhaveman
|
|
|
+ * The events SK_HWEV_SET_LMODE and SK_HWEV_SET_FLOWMODE pass now in
|
|
|
+ * Para32[0] the physical MAC index and in Para32[1] the new mode.
|
|
|
+ *
|
|
|
+ * Revision 1.31 1998/11/03 12:30:40 gklug
|
|
|
+ * fix: compiler warning memset
|
|
|
+ *
|
|
|
+ * Revision 1.30 1998/11/03 12:04:46 mhaveman
|
|
|
+ * Fixed problem in SENSOR_VALUE, which wrote beyond the buffer end
|
|
|
+ * Fixed alignment problem with CHIPSET.
|
|
|
+ *
|
|
|
+ * Revision 1.29 1998/11/02 11:23:54 mhaveman
|
|
|
+ * Corrected SK_ERROR_LOG to SK_ERR_LOG. Sorry.
|
|
|
+ *
|
|
|
+ * Revision 1.28 1998/11/02 10:47:16 mhaveman
|
|
|
+ * Added syslog messages for internal errors.
|
|
|
+ *
|
|
|
+ * Revision 1.27 1998/10/30 15:48:06 mhaveman
|
|
|
+ * Fixed problems after simulation of SK_PNMI_EVT_CHG_EST_TIMER and
|
|
|
+ * RlmtChangeThreshold calculation.
|
|
|
+ *
|
|
|
+ * Revision 1.26 1998/10/29 15:36:55 mhaveman
|
|
|
+ * -Fixed bug in trap buffer handling.
|
|
|
+ * -OID_SKGE_DRIVER_DESCR, OID_SKGE_DRIVER_VERSION, OID_SKGE_HW_DESCR,
|
|
|
+ * OID_SKGE_HW_VERSION, OID_SKGE_VPD_ENTRIES_LIST, OID_SKGE_VPD_KEY,
|
|
|
+ * OID_SKGE_VPD_VALUE, and OID_SKGE_SENSOR_DESCR return values with
|
|
|
+ * a leading octet before each string storing the string length.
|
|
|
+ * -Perform a RlmtUpdate during SK_PNMI_EVT_XMAC_RESET to minimize
|
|
|
+ * RlmtUpdate calls in GetStatVal.
|
|
|
+ * -Inserted SK_PNMI_CHECKFLAGS macro increase readability.
|
|
|
+ *
|
|
|
+ * Revision 1.25 1998/10/29 08:50:36 mhaveman
|
|
|
+ * Fixed problems after second event simulation.
|
|
|
+ *
|
|
|
+ * Revision 1.24 1998/10/28 08:44:37 mhaveman
|
|
|
+ * -Fixed alignment problem
|
|
|
+ * -Fixed problems during event simulation
|
|
|
+ * -Fixed sequence of error return code (INSTANCE -> ACCESS -> SHORT)
|
|
|
+ * -Changed type of parameter Instance back to SK_U32 because of VPD
|
|
|
+ * -Updated new VPD function calls
|
|
|
+ *
|
|
|
+ * Revision 1.23 1998/10/23 10:16:37 mhaveman
|
|
|
+ * Fixed bugs after buffer test simulation.
|
|
|
+ *
|
|
|
+ * Revision 1.22 1998/10/21 13:23:52 mhaveman
|
|
|
+ * -Call syntax of SkOsGetTime() changed to SkOsGetTime(pAc).
|
|
|
+ * -Changed calculation of hundrets of seconds.
|
|
|
+ *
|
|
|
+ * Revision 1.20 1998/10/20 07:30:45 mhaveman
|
|
|
+ * Made type changes to unsigned integer where possible.
|
|
|
+ *
|
|
|
+ * Revision 1.19 1998/10/19 10:51:30 mhaveman
|
|
|
+ * -Made Bug fixes after simulation run
|
|
|
+ * -Renamed RlmtMAC... to RlmtPort...
|
|
|
+ * -Marked workarounds with Errata comments
|
|
|
+ *
|
|
|
+ * Revision 1.18 1998/10/14 07:50:08 mhaveman
|
|
|
+ * -For OID_SKGE_LINK_STATUS the link down detection has moved from RLMT
|
|
|
+ * to HWACCESS.
|
|
|
+ * -Provided all MEMCPY/MEMSET macros with (char *) pointers, because
|
|
|
+ * Solaris throwed warnings when mapping to bcopy/bset.
|
|
|
+ *
|
|
|
+ * Revision 1.17 1998/10/13 07:42:01 mhaveman
|
|
|
+ * -Added OIDs OID_SKGE_TRAP_NUMBER and OID_SKGE_ALL_DATA
|
|
|
+ * -Removed old cvs history entries
|
|
|
+ * -Renamed MacNumber to PortNumber
|
|
|
+ *
|
|
|
+ * Revision 1.16 1998/10/07 10:52:49 mhaveman
|
|
|
+ * -Inserted handling of some OID_GEN_ Ids for windows
|
|
|
+ * -Fixed problem with 803.2 statistic.
|
|
|
+ *
|
|
|
+ * Revision 1.15 1998/10/01 09:16:29 mhaveman
|
|
|
+ * Added Debug messages for function call and UpdateFlag tracing.
|
|
|
+ *
|
|
|
+ * Revision 1.14 1998/09/30 13:39:09 mhaveman
|
|
|
+ * -Reduced namings of 'MAC' by replacing them with 'PORT'.
|
|
|
+ * -Completed counting of OID_SKGE_RX_HW_ERROR_CTS,
|
|
|
+ * OID_SKGE_TX_HW_ERROR_CTS,
|
|
|
+ * OID_SKGE_IN_ERRORS_CTS, and OID_SKGE_OUT_ERROR_CTS.
|
|
|
+ * -SET check for RlmtMode
|
|
|
+ *
|
|
|
+ * Revision 1.13 1998/09/28 13:13:08 mhaveman
|
|
|
+ * Hide strcmp, strlen, and strncpy behind macros SK_STRCMP, SK_STRLEN,
|
|
|
+ * and SK_STRNCPY. (Same reasons as for mem.. and MEM..)
|
|
|
+ *
|
|
|
+ * Revision 1.12 1998/09/16 08:18:36 cgoos
|
|
|
+ * Fix: XM_INxx and XM_OUTxx called with different parameter order:
|
|
|
+ * sometimes IoC,Mac,... sometimes Mac,IoC,... Now always first variant.
|
|
|
+ * Fix: inserted "Pnmi." into some pAC->pDriverDescription / Version.
|
|
|
+ * Change: memset, memcpy to makros SK_MEMSET, SK_MEMCPY
|
|
|
+ *
|
|
|
+ * Revision 1.11 1998/09/04 17:01:45 mhaveman
|
|
|
+ * Added SyncCounter as macro and OID_SKGE_.._NO_DESCR_CTS to
|
|
|
+ * OID_SKGE_RX_NO_BUF_CTS.
|
|
|
+ *
|
|
|
+ * Revision 1.10 1998/09/04 14:35:35 mhaveman
|
|
|
+ * Added macro counters, that are counted by driver.
|
|
|
+ *
|
|
|
+ ****************************************************************************/
|
|
|
+
|
|
|
+
|
|
|
+static const char SysKonnectFileId[] =
|
|
|
+ "@(#) $Id: skgepnmi.c,v 1.102 2002/12/16 14:03:24 tschilli Exp $"
|
|
|
+ " (C) SysKonnect.";
|
|
|
+
|
|
|
+#include "h/skdrv1st.h"
|
|
|
+#include "h/sktypes.h"
|
|
|
+#include "h/xmac_ii.h"
|
|
|
+#include "h/skdebug.h"
|
|
|
+#include "h/skqueue.h"
|
|
|
+#include "h/skgepnmi.h"
|
|
|
+#include "h/skgesirq.h"
|
|
|
+#include "h/skcsum.h"
|
|
|
+#include "h/skvpd.h"
|
|
|
+#include "h/skgehw.h"
|
|
|
+#include "h/skgeinit.h"
|
|
|
+#include "h/skdrv2nd.h"
|
|
|
+#include "h/skgepnm2.h"
|
|
|
+#ifdef SK_POWER_MGMT
|
|
|
+#include "h/skgepmgt.h"
|
|
|
+#endif
|
|
|
+/* defines *******************************************************************/
|
|
|
+
|
|
|
+#ifndef DEBUG
|
|
|
+#define PNMI_STATIC static
|
|
|
+#else /* DEBUG */
|
|
|
+#define PNMI_STATIC
|
|
|
+#endif /* DEBUG */
|
|
|
+
|
|
|
+/*
|
|
|
+ * Public Function prototypes
|
|
|
+ */
|
|
|
+int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level);
|
|
|
+int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
|
|
|
+ unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
|
|
|
+int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
|
|
|
+ unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
|
|
|
+int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
|
|
|
+ unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
|
|
|
+int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
|
|
|
+ unsigned int *pLen, SK_U32 NetIndex);
|
|
|
+int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
|
|
|
+ unsigned int *pLen, SK_U32 NetIndex);
|
|
|
+int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
|
|
|
+ unsigned int *pLen, SK_U32 NetIndex);
|
|
|
+int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
|
|
|
+
|
|
|
+
|
|
|
+/*
|
|
|
+ * Private Function prototypes
|
|
|
+ */
|
|
|
+
|
|
|
+PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
|
|
|
+ PhysPortIndex);
|
|
|
+PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
|
|
|
+ PhysPortIndex);
|
|
|
+PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac);
|
|
|
+PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
|
|
|
+PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
|
|
|
+ unsigned int PhysPortIndex, unsigned int StatIndex);
|
|
|
+PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
|
|
|
+ unsigned int StatIndex, SK_U32 NetIndex);
|
|
|
+PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
|
|
|
+PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
|
|
|
+ unsigned int *pEntries);
|
|
|
+PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr,
|
|
|
+ unsigned int KeyArrLen, unsigned int *pKeyNo);
|
|
|
+PNMI_STATIC int LookupId(SK_U32 Id);
|
|
|
+PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
|
|
|
+ unsigned int LastMac);
|
|
|
+PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
|
|
|
+ unsigned int *pLen, SK_U32 NetIndex);
|
|
|
+PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id,
|
|
|
+ char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
|
|
|
+PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
|
|
|
+PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
|
|
|
+ unsigned int PortIndex);
|
|
|
+PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
|
|
|
+ unsigned int SensorIndex);
|
|
|
+PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
|
|
|
+PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
|
|
|
+PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
|
|
|
+PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
|
|
|
+PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
|
|
|
+PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
|
|
|
+ unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
|
|
|
+PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
|
|
|
+
|
|
|
+/*
|
|
|
+ * Table to correlate OID with handler function and index to
|
|
|
+ * hardware register stored in StatAddress if applicable.
|
|
|
+ */
|
|
|
+#include "skgemib.c"
|
|
|
+
|
|
|
+/* global variables **********************************************************/
|
|
|
+
|
|
|
+/*
|
|
|
+ * Overflow status register bit table and corresponding counter
|
|
|
+ * dependent on MAC type - the number relates to the size of overflow
|
|
|
+ * mask returned by the pFnMacOverflow function
|
|
|
+ */
|
|
|
+PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = {
|
|
|
+/* Bit0 */ { SK_PNMI_HTX, SK_PNMI_HTX_UNICAST},
|
|
|
+/* Bit1 */ { SK_PNMI_HTX_OCTETHIGH, SK_PNMI_HTX_BROADCAST},
|
|
|
+/* Bit2 */ { SK_PNMI_HTX_OCTETLOW, SK_PNMI_HTX_PMACC},
|
|
|
+/* Bit3 */ { SK_PNMI_HTX_BROADCAST, SK_PNMI_HTX_MULTICAST},
|
|
|
+/* Bit4 */ { SK_PNMI_HTX_MULTICAST, SK_PNMI_HTX_OCTETLOW},
|
|
|
+/* Bit5 */ { SK_PNMI_HTX_UNICAST, SK_PNMI_HTX_OCTETHIGH},
|
|
|
+/* Bit6 */ { SK_PNMI_HTX_LONGFRAMES, SK_PNMI_HTX_64},
|
|
|
+/* Bit7 */ { SK_PNMI_HTX_BURST, SK_PNMI_HTX_127},
|
|
|
+/* Bit8 */ { SK_PNMI_HTX_PMACC, SK_PNMI_HTX_255},
|
|
|
+/* Bit9 */ { SK_PNMI_HTX_MACC, SK_PNMI_HTX_511},
|
|
|
+/* Bit10 */ { SK_PNMI_HTX_SINGLE_COL, SK_PNMI_HTX_1023},
|
|
|
+/* Bit11 */ { SK_PNMI_HTX_MULTI_COL, SK_PNMI_HTX_MAX},
|
|
|
+/* Bit12 */ { SK_PNMI_HTX_EXCESS_COL, SK_PNMI_HTX_LONGFRAMES},
|
|
|
+/* Bit13 */ { SK_PNMI_HTX_LATE_COL, SK_PNMI_HTX_RESERVED},
|
|
|
+/* Bit14 */ { SK_PNMI_HTX_DEFFERAL, SK_PNMI_HTX_COL},
|
|
|
+/* Bit15 */ { SK_PNMI_HTX_EXCESS_DEF, SK_PNMI_HTX_LATE_COL},
|
|
|
+/* Bit16 */ { SK_PNMI_HTX_UNDERRUN, SK_PNMI_HTX_EXCESS_COL},
|
|
|
+/* Bit17 */ { SK_PNMI_HTX_CARRIER, SK_PNMI_HTX_MULTI_COL},
|
|
|
+/* Bit18 */ { SK_PNMI_HTX_UTILUNDER, SK_PNMI_HTX_SINGLE_COL},
|
|
|
+/* Bit19 */ { SK_PNMI_HTX_UTILOVER, SK_PNMI_HTX_UNDERRUN},
|
|
|
+/* Bit20 */ { SK_PNMI_HTX_64, SK_PNMI_HTX_RESERVED},
|
|
|
+/* Bit21 */ { SK_PNMI_HTX_127, SK_PNMI_HTX_RESERVED},
|
|
|
+/* Bit22 */ { SK_PNMI_HTX_255, SK_PNMI_HTX_RESERVED},
|
|
|
+/* Bit23 */ { SK_PNMI_HTX_511, SK_PNMI_HTX_RESERVED},
|
|
|
+/* Bit24 */ { SK_PNMI_HTX_1023, SK_PNMI_HTX_RESERVED},
|
|
|
+/* Bit25 */ { SK_PNMI_HTX_MAX, SK_PNMI_HTX_RESERVED},
|
|
|
+/* Bit26 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
|
|
|
+/* Bit27 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
|
|
|
+/* Bit28 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
|
|
|
+/* Bit29 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
|
|
|
+/* Bit30 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
|
|
|
+/* Bit31 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
|
|
|
+/* Bit32 */ { SK_PNMI_HRX, SK_PNMI_HRX_UNICAST},
|
|
|
+/* Bit33 */ { SK_PNMI_HRX_OCTETHIGH, SK_PNMI_HRX_BROADCAST},
|
|
|
+/* Bit34 */ { SK_PNMI_HRX_OCTETLOW, SK_PNMI_HRX_PMACC},
|
|
|
+/* Bit35 */ { SK_PNMI_HRX_BROADCAST, SK_PNMI_HRX_MULTICAST},
|
|
|
+/* Bit36 */ { SK_PNMI_HRX_MULTICAST, SK_PNMI_HRX_FCS},
|
|
|
+/* Bit37 */ { SK_PNMI_HRX_UNICAST, SK_PNMI_HRX_RESERVED},
|
|
|
+/* Bit38 */ { SK_PNMI_HRX_PMACC, SK_PNMI_HRX_OCTETLOW},
|
|
|
+/* Bit39 */ { SK_PNMI_HRX_MACC, SK_PNMI_HRX_OCTETHIGH},
|
|
|
+/* Bit40 */ { SK_PNMI_HRX_PMACC_ERR, SK_PNMI_HRX_BADOCTETLOW},
|
|
|
+/* Bit41 */ { SK_PNMI_HRX_MACC_UNKWN, SK_PNMI_HRX_BADOCTETHIGH},
|
|
|
+/* Bit42 */ { SK_PNMI_HRX_BURST, SK_PNMI_HRX_UNDERSIZE},
|
|
|
+/* Bit43 */ { SK_PNMI_HRX_MISSED, SK_PNMI_HRX_RUNT},
|
|
|
+/* Bit44 */ { SK_PNMI_HRX_FRAMING, SK_PNMI_HRX_64},
|
|
|
+/* Bit45 */ { SK_PNMI_HRX_OVERFLOW, SK_PNMI_HRX_127},
|
|
|
+/* Bit46 */ { SK_PNMI_HRX_JABBER, SK_PNMI_HRX_255},
|
|
|
+/* Bit47 */ { SK_PNMI_HRX_CARRIER, SK_PNMI_HRX_511},
|
|
|
+/* Bit48 */ { SK_PNMI_HRX_IRLENGTH, SK_PNMI_HRX_1023},
|
|
|
+/* Bit49 */ { SK_PNMI_HRX_SYMBOL, SK_PNMI_HRX_MAX},
|
|
|
+/* Bit50 */ { SK_PNMI_HRX_SHORTS, SK_PNMI_HRX_LONGFRAMES},
|
|
|
+/* Bit51 */ { SK_PNMI_HRX_RUNT, SK_PNMI_HRX_TOO_LONG},
|
|
|
+/* Bit52 */ { SK_PNMI_HRX_TOO_LONG, SK_PNMI_HRX_JABBER},
|
|
|
+/* Bit53 */ { SK_PNMI_HRX_FCS, SK_PNMI_HRX_RESERVED},
|
|
|
+/* Bit54 */ { SK_PNMI_HRX_RESERVED, SK_PNMI_HRX_OVERFLOW},
|
|
|
+/* Bit55 */ { SK_PNMI_HRX_CEXT, SK_PNMI_HRX_RESERVED},
|
|
|
+/* Bit56 */ { SK_PNMI_HRX_UTILUNDER, SK_PNMI_HRX_RESERVED},
|
|
|
+/* Bit57 */ { SK_PNMI_HRX_UTILOVER, SK_PNMI_HRX_RESERVED},
|
|
|
+/* Bit58 */ { SK_PNMI_HRX_64, SK_PNMI_HRX_RESERVED},
|
|
|
+/* Bit59 */ { SK_PNMI_HRX_127, SK_PNMI_HRX_RESERVED},
|
|
|
+/* Bit60 */ { SK_PNMI_HRX_255, SK_PNMI_HRX_RESERVED},
|
|
|
+/* Bit61 */ { SK_PNMI_HRX_511, SK_PNMI_HRX_RESERVED},
|
|
|
+/* Bit62 */ { SK_PNMI_HRX_1023, SK_PNMI_HRX_RESERVED},
|
|
|
+/* Bit63 */ { SK_PNMI_HRX_MAX, SK_PNMI_HRX_RESERVED}
|
|
|
+};
|
|
|
+
|
|
|
+/*
|
|
|
+ * Table for hardware register saving on resets and port switches
|
|
|
+ */
|
|
|
+PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = {
|
|
|
+ /* SK_PNMI_HTX */
|
|
|
+ {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HTX_OCTETHIGH */
|
|
|
+ {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HTX_OCTETLOW */
|
|
|
+ {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HTX_BROADCAST */
|
|
|
+ {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HTX_MULTICAST */
|
|
|
+ {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HTX_UNICAST */
|
|
|
+ {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HTX_BURST */
|
|
|
+ {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HTX_PMACC */
|
|
|
+ {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HTX_MACC */
|
|
|
+ {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HTX_COL */
|
|
|
+ {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HTX_SINGLE_COL */
|
|
|
+ {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HTX_MULTI_COL */
|
|
|
+ {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HTX_EXCESS_COL */
|
|
|
+ {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HTX_LATE_COL */
|
|
|
+ {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HTX_DEFFERAL */
|
|
|
+ {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HTX_EXCESS_DEF */
|
|
|
+ {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HTX_UNDERRUN */
|
|
|
+ {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HTX_CARRIER */
|
|
|
+ {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HTX_UTILUNDER */
|
|
|
+ {{0, SK_FALSE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HTX_UTILOVER */
|
|
|
+ {{0, SK_FALSE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HTX_64 */
|
|
|
+ {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HTX_127 */
|
|
|
+ {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HTX_255 */
|
|
|
+ {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HTX_511 */
|
|
|
+ {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HTX_1023 */
|
|
|
+ {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HTX_MAX */
|
|
|
+ {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HTX_LONGFRAMES */
|
|
|
+ {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HTX_SYNC */
|
|
|
+ {{0, SK_FALSE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HTX_SYNC_OCTET */
|
|
|
+ {{0, SK_FALSE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HTX_RESERVED */
|
|
|
+ {{0, SK_FALSE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HRX */
|
|
|
+ {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HRX_OCTETHIGH */
|
|
|
+ {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HRX_OCTETLOW */
|
|
|
+ {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HRX_BADOCTETHIGH */
|
|
|
+ {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HRX_BADOCTETLOW */
|
|
|
+ {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HRX_BROADCAST */
|
|
|
+ {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HRX_MULTICAST */
|
|
|
+ {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HRX_UNICAST */
|
|
|
+ {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HRX_PMACC */
|
|
|
+ {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HRX_MACC */
|
|
|
+ {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HRX_PMACC_ERR */
|
|
|
+ {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HRX_MACC_UNKWN */
|
|
|
+ {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HRX_BURST */
|
|
|
+ {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HRX_MISSED */
|
|
|
+ {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HRX_FRAMING */
|
|
|
+ {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HRX_UNDERSIZE */
|
|
|
+ {{0, SK_FALSE},{GM_RXF_SHT, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HRX_OVERFLOW */
|
|
|
+ {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HRX_JABBER */
|
|
|
+ {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HRX_CARRIER */
|
|
|
+ {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HRX_IRLENGTH */
|
|
|
+ {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HRX_SYMBOL */
|
|
|
+ {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HRX_SHORTS */
|
|
|
+ {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HRX_RUNT */
|
|
|
+ {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HRX_TOO_LONG */
|
|
|
+ {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HRX_FCS */
|
|
|
+ {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HRX_CEXT */
|
|
|
+ {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HRX_UTILUNDER */
|
|
|
+ {{0, SK_FALSE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HRX_UTILOVER */
|
|
|
+ {{0, SK_FALSE}, {0, SK_FALSE}},
|
|
|
+ /* SK_PNMI_HRX_64 */
|
|
|
+ {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HRX_127 */
|
|
|
+ {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HRX_255 */
|
|
|
+ {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HRX_511 */
|
|
|
+ {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HRX_1023 */
|
|
|
+ {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HRX_MAX */
|
|
|
+ {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HRX_LONGFRAMES */
|
|
|
+ {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}},
|
|
|
+ /* SK_PNMI_HRX_RESERVED */
|
|
|
+ {{0, SK_FALSE}, {0, SK_FALSE}}
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * Public functions
|
|
|
+ *
|
|
|
+ */
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * SkPnmiInit - Init function of PNMI
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * SK_INIT_DATA: Initialises the data structures
|
|
|
+ * SK_INIT_IO: Resets the XMAC statistics, determines the device and
|
|
|
+ * connector type.
|
|
|
+ * SK_INIT_RUN: Starts a timer event for port switch per hour
|
|
|
+ * calculation.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * Always 0
|
|
|
+ */
|
|
|
+int SkPnmiInit(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+int Level) /* Initialization level */
|
|
|
+{
|
|
|
+ unsigned int PortMax; /* Number of ports */
|
|
|
+ unsigned int PortIndex; /* Current port index in loop */
|
|
|
+ SK_U16 Val16; /* Multiple purpose 16 bit variable */
|
|
|
+ SK_U8 Val8; /* Mulitple purpose 8 bit variable */
|
|
|
+ SK_EVPARA EventParam; /* Event struct for timer event */
|
|
|
+ SK_GEPORT *pPrt;
|
|
|
+ SK_PNMI_VCT *pVctBackupData;
|
|
|
+
|
|
|
+
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
|
|
|
+ ("PNMI: SkPnmiInit: Called, level=%d\n", Level));
|
|
|
+
|
|
|
+ switch (Level) {
|
|
|
+
|
|
|
+ case SK_INIT_DATA:
|
|
|
+ SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
|
|
|
+ pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
|
|
|
+ pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
|
|
|
+ pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
|
|
|
+ for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
|
|
|
+
|
|
|
+ pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
|
|
|
+ pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+#ifdef SK_PNMI_CHECK
|
|
|
+ if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG);
|
|
|
+
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
|
|
|
+ ("CounterOffset struct size (%d) differs from"
|
|
|
+ "SK_PNMI_MAX_IDX (%d)\n",
|
|
|
+ SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
|
|
|
+ BRK;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (SK_PNMI_MAX_IDX !=
|
|
|
+ (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG);
|
|
|
+
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
|
|
|
+ ("StatAddr table size (%d) differs from "
|
|
|
+ "SK_PNMI_MAX_IDX (%d)\n",
|
|
|
+ (sizeof(StatAddr) /
|
|
|
+ (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)),
|
|
|
+ SK_PNMI_MAX_IDX));
|
|
|
+ BRK;
|
|
|
+ }
|
|
|
+#endif /* SK_PNMI_CHECK */
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_INIT_IO:
|
|
|
+ /*
|
|
|
+ * Reset MAC counters
|
|
|
+ */
|
|
|
+ PortMax = pAC->GIni.GIMacsFound;
|
|
|
+
|
|
|
+ for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
|
|
|
+
|
|
|
+ pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Initialize DSP variables for Vct() to 0xff => Never written! */
|
|
|
+ for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
|
|
|
+ pPrt = &pAC->GIni.GP[PortIndex];
|
|
|
+ pPrt->PCableLen =0xff;
|
|
|
+ pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
|
|
|
+ pVctBackupData->PCableLen = 0xff;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get pci bus speed
|
|
|
+ */
|
|
|
+ SK_IN16(IoC, B0_CTST, &Val16);
|
|
|
+ if ((Val16 & CS_BUS_CLOCK) == 0) {
|
|
|
+
|
|
|
+ pAC->Pnmi.PciBusSpeed = 33;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ pAC->Pnmi.PciBusSpeed = 66;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get pci bus width
|
|
|
+ */
|
|
|
+ SK_IN16(IoC, B0_CTST, &Val16);
|
|
|
+ if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
|
|
|
+
|
|
|
+ pAC->Pnmi.PciBusWidth = 32;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ pAC->Pnmi.PciBusWidth = 64;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get chipset
|
|
|
+ */
|
|
|
+ switch (pAC->GIni.GIChipId) {
|
|
|
+ case CHIP_ID_GENESIS:
|
|
|
+ pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case CHIP_ID_YUKON:
|
|
|
+ pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get PMD and DeviceType
|
|
|
+ */
|
|
|
+ SK_IN8(IoC, B2_PMD_TYP, &Val8);
|
|
|
+ switch (Val8) {
|
|
|
+ case 'S':
|
|
|
+ pAC->Pnmi.PMD = 3;
|
|
|
+ if (pAC->GIni.GIMacsFound > 1) {
|
|
|
+
|
|
|
+ pAC->Pnmi.DeviceType = 0x00020002;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ pAC->Pnmi.DeviceType = 0x00020001;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'L':
|
|
|
+ pAC->Pnmi.PMD = 2;
|
|
|
+ if (pAC->GIni.GIMacsFound > 1) {
|
|
|
+
|
|
|
+ pAC->Pnmi.DeviceType = 0x00020004;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ pAC->Pnmi.DeviceType = 0x00020003;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'C':
|
|
|
+ pAC->Pnmi.PMD = 4;
|
|
|
+ if (pAC->GIni.GIMacsFound > 1) {
|
|
|
+
|
|
|
+ pAC->Pnmi.DeviceType = 0x00020006;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ pAC->Pnmi.DeviceType = 0x00020005;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'T':
|
|
|
+ pAC->Pnmi.PMD = 5;
|
|
|
+ if (pAC->GIni.GIMacsFound > 1) {
|
|
|
+
|
|
|
+ pAC->Pnmi.DeviceType = 0x00020008;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ pAC->Pnmi.DeviceType = 0x00020007;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default :
|
|
|
+ pAC->Pnmi.PMD = 1;
|
|
|
+ pAC->Pnmi.DeviceType = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get connector
|
|
|
+ */
|
|
|
+ SK_IN8(IoC, B2_CONN_TYP, &Val8);
|
|
|
+ switch (Val8) {
|
|
|
+ case 'C':
|
|
|
+ pAC->Pnmi.Connector = 2;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'D':
|
|
|
+ pAC->Pnmi.Connector = 3;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'F':
|
|
|
+ pAC->Pnmi.Connector = 4;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'J':
|
|
|
+ pAC->Pnmi.Connector = 5;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'V':
|
|
|
+ pAC->Pnmi.Connector = 6;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ pAC->Pnmi.Connector = 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_INIT_RUN:
|
|
|
+ /*
|
|
|
+ * Start timer for RLMT change counter
|
|
|
+ */
|
|
|
+ SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
|
|
|
+ SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
|
|
|
+ 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
|
|
|
+ EventParam);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break; /* Nothing todo */
|
|
|
+ }
|
|
|
+
|
|
|
+ return (0);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * SkPnmiGetVar - Retrieves the value of a single OID
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Calls a general sub-function for all this stuff. If the instance
|
|
|
+ * -1 is passed, the values of all instances are returned in an
|
|
|
+ * array of values.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK The request was successfully performed
|
|
|
+ * SK_PNMI_ERR_GENERAL A general severe internal error occured
|
|
|
+ * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
|
|
|
+ * the data.
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
|
|
|
+ * exist (e.g. port instance 3 on a two port
|
|
|
+ * adapter.
|
|
|
+ */
|
|
|
+int SkPnmiGetVar(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+SK_U32 Id, /* Object ID that is to be processed */
|
|
|
+void *pBuf, /* Buffer to which to mgmt data will be retrieved */
|
|
|
+unsigned int *pLen, /* On call: buffer length. On return: used buffer */
|
|
|
+SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
|
|
|
+ ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
|
|
|
+ Id, *pLen, Instance, NetIndex));
|
|
|
+
|
|
|
+ return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
|
|
|
+ Instance, NetIndex));
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * SkPnmiPreSetVar - Presets the value of a single OID
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Calls a general sub-function for all this stuff. The preset does
|
|
|
+ * the same as a set, but returns just before finally setting the
|
|
|
+ * new value. This is usefull to check if a set might be successfull.
|
|
|
+ * If as instance a -1 is passed, an array of values is supposed and
|
|
|
+ * all instance of the OID will be set.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK The request was successfully performed.
|
|
|
+ * SK_PNMI_ERR_GENERAL A general severe internal error occured.
|
|
|
+ * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
|
|
|
+ * the correct data (e.g. a 32bit value is
|
|
|
+ * needed, but a 16 bit value was passed).
|
|
|
+ * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
|
|
|
+ * value range.
|
|
|
+ * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
|
|
|
+ * exist (e.g. port instance 3 on a two port
|
|
|
+ * adapter.
|
|
|
+ */
|
|
|
+int SkPnmiPreSetVar(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+SK_U32 Id, /* Object ID that is to be processed */
|
|
|
+void *pBuf, /* Buffer which stores the mgmt data to be set */
|
|
|
+unsigned int *pLen, /* Total length of mgmt data */
|
|
|
+SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
|
|
|
+ ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
|
|
|
+ Id, *pLen, Instance, NetIndex));
|
|
|
+
|
|
|
+
|
|
|
+ return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
|
|
|
+ Instance, NetIndex));
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * SkPnmiSetVar - Sets the value of a single OID
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Calls a general sub-function for all this stuff. The preset does
|
|
|
+ * the same as a set, but returns just before finally setting the
|
|
|
+ * new value. This is usefull to check if a set might be successfull.
|
|
|
+ * If as instance a -1 is passed, an array of values is supposed and
|
|
|
+ * all instance of the OID will be set.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK The request was successfully performed.
|
|
|
+ * SK_PNMI_ERR_GENERAL A general severe internal error occured.
|
|
|
+ * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
|
|
|
+ * the correct data (e.g. a 32bit value is
|
|
|
+ * needed, but a 16 bit value was passed).
|
|
|
+ * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
|
|
|
+ * value range.
|
|
|
+ * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
|
|
|
+ * exist (e.g. port instance 3 on a two port
|
|
|
+ * adapter.
|
|
|
+ */
|
|
|
+int SkPnmiSetVar(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+SK_U32 Id, /* Object ID that is to be processed */
|
|
|
+void *pBuf, /* Buffer which stores the mgmt data to be set */
|
|
|
+unsigned int *pLen, /* Total length of mgmt data */
|
|
|
+SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
|
|
|
+ ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
|
|
|
+ Id, *pLen, Instance, NetIndex));
|
|
|
+
|
|
|
+ return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
|
|
|
+ Instance, NetIndex));
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Runs through the IdTable, queries the single OIDs and stores the
|
|
|
+ * returned data into the management database structure
|
|
|
+ * SK_PNMI_STRUCT_DATA. The offset of the OID in the structure
|
|
|
+ * is stored in the IdTable. The return value of the function will also
|
|
|
+ * be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
|
|
|
+ * minimum size of SK_PNMI_MIN_STRUCT_SIZE.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK The request was successfully performed
|
|
|
+ * SK_PNMI_ERR_GENERAL A general severe internal error occured
|
|
|
+ * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
|
|
|
+ * the data.
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
|
|
|
+ */
|
|
|
+int SkPnmiGetStruct(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+void *pBuf, /* Buffer which will store the retrieved data */
|
|
|
+unsigned int *pLen, /* Length of buffer */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+ int Ret;
|
|
|
+ unsigned int TableIndex;
|
|
|
+ unsigned int DstOffset;
|
|
|
+ unsigned int InstanceNo;
|
|
|
+ unsigned int InstanceCnt;
|
|
|
+ SK_U32 Instance;
|
|
|
+ unsigned int TmpLen;
|
|
|
+ char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
|
|
|
+
|
|
|
+
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
|
|
|
+ ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
|
|
|
+ *pLen, NetIndex));
|
|
|
+
|
|
|
+ if (*pLen < SK_PNMI_STRUCT_SIZE) {
|
|
|
+
|
|
|
+ if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
|
|
|
+
|
|
|
+ SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
|
|
|
+ (SK_U32)(-1));
|
|
|
+ }
|
|
|
+
|
|
|
+ *pLen = SK_PNMI_STRUCT_SIZE;
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check NetIndex
|
|
|
+ */
|
|
|
+ if (NetIndex >= pAC->Rlmt.NumNets) {
|
|
|
+ return (SK_PNMI_ERR_UNKNOWN_NET);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Update statistic */
|
|
|
+ SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
|
|
|
+
|
|
|
+ if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
|
|
|
+ SK_PNMI_ERR_OK) {
|
|
|
+
|
|
|
+ SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
|
|
|
+ *pLen = SK_PNMI_MIN_STRUCT_SIZE;
|
|
|
+ return (Ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
|
|
|
+
|
|
|
+ SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
|
|
|
+ *pLen = SK_PNMI_MIN_STRUCT_SIZE;
|
|
|
+ return (Ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
|
|
|
+
|
|
|
+ SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
|
|
|
+ *pLen = SK_PNMI_MIN_STRUCT_SIZE;
|
|
|
+ return (Ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Increment semaphores to indicate that an update was
|
|
|
+ * already done
|
|
|
+ */
|
|
|
+ pAC->Pnmi.MacUpdatedFlag ++;
|
|
|
+ pAC->Pnmi.RlmtUpdatedFlag ++;
|
|
|
+ pAC->Pnmi.SirqUpdatedFlag ++;
|
|
|
+
|
|
|
+ /* Get vpd keys for instance calculation */
|
|
|
+ Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
|
|
|
+ if (Ret != SK_PNMI_ERR_OK) {
|
|
|
+
|
|
|
+ pAC->Pnmi.MacUpdatedFlag --;
|
|
|
+ pAC->Pnmi.RlmtUpdatedFlag --;
|
|
|
+ pAC->Pnmi.SirqUpdatedFlag --;
|
|
|
+
|
|
|
+ SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
|
|
|
+ SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
|
|
|
+ *pLen = SK_PNMI_MIN_STRUCT_SIZE;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Retrieve values */
|
|
|
+ SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
|
|
|
+ for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
|
|
|
+
|
|
|
+ InstanceNo = IdTable[TableIndex].InstanceNo;
|
|
|
+ for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
|
|
|
+ InstanceCnt ++) {
|
|
|
+
|
|
|
+ DstOffset = IdTable[TableIndex].Offset +
|
|
|
+ (InstanceCnt - 1) *
|
|
|
+ IdTable[TableIndex].StructSize;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * For the VPD the instance is not an index number
|
|
|
+ * but the key itself. Determin with the instance
|
|
|
+ * counter the VPD key to be used.
|
|
|
+ */
|
|
|
+ if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
|
|
|
+ IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
|
|
|
+ IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
|
|
|
+ IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
|
|
|
+
|
|
|
+ SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ Instance = (SK_U32)InstanceCnt;
|
|
|
+ }
|
|
|
+
|
|
|
+ TmpLen = *pLen - DstOffset;
|
|
|
+ Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
|
|
|
+ IdTable[TableIndex].Id, (char *)pBuf +
|
|
|
+ DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * An unknown instance error means that we reached
|
|
|
+ * the last instance of that variable. Proceed with
|
|
|
+ * the next OID in the table and ignore the return
|
|
|
+ * code.
|
|
|
+ */
|
|
|
+ if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Ret != SK_PNMI_ERR_OK) {
|
|
|
+
|
|
|
+ pAC->Pnmi.MacUpdatedFlag --;
|
|
|
+ pAC->Pnmi.RlmtUpdatedFlag --;
|
|
|
+ pAC->Pnmi.SirqUpdatedFlag --;
|
|
|
+
|
|
|
+ SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
|
|
|
+ SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
|
|
|
+ *pLen = SK_PNMI_MIN_STRUCT_SIZE;
|
|
|
+ return (Ret);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ pAC->Pnmi.MacUpdatedFlag --;
|
|
|
+ pAC->Pnmi.RlmtUpdatedFlag --;
|
|
|
+ pAC->Pnmi.SirqUpdatedFlag --;
|
|
|
+
|
|
|
+ *pLen = SK_PNMI_STRUCT_SIZE;
|
|
|
+ SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
|
|
|
+ SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Calls a general sub-function for all this set stuff. The preset does
|
|
|
+ * the same as a set, but returns just before finally setting the
|
|
|
+ * new value. This is usefull to check if a set might be successfull.
|
|
|
+ * The sub-function runs through the IdTable, checks which OIDs are able
|
|
|
+ * to set, and calls the handler function of the OID to perform the
|
|
|
+ * preset. The return value of the function will also be stored in
|
|
|
+ * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
|
|
|
+ * SK_PNMI_MIN_STRUCT_SIZE.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK The request was successfully performed.
|
|
|
+ * SK_PNMI_ERR_GENERAL A general severe internal error occured.
|
|
|
+ * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
|
|
|
+ * the correct data (e.g. a 32bit value is
|
|
|
+ * needed, but a 16 bit value was passed).
|
|
|
+ * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
|
|
|
+ * value range.
|
|
|
+ */
|
|
|
+int SkPnmiPreSetStruct(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+void *pBuf, /* Buffer which contains the data to be set */
|
|
|
+unsigned int *pLen, /* Length of buffer */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
|
|
|
+ ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
|
|
|
+ *pLen, NetIndex));
|
|
|
+
|
|
|
+ return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf,
|
|
|
+ pLen, NetIndex));
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Calls a general sub-function for all this set stuff. The return value
|
|
|
+ * of the function will also be stored in SK_PNMI_STRUCT_DATA if the
|
|
|
+ * passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE.
|
|
|
+ * The sub-function runs through the IdTable, checks which OIDs are able
|
|
|
+ * to set, and calls the handler function of the OID to perform the
|
|
|
+ * set. The return value of the function will also be stored in
|
|
|
+ * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
|
|
|
+ * SK_PNMI_MIN_STRUCT_SIZE.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK The request was successfully performed.
|
|
|
+ * SK_PNMI_ERR_GENERAL A general severe internal error occured.
|
|
|
+ * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
|
|
|
+ * the correct data (e.g. a 32bit value is
|
|
|
+ * needed, but a 16 bit value was passed).
|
|
|
+ * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
|
|
|
+ * value range.
|
|
|
+ */
|
|
|
+int SkPnmiSetStruct(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+void *pBuf, /* Buffer which contains the data to be set */
|
|
|
+unsigned int *pLen, /* Length of buffer */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
|
|
|
+ ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
|
|
|
+ *pLen, NetIndex));
|
|
|
+
|
|
|
+ return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf,
|
|
|
+ pLen, NetIndex));
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * SkPnmiEvent - Event handler
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Handles the following events:
|
|
|
+ * SK_PNMI_EVT_SIRQ_OVERFLOW When a hardware counter overflows an
|
|
|
+ * interrupt will be generated which is
|
|
|
+ * first handled by SIRQ which generates a
|
|
|
+ * this event. The event increments the
|
|
|
+ * upper 32 bit of the 64 bit counter.
|
|
|
+ * SK_PNMI_EVT_SEN_XXX The event is generated by the I2C module
|
|
|
+ * when a sensor reports a warning or
|
|
|
+ * error. The event will store a trap
|
|
|
+ * message in the trap buffer.
|
|
|
+ * SK_PNMI_EVT_CHG_EST_TIMER The timer event was initiated by this
|
|
|
+ * module and is used to calculate the
|
|
|
+ * port switches per hour.
|
|
|
+ * SK_PNMI_EVT_CLEAR_COUNTER The event clears all counters and
|
|
|
+ * timestamps.
|
|
|
+ * SK_PNMI_EVT_XMAC_RESET The event is generated by the driver
|
|
|
+ * before a hard reset of the XMAC is
|
|
|
+ * performed. All counters will be saved
|
|
|
+ * and added to the hardware counter
|
|
|
+ * values after reset to grant continuous
|
|
|
+ * counter values.
|
|
|
+ * SK_PNMI_EVT_RLMT_PORT_UP Generated by RLMT to notify that a port
|
|
|
+ * went logically up. A trap message will
|
|
|
+ * be stored to the trap buffer.
|
|
|
+ * SK_PNMI_EVT_RLMT_PORT_DOWN Generated by RLMT to notify that a port
|
|
|
+ * went logically down. A trap message will
|
|
|
+ * be stored to the trap buffer.
|
|
|
+ * SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
|
|
|
+ * spanning tree root bridges were
|
|
|
+ * detected. A trap message will be stored
|
|
|
+ * to the trap buffer.
|
|
|
+ * SK_PNMI_EVT_RLMT_ACTIVE_DOWN Notifies PNMI that an active port went
|
|
|
+ * down. PNMI will not further add the
|
|
|
+ * statistic values to the virtual port.
|
|
|
+ * SK_PNMI_EVT_RLMT_ACTIVE_UP Notifies PNMI that a port went up and
|
|
|
+ * is now an active port. PNMI will now
|
|
|
+ * add the statistic data of this port to
|
|
|
+ * the virtual port.
|
|
|
+ * SK_PNMI_EVT_RLMT_SET_NETS Notifies PNMI about the net mode. The first Parameter
|
|
|
+ * contains the number of nets. 1 means single net, 2 means
|
|
|
+ * dual net. The second Parameter is -1
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * Always 0
|
|
|
+ */
|
|
|
+int SkPnmiEvent(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+SK_U32 Event, /* Event-Id */
|
|
|
+SK_EVPARA Param) /* Event dependent parameter */
|
|
|
+{
|
|
|
+ unsigned int PhysPortIndex;
|
|
|
+ unsigned int MaxNetNumber;
|
|
|
+ int CounterIndex;
|
|
|
+ int Ret;
|
|
|
+ SK_U16 MacStatus;
|
|
|
+ SK_U64 OverflowStatus;
|
|
|
+ SK_U64 Mask;
|
|
|
+ int MacType;
|
|
|
+ SK_U64 Value;
|
|
|
+ SK_U32 Val32;
|
|
|
+ SK_U16 Register;
|
|
|
+ SK_EVPARA EventParam;
|
|
|
+ SK_U64 NewestValue;
|
|
|
+ SK_U64 OldestValue;
|
|
|
+ SK_U64 Delta;
|
|
|
+ SK_PNMI_ESTIMATE *pEst;
|
|
|
+ SK_U32 NetIndex;
|
|
|
+ SK_GEPORT *pPrt;
|
|
|
+ SK_PNMI_VCT *pVctBackupData;
|
|
|
+ SK_U32 RetCode;
|
|
|
+ int i;
|
|
|
+ SK_U32 CableLength;
|
|
|
+
|
|
|
+
|
|
|
+#ifdef DEBUG
|
|
|
+ if (Event != SK_PNMI_EVT_XMAC_RESET) {
|
|
|
+
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
|
|
|
+ ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n",
|
|
|
+ (unsigned int)Event, (unsigned int)Param.Para64));
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call");
|
|
|
+
|
|
|
+ MacType = pAC->GIni.GIMacType;
|
|
|
+
|
|
|
+ switch (Event) {
|
|
|
+
|
|
|
+ case SK_PNMI_EVT_SIRQ_OVERFLOW:
|
|
|
+ PhysPortIndex = (int)Param.Para32[0];
|
|
|
+ MacStatus = (SK_U16)Param.Para32[1];
|
|
|
+#ifdef DEBUG
|
|
|
+ if (PhysPortIndex >= SK_MAX_MACS) {
|
|
|
+
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
|
|
|
+ ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter"
|
|
|
+ " wrong, PhysPortIndex=0x%x\n",
|
|
|
+ PhysPortIndex));
|
|
|
+ return (0);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ OverflowStatus = 0;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check which source caused an overflow interrupt.
|
|
|
+ */
|
|
|
+ if ((pAC->GIni.GIFunc.pFnMacOverflow(
|
|
|
+ pAC, IoC, PhysPortIndex, MacStatus, &OverflowStatus) != 0) ||
|
|
|
+ (OverflowStatus == 0)) {
|
|
|
+
|
|
|
+ SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
|
|
|
+ return (0);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check the overflow status register and increment
|
|
|
+ * the upper dword of corresponding counter.
|
|
|
+ */
|
|
|
+ for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8;
|
|
|
+ CounterIndex ++) {
|
|
|
+
|
|
|
+ Mask = (SK_U64)1 << CounterIndex;
|
|
|
+ if ((OverflowStatus & Mask) == 0) {
|
|
|
+
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (StatOvrflwBit[CounterIndex][MacType]) {
|
|
|
+
|
|
|
+ case SK_PNMI_HTX_UTILUNDER:
|
|
|
+ case SK_PNMI_HTX_UTILOVER:
|
|
|
+ XM_IN16(IoC, PhysPortIndex, XM_TX_CMD,
|
|
|
+ &Register);
|
|
|
+ Register |= XM_TX_SAM_LINE;
|
|
|
+ XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD,
|
|
|
+ Register);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_HRX_UTILUNDER:
|
|
|
+ case SK_PNMI_HRX_UTILOVER:
|
|
|
+ XM_IN16(IoC, PhysPortIndex, XM_RX_CMD,
|
|
|
+ &Register);
|
|
|
+ Register |= XM_RX_SAM_LINE;
|
|
|
+ XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD,
|
|
|
+ Register);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_HTX_OCTETHIGH:
|
|
|
+ case SK_PNMI_HTX_OCTETLOW:
|
|
|
+ case SK_PNMI_HTX_RESERVED:
|
|
|
+ case SK_PNMI_HRX_OCTETHIGH:
|
|
|
+ case SK_PNMI_HRX_OCTETLOW:
|
|
|
+ case SK_PNMI_HRX_IRLENGTH:
|
|
|
+ case SK_PNMI_HRX_RESERVED:
|
|
|
+
|
|
|
+ /*
|
|
|
+ * the following counters aren't be handled (id > 63)
|
|
|
+ */
|
|
|
+ case SK_PNMI_HTX_SYNC:
|
|
|
+ case SK_PNMI_HTX_SYNC_OCTET:
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_HRX_LONGFRAMES:
|
|
|
+ if (MacType == SK_MAC_GMAC) {
|
|
|
+ pAC->Pnmi.Port[PhysPortIndex].
|
|
|
+ CounterHigh[CounterIndex] ++;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ pAC->Pnmi.Port[PhysPortIndex].
|
|
|
+ CounterHigh[CounterIndex] ++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_EVT_SEN_WAR_LOW:
|
|
|
+#ifdef DEBUG
|
|
|
+ if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
|
|
|
+
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
|
|
|
+ ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n",
|
|
|
+ (unsigned int)Param.Para64));
|
|
|
+ return (0);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ /*
|
|
|
+ * Store a trap message in the trap buffer and generate
|
|
|
+ * an event for user space applications with the
|
|
|
+ * SK_DRIVER_SENDEVENT macro.
|
|
|
+ */
|
|
|
+ QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW,
|
|
|
+ (unsigned int)Param.Para64);
|
|
|
+ (void)SK_DRIVER_SENDEVENT(pAC, IoC);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_EVT_SEN_WAR_UPP:
|
|
|
+#ifdef DEBUG
|
|
|
+ if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
|
|
|
+
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
|
|
|
+ ("PNMI: ERR:SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n",
|
|
|
+ (unsigned int)Param.Para64));
|
|
|
+ return (0);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ /*
|
|
|
+ * Store a trap message in the trap buffer and generate
|
|
|
+ * an event for user space applications with the
|
|
|
+ * SK_DRIVER_SENDEVENT macro.
|
|
|
+ */
|
|
|
+ QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP,
|
|
|
+ (unsigned int)Param.Para64);
|
|
|
+ (void)SK_DRIVER_SENDEVENT(pAC, IoC);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_EVT_SEN_ERR_LOW:
|
|
|
+#ifdef DEBUG
|
|
|
+ if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
|
|
|
+
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
|
|
|
+ ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n",
|
|
|
+ (unsigned int)Param.Para64));
|
|
|
+ return (0);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ /*
|
|
|
+ * Store a trap message in the trap buffer and generate
|
|
|
+ * an event for user space applications with the
|
|
|
+ * SK_DRIVER_SENDEVENT macro.
|
|
|
+ */
|
|
|
+ QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW,
|
|
|
+ (unsigned int)Param.Para64);
|
|
|
+ (void)SK_DRIVER_SENDEVENT(pAC, IoC);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_EVT_SEN_ERR_UPP:
|
|
|
+#ifdef DEBUG
|
|
|
+ if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
|
|
|
+
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
|
|
|
+ ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
|
|
|
+ (unsigned int)Param.Para64));
|
|
|
+ return (0);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ /*
|
|
|
+ * Store a trap message in the trap buffer and generate
|
|
|
+ * an event for user space applications with the
|
|
|
+ * SK_DRIVER_SENDEVENT macro.
|
|
|
+ */
|
|
|
+ QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP,
|
|
|
+ (unsigned int)Param.Para64);
|
|
|
+ (void)SK_DRIVER_SENDEVENT(pAC, IoC);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_EVT_CHG_EST_TIMER:
|
|
|
+ /*
|
|
|
+ * Calculate port switch average on a per hour basis
|
|
|
+ * Time interval for check : 28125 ms
|
|
|
+ * Number of values for average : 8
|
|
|
+ *
|
|
|
+ * Be careful in changing these values, on change check
|
|
|
+ * - typedef of SK_PNMI_ESTIMATE (Size of EstValue
|
|
|
+ * array one less than value number)
|
|
|
+ * - Timer initilization SkTimerStart() in SkPnmiInit
|
|
|
+ * - Delta value below must be multiplicated with
|
|
|
+ * power of 2
|
|
|
+ *
|
|
|
+ */
|
|
|
+ pEst = &pAC->Pnmi.RlmtChangeEstimate;
|
|
|
+ CounterIndex = pEst->EstValueIndex + 1;
|
|
|
+ if (CounterIndex == 7) {
|
|
|
+
|
|
|
+ CounterIndex = 0;
|
|
|
+ }
|
|
|
+ pEst->EstValueIndex = CounterIndex;
|
|
|
+
|
|
|
+ NewestValue = pAC->Pnmi.RlmtChangeCts;
|
|
|
+ OldestValue = pEst->EstValue[CounterIndex];
|
|
|
+ pEst->EstValue[CounterIndex] = NewestValue;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Calculate average. Delta stores the number of
|
|
|
+ * port switches per 28125 * 8 = 225000 ms
|
|
|
+ */
|
|
|
+ if (NewestValue >= OldestValue) {
|
|
|
+
|
|
|
+ Delta = NewestValue - OldestValue;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Overflow situation */
|
|
|
+ Delta = (SK_U64)(0 - OldestValue) + NewestValue;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Extrapolate delta to port switches per hour.
|
|
|
+ * Estimate = Delta * (3600000 / 225000)
|
|
|
+ * = Delta * 16
|
|
|
+ * = Delta << 4
|
|
|
+ */
|
|
|
+ pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check if threshold is exceeded. If the threshold is
|
|
|
+ * permanently exceeded every 28125 ms an event will be
|
|
|
+ * generated to remind the user of this condition.
|
|
|
+ */
|
|
|
+ if ((pAC->Pnmi.RlmtChangeThreshold != 0) &&
|
|
|
+ (pAC->Pnmi.RlmtChangeEstimate.Estimate >=
|
|
|
+ pAC->Pnmi.RlmtChangeThreshold)) {
|
|
|
+
|
|
|
+ QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES);
|
|
|
+ (void)SK_DRIVER_SENDEVENT(pAC, IoC);
|
|
|
+ }
|
|
|
+
|
|
|
+ SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
|
|
|
+ SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
|
|
|
+ 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
|
|
|
+ EventParam);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_EVT_CLEAR_COUNTER:
|
|
|
+ /*
|
|
|
+ * Param.Para32[0] contains the NetIndex (0 ..1).
|
|
|
+ * Param.Para32[1] is reserved, contains -1.
|
|
|
+ */
|
|
|
+ NetIndex = (SK_U32)Param.Para32[0];
|
|
|
+
|
|
|
+#ifdef DEBUG
|
|
|
+ if (NetIndex >= pAC->Rlmt.NumNets) {
|
|
|
+
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
|
|
|
+ ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
|
|
|
+ NetIndex));
|
|
|
+
|
|
|
+ return (0);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Set all counters and timestamps to zero
|
|
|
+ */
|
|
|
+ ResetCounter(pAC, IoC, NetIndex); /* the according NetIndex is required
|
|
|
+ as a Parameter of the Event */
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_EVT_XMAC_RESET:
|
|
|
+ /*
|
|
|
+ * To grant continuous counter values store the current
|
|
|
+ * XMAC statistic values to the entries 1..n of the
|
|
|
+ * CounterOffset array. XMAC Errata #2
|
|
|
+ */
|
|
|
+#ifdef DEBUG
|
|
|
+ if ((unsigned int)Param.Para64 >= SK_MAX_MACS) {
|
|
|
+
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
|
|
|
+ ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n",
|
|
|
+ (unsigned int)Param.Para64));
|
|
|
+ return (0);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ PhysPortIndex = (unsigned int)Param.Para64;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Update XMAC statistic to get fresh values
|
|
|
+ */
|
|
|
+ Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
|
|
|
+ if (Ret != SK_PNMI_ERR_OK) {
|
|
|
+
|
|
|
+ SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
|
|
|
+ return (0);
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ * Increment semaphore to indicate that an update was
|
|
|
+ * already done
|
|
|
+ */
|
|
|
+ pAC->Pnmi.MacUpdatedFlag ++;
|
|
|
+
|
|
|
+ for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
|
|
|
+ CounterIndex ++) {
|
|
|
+
|
|
|
+ if (!StatAddr[CounterIndex][MacType].GetOffset) {
|
|
|
+
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ pAC->Pnmi.Port[PhysPortIndex].
|
|
|
+ CounterOffset[CounterIndex] = GetPhysStatVal(
|
|
|
+ pAC, IoC, PhysPortIndex, CounterIndex);
|
|
|
+ pAC->Pnmi.Port[PhysPortIndex].
|
|
|
+ CounterHigh[CounterIndex] = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ pAC->Pnmi.MacUpdatedFlag --;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_EVT_RLMT_PORT_UP:
|
|
|
+ PhysPortIndex = (unsigned int)Param.Para32[0];
|
|
|
+#ifdef DEBUG
|
|
|
+ if (PhysPortIndex >= SK_MAX_MACS) {
|
|
|
+
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
|
|
|
+ ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter"
|
|
|
+ " wrong, PhysPortIndex=%d\n", PhysPortIndex));
|
|
|
+
|
|
|
+ return (0);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ /*
|
|
|
+ * Store a trap message in the trap buffer and generate an event for
|
|
|
+ * user space applications with the SK_DRIVER_SENDEVENT macro.
|
|
|
+ */
|
|
|
+ QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
|
|
|
+ (void)SK_DRIVER_SENDEVENT(pAC, IoC);
|
|
|
+
|
|
|
+ /* Bugfix for XMAC errata (#10620)*/
|
|
|
+ if (pAC->GIni.GIMacType == SK_MAC_XMAC){
|
|
|
+
|
|
|
+ /* Add incremental difference to offset (#10620)*/
|
|
|
+ (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
|
|
|
+ XM_RXE_SHT_ERR, &Val32);
|
|
|
+
|
|
|
+ Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
|
|
|
+ CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
|
|
|
+ pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
|
|
|
+ Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Tell VctStatus() that a link was up meanwhile. */
|
|
|
+ pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_EVT_RLMT_PORT_DOWN:
|
|
|
+ PhysPortIndex = (unsigned int)Param.Para32[0];
|
|
|
+
|
|
|
+#ifdef DEBUG
|
|
|
+ if (PhysPortIndex >= SK_MAX_MACS) {
|
|
|
+
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
|
|
|
+ ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter"
|
|
|
+ " wrong, PhysPortIndex=%d\n", PhysPortIndex));
|
|
|
+
|
|
|
+ return (0);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ /*
|
|
|
+ * Store a trap message in the trap buffer and generate an event for
|
|
|
+ * user space applications with the SK_DRIVER_SENDEVENT macro.
|
|
|
+ */
|
|
|
+ QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
|
|
|
+ (void)SK_DRIVER_SENDEVENT(pAC, IoC);
|
|
|
+
|
|
|
+ /* Bugfix #10620 - get zero level for incremental difference */
|
|
|
+ if ((pAC->GIni.GIMacType == SK_MAC_XMAC)) {
|
|
|
+
|
|
|
+ (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
|
|
|
+ XM_RXE_SHT_ERR, &Val32);
|
|
|
+ pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark =
|
|
|
+ (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
|
|
|
+ CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
|
|
|
+ PhysPortIndex = (unsigned int)Param.Para32[0];
|
|
|
+ NetIndex = (SK_U32)Param.Para32[1];
|
|
|
+
|
|
|
+#ifdef DEBUG
|
|
|
+ if (PhysPortIndex >= SK_MAX_MACS) {
|
|
|
+
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
|
|
|
+ ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
|
|
|
+ PhysPortIndex));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (NetIndex >= pAC->Rlmt.NumNets) {
|
|
|
+
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
|
|
|
+ ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
|
|
|
+ NetIndex));
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ /*
|
|
|
+ * For now, ignore event if NetIndex != 0.
|
|
|
+ */
|
|
|
+ if (Param.Para32[1] != 0) {
|
|
|
+
|
|
|
+ return (0);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Nothing to do if port is already inactive
|
|
|
+ */
|
|
|
+ if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
|
|
|
+
|
|
|
+ return (0);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Update statistic counters to calculate new offset for the virtual
|
|
|
+ * port and increment semaphore to indicate that an update was already
|
|
|
+ * done.
|
|
|
+ */
|
|
|
+ if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
|
|
|
+ SK_PNMI_ERR_OK) {
|
|
|
+
|
|
|
+ SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
|
|
|
+ return (0);
|
|
|
+ }
|
|
|
+ pAC->Pnmi.MacUpdatedFlag ++;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Calculate new counter offset for virtual port to grant continous
|
|
|
+ * counting on port switches. The virtual port consists of all currently
|
|
|
+ * active ports. The port down event indicates that a port is removed
|
|
|
+ * from the virtual port. Therefore add the counter value of the removed
|
|
|
+ * port to the CounterOffset for the virtual port to grant the same
|
|
|
+ * counter value.
|
|
|
+ */
|
|
|
+ for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
|
|
|
+ CounterIndex ++) {
|
|
|
+
|
|
|
+ if (!StatAddr[CounterIndex][MacType].GetOffset) {
|
|
|
+
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
|
|
|
+
|
|
|
+ pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Set port to inactive
|
|
|
+ */
|
|
|
+ pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
|
|
|
+
|
|
|
+ pAC->Pnmi.MacUpdatedFlag --;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_EVT_RLMT_ACTIVE_UP:
|
|
|
+ PhysPortIndex = (unsigned int)Param.Para32[0];
|
|
|
+ NetIndex = (SK_U32)Param.Para32[1];
|
|
|
+
|
|
|
+#ifdef DEBUG
|
|
|
+ if (PhysPortIndex >= SK_MAX_MACS) {
|
|
|
+
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
|
|
|
+ ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
|
|
|
+ PhysPortIndex));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (NetIndex >= pAC->Rlmt.NumNets) {
|
|
|
+
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
|
|
|
+ ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
|
|
|
+ NetIndex));
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ /*
|
|
|
+ * For now, ignore event if NetIndex != 0.
|
|
|
+ */
|
|
|
+ if (Param.Para32[1] != 0) {
|
|
|
+
|
|
|
+ return (0);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Nothing to do if port is already active
|
|
|
+ */
|
|
|
+ if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
|
|
|
+
|
|
|
+ return (0);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Statistic maintenance
|
|
|
+ */
|
|
|
+ pAC->Pnmi.RlmtChangeCts ++;
|
|
|
+ pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Store a trap message in the trap buffer and generate an event for
|
|
|
+ * user space applications with the SK_DRIVER_SENDEVENT macro.
|
|
|
+ */
|
|
|
+ QueueRlmtNewMacTrap(pAC, PhysPortIndex);
|
|
|
+ (void)SK_DRIVER_SENDEVENT(pAC, IoC);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Update statistic counters to calculate new offset for the virtual
|
|
|
+ * port and increment semaphore to indicate that an update was
|
|
|
+ * already done.
|
|
|
+ */
|
|
|
+ if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
|
|
|
+ SK_PNMI_ERR_OK) {
|
|
|
+
|
|
|
+ SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
|
|
|
+ return (0);
|
|
|
+ }
|
|
|
+ pAC->Pnmi.MacUpdatedFlag ++;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Calculate new counter offset for virtual port to grant continous
|
|
|
+ * counting on port switches. A new port is added to the virtual port.
|
|
|
+ * Therefore substract the counter value of the new port from the
|
|
|
+ * CounterOffset for the virtual port to grant the same value.
|
|
|
+ */
|
|
|
+ for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
|
|
|
+ CounterIndex ++) {
|
|
|
+
|
|
|
+ if (!StatAddr[CounterIndex][MacType].GetOffset) {
|
|
|
+
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
|
|
|
+
|
|
|
+ pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Set port to active
|
|
|
+ */
|
|
|
+ pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
|
|
|
+
|
|
|
+ pAC->Pnmi.MacUpdatedFlag --;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_EVT_RLMT_SEGMENTATION:
|
|
|
+ /*
|
|
|
+ * Para.Para32[0] contains the NetIndex.
|
|
|
+ */
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Store a trap message in the trap buffer and generate an event for
|
|
|
+ * user space applications with the SK_DRIVER_SENDEVENT macro.
|
|
|
+ */
|
|
|
+ QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
|
|
|
+ (void)SK_DRIVER_SENDEVENT(pAC, IoC);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_EVT_RLMT_SET_NETS:
|
|
|
+ /*
|
|
|
+ * Param.Para32[0] contains the number of Nets.
|
|
|
+ * Param.Para32[1] is reserved, contains -1.
|
|
|
+ */
|
|
|
+ /*
|
|
|
+ * Check number of nets
|
|
|
+ */
|
|
|
+ MaxNetNumber = pAC->GIni.GIMacsFound;
|
|
|
+ if (((unsigned int)Param.Para32[0] < 1)
|
|
|
+ || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
|
|
|
+ return (SK_PNMI_ERR_UNKNOWN_NET);
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
|
|
|
+ pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
|
|
|
+ }
|
|
|
+ else { /* dual net mode */
|
|
|
+ pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_EVT_VCT_RESET:
|
|
|
+ PhysPortIndex = Param.Para32[0];
|
|
|
+ pPrt = &pAC->GIni.GP[PhysPortIndex];
|
|
|
+ pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
|
|
|
+
|
|
|
+ if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
|
|
|
+ RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
|
|
|
+ if (RetCode == 2) {
|
|
|
+ /*
|
|
|
+ * VCT test is still running.
|
|
|
+ * Start VCT timer counter again.
|
|
|
+ */
|
|
|
+ SK_MEMSET((char *) &Param, 0, sizeof(Param));
|
|
|
+ Param.Para32[0] = PhysPortIndex;
|
|
|
+ Param.Para32[1] = -1;
|
|
|
+ SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
|
|
|
+ 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
|
|
|
+ pAC->Pnmi.VctStatus[PhysPortIndex] |=
|
|
|
+ (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
|
|
|
+
|
|
|
+ /* Copy results for later use to PNMI struct. */
|
|
|
+ for (i = 0; i < 4; i++) {
|
|
|
+ if (pPrt->PMdiPairLen[i] > 35) {
|
|
|
+ CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ CableLength = 0;
|
|
|
+ }
|
|
|
+ pVctBackupData->PMdiPairLen[i] = CableLength;
|
|
|
+ pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
|
|
|
+ }
|
|
|
+
|
|
|
+ Param.Para32[0] = PhysPortIndex;
|
|
|
+ Param.Para32[1] = -1;
|
|
|
+ SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
|
|
|
+ SkEventDispatcher(pAC, IoC);
|
|
|
+ }
|
|
|
+
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
|
|
|
+ return (0);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/******************************************************************************
|
|
|
+ *
|
|
|
+ * Private functions
|
|
|
+ *
|
|
|
+ */
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * PnmiVar - Gets, presets, and sets single OIDs
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Looks up the requested OID, calls the corresponding handler
|
|
|
+ * function, and passes the parameters with the get, preset, or
|
|
|
+ * set command. The function is called by SkGePnmiGetVar,
|
|
|
+ * SkGePnmiPreSetVar, or SkGePnmiSetVar.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_XXX. For details have a look to the description of the
|
|
|
+ * calling functions.
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
|
|
|
+ */
|
|
|
+PNMI_STATIC int PnmiVar(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+int Action, /* Get/PreSet/Set action */
|
|
|
+SK_U32 Id, /* Object ID that is to be processed */
|
|
|
+char *pBuf, /* Buffer which stores the mgmt data to be set */
|
|
|
+unsigned int *pLen, /* Total length of mgmt data */
|
|
|
+SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+ unsigned int TableIndex;
|
|
|
+ int Ret;
|
|
|
+
|
|
|
+
|
|
|
+ if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_UNKNOWN_OID);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check NetIndex
|
|
|
+ */
|
|
|
+ if (NetIndex >= pAC->Rlmt.NumNets) {
|
|
|
+ return (SK_PNMI_ERR_UNKNOWN_NET);
|
|
|
+ }
|
|
|
+
|
|
|
+ SK_PNMI_CHECKFLAGS("PnmiVar: On call");
|
|
|
+
|
|
|
+ Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
|
|
|
+ Instance, TableIndex, NetIndex);
|
|
|
+
|
|
|
+ SK_PNMI_CHECKFLAGS("PnmiVar: On return");
|
|
|
+
|
|
|
+ return (Ret);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * The return value of the function will also be stored in
|
|
|
+ * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
|
|
|
+ * SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable,
|
|
|
+ * checks which OIDs are able to set, and calls the handler function of
|
|
|
+ * the OID to perform the set. The return value of the function will
|
|
|
+ * also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
|
|
|
+ * minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called
|
|
|
+ * by SkGePnmiPreSetStruct and SkGePnmiSetStruct.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_XXX. The codes are described in the calling functions.
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
|
|
|
+ */
|
|
|
+PNMI_STATIC int PnmiStruct(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+int Action, /* Set action to be performed */
|
|
|
+char *pBuf, /* Buffer which contains the data to be set */
|
|
|
+unsigned int *pLen, /* Length of buffer */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+ int Ret;
|
|
|
+ unsigned int TableIndex;
|
|
|
+ unsigned int DstOffset;
|
|
|
+ unsigned int Len;
|
|
|
+ unsigned int InstanceNo;
|
|
|
+ unsigned int InstanceCnt;
|
|
|
+ SK_U32 Instance;
|
|
|
+ SK_U32 Id;
|
|
|
+
|
|
|
+
|
|
|
+ /* Check if the passed buffer has the right size */
|
|
|
+ if (*pLen < SK_PNMI_STRUCT_SIZE) {
|
|
|
+
|
|
|
+ /* Check if we can return the error within the buffer */
|
|
|
+ if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
|
|
|
+
|
|
|
+ SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
|
|
|
+ (SK_U32)(-1));
|
|
|
+ }
|
|
|
+
|
|
|
+ *pLen = SK_PNMI_STRUCT_SIZE;
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check NetIndex
|
|
|
+ */
|
|
|
+ if (NetIndex >= pAC->Rlmt.NumNets) {
|
|
|
+ return (SK_PNMI_ERR_UNKNOWN_NET);
|
|
|
+ }
|
|
|
+
|
|
|
+ SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Update the values of RLMT and SIRQ and increment semaphores to
|
|
|
+ * indicate that an update was already done.
|
|
|
+ */
|
|
|
+ if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
|
|
|
+
|
|
|
+ SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
|
|
|
+ *pLen = SK_PNMI_MIN_STRUCT_SIZE;
|
|
|
+ return (Ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
|
|
|
+
|
|
|
+ SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
|
|
|
+ *pLen = SK_PNMI_MIN_STRUCT_SIZE;
|
|
|
+ return (Ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ pAC->Pnmi.RlmtUpdatedFlag ++;
|
|
|
+ pAC->Pnmi.SirqUpdatedFlag ++;
|
|
|
+
|
|
|
+ /* Preset/Set values */
|
|
|
+ for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
|
|
|
+
|
|
|
+ if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
|
|
|
+ (IdTable[TableIndex].Access != SK_PNMI_WO)) {
|
|
|
+
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ InstanceNo = IdTable[TableIndex].InstanceNo;
|
|
|
+ Id = IdTable[TableIndex].Id;
|
|
|
+
|
|
|
+ for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
|
|
|
+ InstanceCnt ++) {
|
|
|
+
|
|
|
+ DstOffset = IdTable[TableIndex].Offset +
|
|
|
+ (InstanceCnt - 1) *
|
|
|
+ IdTable[TableIndex].StructSize;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Because VPD multiple instance variables are
|
|
|
+ * not setable we do not need to evaluate VPD
|
|
|
+ * instances. Have a look to VPD instance
|
|
|
+ * calculation in SkPnmiGetStruct().
|
|
|
+ */
|
|
|
+ Instance = (SK_U32)InstanceCnt;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Evaluate needed buffer length
|
|
|
+ */
|
|
|
+ Len = 0;
|
|
|
+ Ret = IdTable[TableIndex].Func(pAC, IoC,
|
|
|
+ SK_PNMI_GET, IdTable[TableIndex].Id,
|
|
|
+ NULL, &Len, Instance, TableIndex, NetIndex);
|
|
|
+
|
|
|
+ if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (Ret != SK_PNMI_ERR_TOO_SHORT) {
|
|
|
+
|
|
|
+ pAC->Pnmi.RlmtUpdatedFlag --;
|
|
|
+ pAC->Pnmi.SirqUpdatedFlag --;
|
|
|
+
|
|
|
+ SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
|
|
|
+ SK_PNMI_SET_STAT(pBuf,
|
|
|
+ SK_PNMI_ERR_GENERAL, DstOffset);
|
|
|
+ *pLen = SK_PNMI_MIN_STRUCT_SIZE;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ if (Id == OID_SKGE_VPD_ACTION) {
|
|
|
+
|
|
|
+ switch (*(pBuf + DstOffset)) {
|
|
|
+
|
|
|
+ case SK_PNMI_VPD_CREATE:
|
|
|
+ Len = 3 + *(pBuf + DstOffset + 3);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_VPD_DELETE:
|
|
|
+ Len = 3;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ Len = 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Call the OID handler function */
|
|
|
+ Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
|
|
|
+ IdTable[TableIndex].Id, pBuf + DstOffset,
|
|
|
+ &Len, Instance, TableIndex, NetIndex);
|
|
|
+
|
|
|
+ if (Ret != SK_PNMI_ERR_OK) {
|
|
|
+
|
|
|
+ pAC->Pnmi.RlmtUpdatedFlag --;
|
|
|
+ pAC->Pnmi.SirqUpdatedFlag --;
|
|
|
+
|
|
|
+ SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
|
|
|
+ SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
|
|
|
+ DstOffset);
|
|
|
+ *pLen = SK_PNMI_MIN_STRUCT_SIZE;
|
|
|
+ return (SK_PNMI_ERR_BAD_VALUE);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ pAC->Pnmi.RlmtUpdatedFlag --;
|
|
|
+ pAC->Pnmi.SirqUpdatedFlag --;
|
|
|
+
|
|
|
+ SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
|
|
|
+ SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * LookupId - Lookup an OID in the IdTable
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Scans the IdTable to find the table entry of an OID.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * The table index or -1 if not found.
|
|
|
+ */
|
|
|
+PNMI_STATIC int LookupId(
|
|
|
+SK_U32 Id) /* Object identifier to be searched */
|
|
|
+{
|
|
|
+ int i;
|
|
|
+
|
|
|
+ for (i = 0; i < ID_TABLE_SIZE; i++) {
|
|
|
+
|
|
|
+ if (IdTable[i].Id == Id) {
|
|
|
+
|
|
|
+ return i;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (-1);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * OidStruct - Handler of OID_SKGE_ALL_DATA
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * This OID performs a Get/Preset/SetStruct call and returns all data
|
|
|
+ * in a SK_PNMI_STRUCT_DATA structure.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK The request was successfully performed.
|
|
|
+ * SK_PNMI_ERR_GENERAL A general severe internal error occured.
|
|
|
+ * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
|
|
|
+ * the correct data (e.g. a 32bit value is
|
|
|
+ * needed, but a 16 bit value was passed).
|
|
|
+ * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
|
|
|
+ * value range.
|
|
|
+ * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
|
|
|
+ * exist (e.g. port instance 3 on a two port
|
|
|
+ * adapter.
|
|
|
+ */
|
|
|
+PNMI_STATIC int OidStruct(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+int Action, /* Get/PreSet/Set action */
|
|
|
+SK_U32 Id, /* Object ID that is to be processed */
|
|
|
+char *pBuf, /* Buffer to which to mgmt data will be retrieved */
|
|
|
+unsigned int *pLen, /* On call: buffer length. On return: used buffer */
|
|
|
+SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
|
|
|
+unsigned int TableIndex, /* Index to the Id table */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+ if (Id != OID_SKGE_ALL_DATA) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
|
|
|
+ SK_PNMI_ERR003MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check instance. We only handle single instance variables
|
|
|
+ */
|
|
|
+ if (Instance != (SK_U32)(-1) && Instance != 1) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_UNKNOWN_INST);
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (Action) {
|
|
|
+
|
|
|
+ case SK_PNMI_GET:
|
|
|
+ return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
|
|
|
+
|
|
|
+ case SK_PNMI_PRESET:
|
|
|
+ return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
|
|
|
+
|
|
|
+ case SK_PNMI_SET:
|
|
|
+ return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
|
|
|
+ }
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * Perform - OID handler of OID_SKGE_ACTION
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * None.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK The request was successfully performed.
|
|
|
+ * SK_PNMI_ERR_GENERAL A general severe internal error occured.
|
|
|
+ * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
|
|
|
+ * the correct data (e.g. a 32bit value is
|
|
|
+ * needed, but a 16 bit value was passed).
|
|
|
+ * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
|
|
|
+ * value range.
|
|
|
+ * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
|
|
|
+ * exist (e.g. port instance 3 on a two port
|
|
|
+ * adapter.
|
|
|
+ */
|
|
|
+PNMI_STATIC int Perform(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+int Action, /* Get/PreSet/Set action */
|
|
|
+SK_U32 Id, /* Object ID that is to be processed */
|
|
|
+char *pBuf, /* Buffer to which to mgmt data will be retrieved */
|
|
|
+unsigned int *pLen, /* On call: buffer length. On return: used buffer */
|
|
|
+SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
|
|
|
+unsigned int TableIndex, /* Index to the Id table */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+ int Ret;
|
|
|
+ SK_U32 ActionOp;
|
|
|
+
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check instance. We only handle single instance variables
|
|
|
+ */
|
|
|
+ if (Instance != (SK_U32)(-1) && Instance != 1) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_UNKNOWN_INST);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (*pLen < sizeof(SK_U32)) {
|
|
|
+
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Check if a get should be performed */
|
|
|
+ if (Action == SK_PNMI_GET) {
|
|
|
+
|
|
|
+ /* A get is easy. We always return the same value */
|
|
|
+ ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
|
|
|
+ SK_PNMI_STORE_U32(pBuf, ActionOp);
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Continue with PRESET/SET action */
|
|
|
+ if (*pLen > sizeof(SK_U32)) {
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_BAD_VALUE);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Check if the command is a known one */
|
|
|
+ SK_PNMI_READ_U32(pBuf, ActionOp);
|
|
|
+ if (*pLen > sizeof(SK_U32) ||
|
|
|
+ (ActionOp != SK_PNMI_ACT_IDLE &&
|
|
|
+ ActionOp != SK_PNMI_ACT_RESET &&
|
|
|
+ ActionOp != SK_PNMI_ACT_SELFTEST &&
|
|
|
+ ActionOp != SK_PNMI_ACT_RESETCNT)) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_BAD_VALUE);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* A preset ends here */
|
|
|
+ if (Action == SK_PNMI_PRESET) {
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (ActionOp) {
|
|
|
+
|
|
|
+ case SK_PNMI_ACT_IDLE:
|
|
|
+ /* Nothing to do */
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_ACT_RESET:
|
|
|
+ /*
|
|
|
+ * Perform a driver reset or something that comes near
|
|
|
+ * to this.
|
|
|
+ */
|
|
|
+ Ret = SK_DRIVER_RESET(pAC, IoC);
|
|
|
+ if (Ret != 0) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
|
|
|
+ SK_PNMI_ERR005MSG);
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_ACT_SELFTEST:
|
|
|
+ /*
|
|
|
+ * Perform a driver selftest or something similar to this.
|
|
|
+ * Currently this feature is not used and will probably
|
|
|
+ * implemented in another way.
|
|
|
+ */
|
|
|
+ Ret = SK_DRIVER_SELFTEST(pAC, IoC);
|
|
|
+ pAC->Pnmi.TestResult = Ret;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_ACT_RESETCNT:
|
|
|
+ /* Set all counters and timestamps to zero */
|
|
|
+ ResetCounter(pAC, IoC, NetIndex);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
|
|
|
+ SK_PNMI_ERR006MSG);
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Retrieves the statistic values of the virtual port (logical
|
|
|
+ * index 0). Only special OIDs of NDIS are handled which consist
|
|
|
+ * of a 32 bit instead of a 64 bit value. The OIDs are public
|
|
|
+ * because perhaps some other platform can use them too.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK The request was successfully performed.
|
|
|
+ * SK_PNMI_ERR_GENERAL A general severe internal error occured.
|
|
|
+ * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
|
|
|
+ * the correct data (e.g. a 32bit value is
|
|
|
+ * needed, but a 16 bit value was passed).
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
|
|
|
+ * exist (e.g. port instance 3 on a two port
|
|
|
+ * adapter.
|
|
|
+ */
|
|
|
+PNMI_STATIC int Mac8023Stat(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+int Action, /* Get/PreSet/Set action */
|
|
|
+SK_U32 Id, /* Object ID that is to be processed */
|
|
|
+char *pBuf, /* Buffer to which to mgmt data will be retrieved */
|
|
|
+unsigned int *pLen, /* On call: buffer length. On return: used buffer */
|
|
|
+SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
|
|
|
+unsigned int TableIndex, /* Index to the Id table */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+ int Ret;
|
|
|
+ SK_U64 StatVal;
|
|
|
+ SK_U32 StatVal32;
|
|
|
+ SK_BOOL Is64BitReq = SK_FALSE;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Only the active Mac is returned
|
|
|
+ */
|
|
|
+ if (Instance != (SK_U32)(-1) && Instance != 1) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_UNKNOWN_INST);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check action type
|
|
|
+ */
|
|
|
+ if (Action != SK_PNMI_GET) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_READ_ONLY);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check length
|
|
|
+ */
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_802_3_PERMANENT_ADDRESS:
|
|
|
+ case OID_802_3_CURRENT_ADDRESS:
|
|
|
+ if (*pLen < sizeof(SK_MAC_ADDR)) {
|
|
|
+
|
|
|
+ *pLen = sizeof(SK_MAC_ADDR);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+#ifndef SK_NDIS_64BIT_CTR
|
|
|
+ if (*pLen < sizeof(SK_U32)) {
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+
|
|
|
+#else /* SK_NDIS_64BIT_CTR */
|
|
|
+
|
|
|
+ /*
|
|
|
+ * for compatibility, at least 32bit are required for oid
|
|
|
+ */
|
|
|
+ if (*pLen < sizeof(SK_U32)) {
|
|
|
+ /*
|
|
|
+ * but indicate handling for 64bit values,
|
|
|
+ * if insufficient space is provided
|
|
|
+ */
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+
|
|
|
+ Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
|
|
|
+#endif /* SK_NDIS_64BIT_CTR */
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Update all statistics, because we retrieve virtual MAC, which
|
|
|
+ * consists of multiple physical statistics and increment semaphore
|
|
|
+ * to indicate that an update was already done.
|
|
|
+ */
|
|
|
+ Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
|
|
|
+ if ( Ret != SK_PNMI_ERR_OK) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (Ret);
|
|
|
+ }
|
|
|
+ pAC->Pnmi.MacUpdatedFlag ++;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get value (MAC Index 0 identifies the virtual MAC)
|
|
|
+ */
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_802_3_PERMANENT_ADDRESS:
|
|
|
+ CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
|
|
|
+ *pLen = sizeof(SK_MAC_ADDR);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_802_3_CURRENT_ADDRESS:
|
|
|
+ CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
|
|
|
+ *pLen = sizeof(SK_MAC_ADDR);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * by default 32bit values are evaluated
|
|
|
+ */
|
|
|
+ if (!Is64BitReq) {
|
|
|
+ StatVal32 = (SK_U32)StatVal;
|
|
|
+ SK_PNMI_STORE_U32(pBuf, StatVal32);
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ SK_PNMI_STORE_U64(pBuf, StatVal);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ pAC->Pnmi.MacUpdatedFlag --;
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Retrieves the XMAC statistic data.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK The request was successfully performed.
|
|
|
+ * SK_PNMI_ERR_GENERAL A general severe internal error occured.
|
|
|
+ * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
|
|
|
+ * the correct data (e.g. a 32bit value is
|
|
|
+ * needed, but a 16 bit value was passed).
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
|
|
|
+ * exist (e.g. port instance 3 on a two port
|
|
|
+ * adapter.
|
|
|
+ */
|
|
|
+PNMI_STATIC int MacPrivateStat(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+int Action, /* Get/PreSet/Set action */
|
|
|
+SK_U32 Id, /* Object ID that is to be processed */
|
|
|
+char *pBuf, /* Buffer to which to mgmt data will be retrieved */
|
|
|
+unsigned int *pLen, /* On call: buffer length. On return: used buffer */
|
|
|
+SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
|
|
|
+unsigned int TableIndex, /* Index to the Id table */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+ unsigned int LogPortMax;
|
|
|
+ unsigned int LogPortIndex;
|
|
|
+ unsigned int PhysPortMax;
|
|
|
+ unsigned int Limit;
|
|
|
+ unsigned int Offset;
|
|
|
+ int Ret;
|
|
|
+ SK_U64 StatVal;
|
|
|
+
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Calculate instance if wished. MAC index 0 is the virtual
|
|
|
+ * MAC.
|
|
|
+ */
|
|
|
+ PhysPortMax = pAC->GIni.GIMacsFound;
|
|
|
+ LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
|
|
|
+
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
|
|
|
+ LogPortMax--;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
|
|
|
+ /* Check instance range */
|
|
|
+ if ((Instance < 1) || (Instance > LogPortMax)) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_UNKNOWN_INST);
|
|
|
+ }
|
|
|
+ LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
|
|
|
+ Limit = LogPortIndex + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
|
|
|
+
|
|
|
+ LogPortIndex = 0;
|
|
|
+ Limit = LogPortMax;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check action
|
|
|
+ */
|
|
|
+ if (Action != SK_PNMI_GET) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_READ_ONLY);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check length
|
|
|
+ */
|
|
|
+ if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
|
|
|
+
|
|
|
+ *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Update XMAC statistic and increment semaphore to indicate that
|
|
|
+ * an update was already done.
|
|
|
+ */
|
|
|
+ Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
|
|
|
+ if (Ret != SK_PNMI_ERR_OK) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (Ret);
|
|
|
+ }
|
|
|
+ pAC->Pnmi.MacUpdatedFlag ++;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get value
|
|
|
+ */
|
|
|
+ Offset = 0;
|
|
|
+ for (; LogPortIndex < Limit; LogPortIndex ++) {
|
|
|
+
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+/* XXX not yet implemented due to XMAC problems
|
|
|
+ case OID_SKGE_STAT_TX_UTIL:
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+*/
|
|
|
+/* XXX not yet implemented due to XMAC problems
|
|
|
+ case OID_SKGE_STAT_RX_UTIL:
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+*/
|
|
|
+ case OID_SKGE_STAT_RX:
|
|
|
+ case OID_SKGE_STAT_TX:
|
|
|
+ switch (pAC->GIni.GIMacType) {
|
|
|
+ case SK_MAC_XMAC:
|
|
|
+ StatVal = GetStatVal(pAC, IoC, LogPortIndex,
|
|
|
+ IdTable[TableIndex].Param, NetIndex);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_MAC_GMAC:
|
|
|
+ if (Id == OID_SKGE_STAT_TX) {
|
|
|
+
|
|
|
+ StatVal =
|
|
|
+ GetStatVal(pAC, IoC, LogPortIndex,
|
|
|
+ SK_PNMI_HTX_BROADCAST, NetIndex) +
|
|
|
+ GetStatVal(pAC, IoC, LogPortIndex,
|
|
|
+ SK_PNMI_HTX_MULTICAST, NetIndex) +
|
|
|
+ GetStatVal(pAC, IoC, LogPortIndex,
|
|
|
+ SK_PNMI_HTX_UNICAST, NetIndex);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ StatVal =
|
|
|
+ GetStatVal(pAC, IoC, LogPortIndex,
|
|
|
+ SK_PNMI_HRX_BROADCAST, NetIndex) +
|
|
|
+ GetStatVal(pAC, IoC, LogPortIndex,
|
|
|
+ SK_PNMI_HRX_MULTICAST, NetIndex) +
|
|
|
+ GetStatVal(pAC, IoC, LogPortIndex,
|
|
|
+ SK_PNMI_HRX_UNICAST, NetIndex) +
|
|
|
+ GetStatVal(pAC, IoC, LogPortIndex,
|
|
|
+ SK_PNMI_HRX_UNDERSIZE, NetIndex);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ StatVal = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ StatVal = GetStatVal(pAC, IoC, LogPortIndex,
|
|
|
+ IdTable[TableIndex].Param, NetIndex);
|
|
|
+ SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ Offset += sizeof(SK_U64);
|
|
|
+ }
|
|
|
+ *pLen = Offset;
|
|
|
+
|
|
|
+ pAC->Pnmi.MacUpdatedFlag --;
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Get/Presets/Sets the current and factory MAC address. The MAC
|
|
|
+ * address of the virtual port, which is reported to the OS, may
|
|
|
+ * not be changed, but the physical ones. A set to the virtual port
|
|
|
+ * will be ignored. No error should be reported because otherwise
|
|
|
+ * a multiple instance set (-1) would always fail.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK The request was successfully performed.
|
|
|
+ * SK_PNMI_ERR_GENERAL A general severe internal error occured.
|
|
|
+ * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
|
|
|
+ * the correct data (e.g. a 32bit value is
|
|
|
+ * needed, but a 16 bit value was passed).
|
|
|
+ * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
|
|
|
+ * value range.
|
|
|
+ * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
|
|
|
+ * exist (e.g. port instance 3 on a two port
|
|
|
+ * adapter.
|
|
|
+ */
|
|
|
+PNMI_STATIC int Addr(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+int Action, /* Get/PreSet/Set action */
|
|
|
+SK_U32 Id, /* Object ID that is to be processed */
|
|
|
+char *pBuf, /* Buffer to which to mgmt data will be retrieved */
|
|
|
+unsigned int *pLen, /* On call: buffer length. On return: used buffer */
|
|
|
+SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
|
|
|
+unsigned int TableIndex, /* Index to the Id table */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+ int Ret;
|
|
|
+ unsigned int LogPortMax;
|
|
|
+ unsigned int PhysPortMax;
|
|
|
+ unsigned int LogPortIndex;
|
|
|
+ unsigned int PhysPortIndex;
|
|
|
+ unsigned int Limit;
|
|
|
+ unsigned int Offset = 0;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Calculate instance if wished. MAC index 0 is the virtual
|
|
|
+ * MAC.
|
|
|
+ */
|
|
|
+ PhysPortMax = pAC->GIni.GIMacsFound;
|
|
|
+ LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
|
|
|
+
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
|
|
|
+ LogPortMax--;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
|
|
|
+ /* Check instance range */
|
|
|
+ if ((Instance < 1) || (Instance > LogPortMax)) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_UNKNOWN_INST);
|
|
|
+ }
|
|
|
+ LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
|
|
|
+ Limit = LogPortIndex + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
|
|
|
+
|
|
|
+ LogPortIndex = 0;
|
|
|
+ Limit = LogPortMax;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Perform Action
|
|
|
+ */
|
|
|
+ if (Action == SK_PNMI_GET) {
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check length
|
|
|
+ */
|
|
|
+ if (*pLen < (Limit - LogPortIndex) * 6) {
|
|
|
+
|
|
|
+ *pLen = (Limit - LogPortIndex) * 6;
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get value
|
|
|
+ */
|
|
|
+ for (; LogPortIndex < Limit; LogPortIndex ++) {
|
|
|
+
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_SKGE_PHYS_CUR_ADDR:
|
|
|
+ if (LogPortIndex == 0) {
|
|
|
+ CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
|
|
|
+
|
|
|
+ CopyMac(pBuf + Offset,
|
|
|
+ &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
|
|
|
+ }
|
|
|
+ Offset += 6;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_PHYS_FAC_ADDR:
|
|
|
+ if (LogPortIndex == 0) {
|
|
|
+ CopyMac(pBuf + Offset,
|
|
|
+ &pAC->Addr.Net[NetIndex].PermanentMacAddress);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
|
|
|
+ pAC, LogPortIndex);
|
|
|
+
|
|
|
+ CopyMac(pBuf + Offset,
|
|
|
+ &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
|
|
|
+ }
|
|
|
+ Offset += 6;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
|
|
|
+ SK_PNMI_ERR008MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ *pLen = Offset;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /*
|
|
|
+ * The logical MAC address may not be changed only
|
|
|
+ * the physical ones
|
|
|
+ */
|
|
|
+ if (Id == OID_SKGE_PHYS_FAC_ADDR) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_READ_ONLY);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Only the current address may be changed
|
|
|
+ */
|
|
|
+ if (Id != OID_SKGE_PHYS_CUR_ADDR) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
|
|
|
+ SK_PNMI_ERR009MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check length
|
|
|
+ */
|
|
|
+ if (*pLen < (Limit - LogPortIndex) * 6) {
|
|
|
+
|
|
|
+ *pLen = (Limit - LogPortIndex) * 6;
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ if (*pLen > (Limit - LogPortIndex) * 6) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_BAD_VALUE);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check Action
|
|
|
+ */
|
|
|
+ if (Action == SK_PNMI_PRESET) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Set OID_SKGE_MAC_CUR_ADDR
|
|
|
+ */
|
|
|
+ for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
|
|
|
+
|
|
|
+ /*
|
|
|
+ * A set to virtual port and set of broadcast
|
|
|
+ * address will be ignored
|
|
|
+ */
|
|
|
+ if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
|
|
|
+ "\xff\xff\xff\xff\xff\xff", 6) == 0) {
|
|
|
+
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
|
|
|
+ LogPortIndex);
|
|
|
+
|
|
|
+ Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
|
|
|
+ (SK_MAC_ADDR *)(pBuf + Offset),
|
|
|
+ (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
|
|
|
+ SK_ADDR_PHYSICAL_ADDRESS));
|
|
|
+ if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ *pLen = Offset;
|
|
|
+ }
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Retrieves the statistic values of the CSUM module. The CSUM data
|
|
|
+ * structure must be available in the SK_AC even if the CSUM module
|
|
|
+ * is not included, because PNMI reads the statistic data from the
|
|
|
+ * CSUM part of SK_AC directly.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK The request was successfully performed.
|
|
|
+ * SK_PNMI_ERR_GENERAL A general severe internal error occured.
|
|
|
+ * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
|
|
|
+ * the correct data (e.g. a 32bit value is
|
|
|
+ * needed, but a 16 bit value was passed).
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
|
|
|
+ * exist (e.g. port instance 3 on a two port
|
|
|
+ * adapter.
|
|
|
+ */
|
|
|
+PNMI_STATIC int CsumStat(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+int Action, /* Get/PreSet/Set action */
|
|
|
+SK_U32 Id, /* Object ID that is to be processed */
|
|
|
+char *pBuf, /* Buffer to which to mgmt data will be retrieved */
|
|
|
+unsigned int *pLen, /* On call: buffer length. On return: used buffer */
|
|
|
+SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
|
|
|
+unsigned int TableIndex, /* Index to the Id table */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+ unsigned int Index;
|
|
|
+ unsigned int Limit;
|
|
|
+ unsigned int Offset = 0;
|
|
|
+ SK_U64 StatVal;
|
|
|
+
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Calculate instance if wished
|
|
|
+ */
|
|
|
+ if (Instance != (SK_U32)(-1)) {
|
|
|
+
|
|
|
+ if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_UNKNOWN_INST);
|
|
|
+ }
|
|
|
+ Index = (unsigned int)Instance - 1;
|
|
|
+ Limit = Index + 1;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ Index = 0;
|
|
|
+ Limit = SKCS_NUM_PROTOCOLS;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check action
|
|
|
+ */
|
|
|
+ if (Action != SK_PNMI_GET) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_READ_ONLY);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check length
|
|
|
+ */
|
|
|
+ if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
|
|
|
+
|
|
|
+ *pLen = (Limit - Index) * sizeof(SK_U64);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get value
|
|
|
+ */
|
|
|
+ for (; Index < Limit; Index ++) {
|
|
|
+
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_SKGE_CHKSM_RX_OK_CTS:
|
|
|
+ StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_CHKSM_RX_UNABLE_CTS:
|
|
|
+ StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_CHKSM_RX_ERR_CTS:
|
|
|
+ StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_CHKSM_TX_OK_CTS:
|
|
|
+ StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_CHKSM_TX_UNABLE_CTS:
|
|
|
+ StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
|
|
|
+ SK_PNMI_ERR010MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
|
|
|
+ Offset += sizeof(SK_U64);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Store used buffer space
|
|
|
+ */
|
|
|
+ *pLen = Offset;
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Retrieves the statistic values of the I2C module, which handles
|
|
|
+ * the temperature and voltage sensors.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK The request was successfully performed.
|
|
|
+ * SK_PNMI_ERR_GENERAL A general severe internal error occured.
|
|
|
+ * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
|
|
|
+ * the correct data (e.g. a 32bit value is
|
|
|
+ * needed, but a 16 bit value was passed).
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
|
|
|
+ * exist (e.g. port instance 3 on a two port
|
|
|
+ * adapter.
|
|
|
+ */
|
|
|
+PNMI_STATIC int SensorStat(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+int Action, /* Get/PreSet/Set action */
|
|
|
+SK_U32 Id, /* Object ID that is to be processed */
|
|
|
+char *pBuf, /* Buffer to which to mgmt data will be retrieved */
|
|
|
+unsigned int *pLen, /* On call: buffer length. On return: used buffer */
|
|
|
+SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
|
|
|
+unsigned int TableIndex, /* Index to the Id table */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+ unsigned int i;
|
|
|
+ unsigned int Index;
|
|
|
+ unsigned int Limit;
|
|
|
+ unsigned int Offset;
|
|
|
+ unsigned int Len;
|
|
|
+ SK_U32 Val32;
|
|
|
+ SK_U64 Val64;
|
|
|
+
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Calculate instance if wished
|
|
|
+ */
|
|
|
+ if ((Instance != (SK_U32)(-1))) {
|
|
|
+
|
|
|
+ if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_UNKNOWN_INST);
|
|
|
+ }
|
|
|
+
|
|
|
+ Index = (unsigned int)Instance -1;
|
|
|
+ Limit = (unsigned int)Instance;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ Index = 0;
|
|
|
+ Limit = (unsigned int) pAC->I2c.MaxSens;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check action
|
|
|
+ */
|
|
|
+ if (Action != SK_PNMI_GET) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_READ_ONLY);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check length
|
|
|
+ */
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_SKGE_SENSOR_VALUE:
|
|
|
+ case OID_SKGE_SENSOR_WAR_THRES_LOW:
|
|
|
+ case OID_SKGE_SENSOR_WAR_THRES_UPP:
|
|
|
+ case OID_SKGE_SENSOR_ERR_THRES_LOW:
|
|
|
+ case OID_SKGE_SENSOR_ERR_THRES_UPP:
|
|
|
+ if (*pLen < (Limit - Index) * sizeof(SK_U32)) {
|
|
|
+
|
|
|
+ *pLen = (Limit - Index) * sizeof(SK_U32);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SENSOR_DESCR:
|
|
|
+ for (Offset = 0, i = Index; i < Limit; i ++) {
|
|
|
+
|
|
|
+ Len = (unsigned int)
|
|
|
+ SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1;
|
|
|
+ if (Len >= SK_PNMI_STRINGLEN2) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011,
|
|
|
+ SK_PNMI_ERR011MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ Offset += Len;
|
|
|
+ }
|
|
|
+ if (*pLen < Offset) {
|
|
|
+
|
|
|
+ *pLen = Offset;
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SENSOR_INDEX:
|
|
|
+ case OID_SKGE_SENSOR_TYPE:
|
|
|
+ case OID_SKGE_SENSOR_STATUS:
|
|
|
+ if (*pLen < Limit - Index) {
|
|
|
+
|
|
|
+ *pLen = Limit - Index;
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SENSOR_WAR_CTS:
|
|
|
+ case OID_SKGE_SENSOR_WAR_TIME:
|
|
|
+ case OID_SKGE_SENSOR_ERR_CTS:
|
|
|
+ case OID_SKGE_SENSOR_ERR_TIME:
|
|
|
+ if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
|
|
|
+
|
|
|
+ *pLen = (Limit - Index) * sizeof(SK_U64);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
|
|
|
+ SK_PNMI_ERR012MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get value
|
|
|
+ */
|
|
|
+ for (Offset = 0; Index < Limit; Index ++) {
|
|
|
+
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_SKGE_SENSOR_INDEX:
|
|
|
+ *(pBuf + Offset) = (char)Index;
|
|
|
+ Offset += sizeof(char);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SENSOR_DESCR:
|
|
|
+ Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
|
|
|
+ SK_MEMCPY(pBuf + Offset + 1,
|
|
|
+ pAC->I2c.SenTable[Index].SenDesc, Len);
|
|
|
+ *(pBuf + Offset) = (char)Len;
|
|
|
+ Offset += Len + 1;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SENSOR_TYPE:
|
|
|
+ *(pBuf + Offset) =
|
|
|
+ (char)pAC->I2c.SenTable[Index].SenType;
|
|
|
+ Offset += sizeof(char);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SENSOR_VALUE:
|
|
|
+ Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
|
|
|
+ SK_PNMI_STORE_U32(pBuf + Offset, Val32);
|
|
|
+ Offset += sizeof(SK_U32);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SENSOR_WAR_THRES_LOW:
|
|
|
+ Val32 = (SK_U32)pAC->I2c.SenTable[Index].
|
|
|
+ SenThreWarnLow;
|
|
|
+ SK_PNMI_STORE_U32(pBuf + Offset, Val32);
|
|
|
+ Offset += sizeof(SK_U32);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SENSOR_WAR_THRES_UPP:
|
|
|
+ Val32 = (SK_U32)pAC->I2c.SenTable[Index].
|
|
|
+ SenThreWarnHigh;
|
|
|
+ SK_PNMI_STORE_U32(pBuf + Offset, Val32);
|
|
|
+ Offset += sizeof(SK_U32);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SENSOR_ERR_THRES_LOW:
|
|
|
+ Val32 = (SK_U32)pAC->I2c.SenTable[Index].
|
|
|
+ SenThreErrLow;
|
|
|
+ SK_PNMI_STORE_U32(pBuf + Offset, Val32);
|
|
|
+ Offset += sizeof(SK_U32);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SENSOR_ERR_THRES_UPP:
|
|
|
+ Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
|
|
|
+ SK_PNMI_STORE_U32(pBuf + Offset, Val32);
|
|
|
+ Offset += sizeof(SK_U32);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SENSOR_STATUS:
|
|
|
+ *(pBuf + Offset) =
|
|
|
+ (char)pAC->I2c.SenTable[Index].SenErrFlag;
|
|
|
+ Offset += sizeof(char);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SENSOR_WAR_CTS:
|
|
|
+ Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
|
|
|
+ SK_PNMI_STORE_U64(pBuf + Offset, Val64);
|
|
|
+ Offset += sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SENSOR_ERR_CTS:
|
|
|
+ Val64 = pAC->I2c.SenTable[Index].SenErrCts;
|
|
|
+ SK_PNMI_STORE_U64(pBuf + Offset, Val64);
|
|
|
+ Offset += sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SENSOR_WAR_TIME:
|
|
|
+ Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
|
|
|
+ SenBegWarnTS);
|
|
|
+ SK_PNMI_STORE_U64(pBuf + Offset, Val64);
|
|
|
+ Offset += sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SENSOR_ERR_TIME:
|
|
|
+ Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
|
|
|
+ SenBegErrTS);
|
|
|
+ SK_PNMI_STORE_U64(pBuf + Offset, Val64);
|
|
|
+ Offset += sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
|
|
|
+ ("SensorStat: Unknown OID should be handled before"));
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Store used buffer space
|
|
|
+ */
|
|
|
+ *pLen = Offset;
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * Vpd - OID handler function of OID_SKGE_VPD_XXX
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Get/preset/set of VPD data. As instance the name of a VPD key
|
|
|
+ * can be passed. The Instance parameter is a SK_U32 and can be
|
|
|
+ * used as a string buffer for the VPD key, because their maximum
|
|
|
+ * length is 4 byte.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK The request was successfully performed.
|
|
|
+ * SK_PNMI_ERR_GENERAL A general severe internal error occured.
|
|
|
+ * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
|
|
|
+ * the correct data (e.g. a 32bit value is
|
|
|
+ * needed, but a 16 bit value was passed).
|
|
|
+ * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
|
|
|
+ * value range.
|
|
|
+ * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
|
|
|
+ * exist (e.g. port instance 3 on a two port
|
|
|
+ * adapter.
|
|
|
+ */
|
|
|
+PNMI_STATIC int Vpd(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+int Action, /* Get/PreSet/Set action */
|
|
|
+SK_U32 Id, /* Object ID that is to be processed */
|
|
|
+char *pBuf, /* Buffer to which to mgmt data will be retrieved */
|
|
|
+unsigned int *pLen, /* On call: buffer length. On return: used buffer */
|
|
|
+SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
|
|
|
+unsigned int TableIndex, /* Index to the Id table */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+ SK_VPD_STATUS *pVpdStatus;
|
|
|
+ unsigned int BufLen;
|
|
|
+ char Buf[256];
|
|
|
+ char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
|
|
|
+ char KeyStr[SK_PNMI_VPD_KEY_SIZE];
|
|
|
+ unsigned int KeyNo;
|
|
|
+ unsigned int Offset;
|
|
|
+ unsigned int Index;
|
|
|
+ unsigned int FirstIndex;
|
|
|
+ unsigned int LastIndex;
|
|
|
+ unsigned int Len;
|
|
|
+ int Ret;
|
|
|
+ SK_U32 Val32;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get array of all currently stored VPD keys
|
|
|
+ */
|
|
|
+ Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr),
|
|
|
+ &KeyNo);
|
|
|
+ if (Ret != SK_PNMI_ERR_OK) {
|
|
|
+ *pLen = 0;
|
|
|
+ return (Ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If instance is not -1, try to find the requested VPD key for
|
|
|
+ * the multiple instance variables. The other OIDs as for example
|
|
|
+ * OID VPD_ACTION are single instance variables and must be
|
|
|
+ * handled separatly.
|
|
|
+ */
|
|
|
+ FirstIndex = 0;
|
|
|
+ LastIndex = KeyNo;
|
|
|
+
|
|
|
+ if ((Instance != (SK_U32)(-1))) {
|
|
|
+
|
|
|
+ if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
|
|
|
+ Id == OID_SKGE_VPD_ACCESS) {
|
|
|
+
|
|
|
+ SK_STRNCPY(KeyStr, (char *)&Instance, 4);
|
|
|
+ KeyStr[4] = 0;
|
|
|
+
|
|
|
+ for (Index = 0; Index < KeyNo; Index ++) {
|
|
|
+
|
|
|
+ if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
|
|
|
+ FirstIndex = Index;
|
|
|
+ LastIndex = Index+1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (Index == KeyNo) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_UNKNOWN_INST);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (Instance != 1) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_UNKNOWN_INST);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get value, if a query should be performed
|
|
|
+ */
|
|
|
+ if (Action == SK_PNMI_GET) {
|
|
|
+
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_SKGE_VPD_FREE_BYTES:
|
|
|
+ /* Check length of buffer */
|
|
|
+ if (*pLen < sizeof(SK_U32)) {
|
|
|
+
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ /* Get number of free bytes */
|
|
|
+ pVpdStatus = VpdStat(pAC, IoC);
|
|
|
+ if (pVpdStatus == NULL) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
|
|
|
+ SK_PNMI_ERR017MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
|
|
|
+ SK_PNMI_ERR018MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
|
|
|
+ SK_PNMI_STORE_U32(pBuf, Val32);
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_VPD_ENTRIES_LIST:
|
|
|
+ /* Check length */
|
|
|
+ for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
|
|
|
+
|
|
|
+ Len += SK_STRLEN(KeyArr[Index]) + 1;
|
|
|
+ }
|
|
|
+ if (*pLen < Len) {
|
|
|
+
|
|
|
+ *pLen = Len;
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Get value */
|
|
|
+ *(pBuf) = (char)Len - 1;
|
|
|
+ for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
|
|
|
+
|
|
|
+ Len = SK_STRLEN(KeyArr[Index]);
|
|
|
+ SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
|
|
|
+
|
|
|
+ Offset += Len;
|
|
|
+
|
|
|
+ if (Index < KeyNo - 1) {
|
|
|
+
|
|
|
+ *(pBuf + Offset) = ' ';
|
|
|
+ Offset ++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ *pLen = Offset;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_VPD_ENTRIES_NUMBER:
|
|
|
+ /* Check length */
|
|
|
+ if (*pLen < sizeof(SK_U32)) {
|
|
|
+
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+
|
|
|
+ Val32 = (SK_U32)KeyNo;
|
|
|
+ SK_PNMI_STORE_U32(pBuf, Val32);
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_VPD_KEY:
|
|
|
+ /* Check buffer length, if it is large enough */
|
|
|
+ for (Len = 0, Index = FirstIndex;
|
|
|
+ Index < LastIndex; Index ++) {
|
|
|
+
|
|
|
+ Len += SK_STRLEN(KeyArr[Index]) + 1;
|
|
|
+ }
|
|
|
+ if (*pLen < Len) {
|
|
|
+
|
|
|
+ *pLen = Len;
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get the key to an intermediate buffer, because
|
|
|
+ * we have to prepend a length byte.
|
|
|
+ */
|
|
|
+ for (Offset = 0, Index = FirstIndex;
|
|
|
+ Index < LastIndex; Index ++) {
|
|
|
+
|
|
|
+ Len = SK_STRLEN(KeyArr[Index]);
|
|
|
+
|
|
|
+ *(pBuf + Offset) = (char)Len;
|
|
|
+ SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
|
|
|
+ Len);
|
|
|
+ Offset += Len + 1;
|
|
|
+ }
|
|
|
+ *pLen = Offset;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_VPD_VALUE:
|
|
|
+ /* Check the buffer length if it is large enough */
|
|
|
+ for (Offset = 0, Index = FirstIndex;
|
|
|
+ Index < LastIndex; Index ++) {
|
|
|
+
|
|
|
+ BufLen = 256;
|
|
|
+ if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
|
|
|
+ (int *)&BufLen) > 0 ||
|
|
|
+ BufLen >= SK_PNMI_VPD_DATALEN) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW,
|
|
|
+ SK_PNMI_ERR021,
|
|
|
+ SK_PNMI_ERR021MSG);
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ Offset += BufLen + 1;
|
|
|
+ }
|
|
|
+ if (*pLen < Offset) {
|
|
|
+
|
|
|
+ *pLen = Offset;
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get the value to an intermediate buffer, because
|
|
|
+ * we have to prepend a length byte.
|
|
|
+ */
|
|
|
+ for (Offset = 0, Index = FirstIndex;
|
|
|
+ Index < LastIndex; Index ++) {
|
|
|
+
|
|
|
+ BufLen = 256;
|
|
|
+ if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
|
|
|
+ (int *)&BufLen) > 0 ||
|
|
|
+ BufLen >= SK_PNMI_VPD_DATALEN) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW,
|
|
|
+ SK_PNMI_ERR022,
|
|
|
+ SK_PNMI_ERR022MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ *(pBuf + Offset) = (char)BufLen;
|
|
|
+ SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
|
|
|
+ Offset += BufLen + 1;
|
|
|
+ }
|
|
|
+ *pLen = Offset;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_VPD_ACCESS:
|
|
|
+ if (*pLen < LastIndex - FirstIndex) {
|
|
|
+
|
|
|
+ *pLen = LastIndex - FirstIndex;
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (Offset = 0, Index = FirstIndex;
|
|
|
+ Index < LastIndex; Index ++) {
|
|
|
+
|
|
|
+ if (VpdMayWrite(KeyArr[Index])) {
|
|
|
+
|
|
|
+ *(pBuf + Offset) = SK_PNMI_VPD_RW;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ *(pBuf + Offset) = SK_PNMI_VPD_RO;
|
|
|
+ }
|
|
|
+ Offset ++;
|
|
|
+ }
|
|
|
+ *pLen = Offset;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_VPD_ACTION:
|
|
|
+ Offset = LastIndex - FirstIndex;
|
|
|
+ if (*pLen < Offset) {
|
|
|
+
|
|
|
+ *pLen = Offset;
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ SK_MEMSET(pBuf, 0, Offset);
|
|
|
+ *pLen = Offset;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
|
|
|
+ SK_PNMI_ERR023MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* The only OID which can be set is VPD_ACTION */
|
|
|
+ if (Id != OID_SKGE_VPD_ACTION) {
|
|
|
+
|
|
|
+ if (Id == OID_SKGE_VPD_FREE_BYTES ||
|
|
|
+ Id == OID_SKGE_VPD_ENTRIES_LIST ||
|
|
|
+ Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
|
|
|
+ Id == OID_SKGE_VPD_KEY ||
|
|
|
+ Id == OID_SKGE_VPD_VALUE ||
|
|
|
+ Id == OID_SKGE_VPD_ACCESS) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_READ_ONLY);
|
|
|
+ }
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
|
|
|
+ SK_PNMI_ERR024MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * From this point we handle VPD_ACTION. Check the buffer
|
|
|
+ * length. It should at least have the size of one byte.
|
|
|
+ */
|
|
|
+ if (*pLen < 1) {
|
|
|
+
|
|
|
+ *pLen = 1;
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The first byte contains the VPD action type we should
|
|
|
+ * perform.
|
|
|
+ */
|
|
|
+ switch (*pBuf) {
|
|
|
+
|
|
|
+ case SK_PNMI_VPD_IGNORE:
|
|
|
+ /* Nothing to do */
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_VPD_CREATE:
|
|
|
+ /*
|
|
|
+ * We have to create a new VPD entry or we modify
|
|
|
+ * an existing one. Check first the buffer length.
|
|
|
+ */
|
|
|
+ if (*pLen < 4) {
|
|
|
+
|
|
|
+ *pLen = 4;
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ KeyStr[0] = pBuf[1];
|
|
|
+ KeyStr[1] = pBuf[2];
|
|
|
+ KeyStr[2] = 0;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Is the entry writable or does it belong to the
|
|
|
+ * read-only area?
|
|
|
+ */
|
|
|
+ if (!VpdMayWrite(KeyStr)) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_BAD_VALUE);
|
|
|
+ }
|
|
|
+
|
|
|
+ Offset = (int)pBuf[3] & 0xFF;
|
|
|
+
|
|
|
+ SK_MEMCPY(Buf, pBuf + 4, Offset);
|
|
|
+ Buf[Offset] = 0;
|
|
|
+
|
|
|
+ /* A preset ends here */
|
|
|
+ if (Action == SK_PNMI_PRESET) {
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Write the new entry or modify an existing one */
|
|
|
+ Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
|
|
|
+ if (Ret == SK_PNMI_VPD_NOWRITE ) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_BAD_VALUE);
|
|
|
+ }
|
|
|
+ else if (Ret != SK_PNMI_VPD_OK) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
|
|
|
+ SK_PNMI_ERR025MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Perform an update of the VPD data. This is
|
|
|
+ * not mandantory, but just to be sure.
|
|
|
+ */
|
|
|
+ Ret = VpdUpdate(pAC, IoC);
|
|
|
+ if (Ret != SK_PNMI_VPD_OK) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
|
|
|
+ SK_PNMI_ERR026MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_VPD_DELETE:
|
|
|
+ /* Check if the buffer size is plausible */
|
|
|
+ if (*pLen < 3) {
|
|
|
+
|
|
|
+ *pLen = 3;
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ if (*pLen > 3) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_BAD_VALUE);
|
|
|
+ }
|
|
|
+ KeyStr[0] = pBuf[1];
|
|
|
+ KeyStr[1] = pBuf[2];
|
|
|
+ KeyStr[2] = 0;
|
|
|
+
|
|
|
+ /* Find the passed key in the array */
|
|
|
+ for (Index = 0; Index < KeyNo; Index ++) {
|
|
|
+
|
|
|
+ if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ * If we cannot find the key it is wrong, so we
|
|
|
+ * return an appropriate error value.
|
|
|
+ */
|
|
|
+ if (Index == KeyNo) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_BAD_VALUE);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Action == SK_PNMI_PRESET) {
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Ok, you wanted it and you will get it */
|
|
|
+ Ret = VpdDelete(pAC, IoC, KeyStr);
|
|
|
+ if (Ret != SK_PNMI_VPD_OK) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
|
|
|
+ SK_PNMI_ERR027MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Perform an update of the VPD data. This is
|
|
|
+ * not mandantory, but just to be sure.
|
|
|
+ */
|
|
|
+ Ret = VpdUpdate(pAC, IoC);
|
|
|
+ if (Ret != SK_PNMI_VPD_OK) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
|
|
|
+ SK_PNMI_ERR028MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_BAD_VALUE);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * General - OID handler function of various single instance OIDs
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * The code is simple. No description necessary.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK The request was successfully performed.
|
|
|
+ * SK_PNMI_ERR_GENERAL A general severe internal error occured.
|
|
|
+ * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
|
|
|
+ * the correct data (e.g. a 32bit value is
|
|
|
+ * needed, but a 16 bit value was passed).
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
|
|
|
+ * exist (e.g. port instance 3 on a two port
|
|
|
+ * adapter.
|
|
|
+ */
|
|
|
+PNMI_STATIC int General(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+int Action, /* Get/PreSet/Set action */
|
|
|
+SK_U32 Id, /* Object ID that is to be processed */
|
|
|
+char *pBuf, /* Buffer to which to mgmt data will be retrieved */
|
|
|
+unsigned int *pLen, /* On call: buffer length. On return: used buffer */
|
|
|
+SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
|
|
|
+unsigned int TableIndex, /* Index to the Id table */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+ int Ret;
|
|
|
+ unsigned int Index;
|
|
|
+ unsigned int Len;
|
|
|
+ unsigned int Offset;
|
|
|
+ unsigned int Val;
|
|
|
+ SK_U8 Val8;
|
|
|
+ SK_U16 Val16;
|
|
|
+ SK_U32 Val32;
|
|
|
+ SK_U64 Val64;
|
|
|
+ SK_U64 Val64RxHwErrs = 0;
|
|
|
+ SK_U64 Val64TxHwErrs = 0;
|
|
|
+ SK_BOOL Is64BitReq = SK_FALSE;
|
|
|
+ char Buf[256];
|
|
|
+ int MacType;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check instance. We only handle single instance variables
|
|
|
+ */
|
|
|
+ if (Instance != (SK_U32)(-1) && Instance != 1) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_UNKNOWN_INST);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check action. We only allow get requests.
|
|
|
+ */
|
|
|
+ if (Action != SK_PNMI_GET) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_READ_ONLY);
|
|
|
+ }
|
|
|
+
|
|
|
+ MacType = pAC->GIni.GIMacType;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check length for the various supported OIDs
|
|
|
+ */
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_GEN_XMIT_ERROR:
|
|
|
+ case OID_GEN_RCV_ERROR:
|
|
|
+ case OID_GEN_RCV_NO_BUFFER:
|
|
|
+#ifndef SK_NDIS_64BIT_CTR
|
|
|
+ if (*pLen < sizeof(SK_U32)) {
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+
|
|
|
+#else /* SK_NDIS_64BIT_CTR */
|
|
|
+
|
|
|
+ /*
|
|
|
+ * for compatibility, at least 32bit are required for oid
|
|
|
+ */
|
|
|
+ if (*pLen < sizeof(SK_U32)) {
|
|
|
+ /*
|
|
|
+ * but indicate handling for 64bit values,
|
|
|
+ * if insufficient space is provided
|
|
|
+ */
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+
|
|
|
+ Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
|
|
|
+#endif /* SK_NDIS_64BIT_CTR */
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_PORT_NUMBER:
|
|
|
+ case OID_SKGE_DEVICE_TYPE:
|
|
|
+ case OID_SKGE_RESULT:
|
|
|
+ case OID_SKGE_RLMT_MONITOR_NUMBER:
|
|
|
+ case OID_GEN_TRANSMIT_QUEUE_LENGTH:
|
|
|
+ case OID_SKGE_TRAP_NUMBER:
|
|
|
+ case OID_SKGE_MDB_VERSION:
|
|
|
+ if (*pLen < sizeof(SK_U32)) {
|
|
|
+
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_CHIPSET:
|
|
|
+ if (*pLen < sizeof(SK_U16)) {
|
|
|
+
|
|
|
+ *pLen = sizeof(SK_U16);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_BUS_TYPE:
|
|
|
+ case OID_SKGE_BUS_SPEED:
|
|
|
+ case OID_SKGE_BUS_WIDTH:
|
|
|
+ case OID_SKGE_SENSOR_NUMBER:
|
|
|
+ case OID_SKGE_CHKSM_NUMBER:
|
|
|
+ if (*pLen < sizeof(SK_U8)) {
|
|
|
+
|
|
|
+ *pLen = sizeof(SK_U8);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_TX_SW_QUEUE_LEN:
|
|
|
+ case OID_SKGE_TX_SW_QUEUE_MAX:
|
|
|
+ case OID_SKGE_TX_RETRY:
|
|
|
+ case OID_SKGE_RX_INTR_CTS:
|
|
|
+ case OID_SKGE_TX_INTR_CTS:
|
|
|
+ case OID_SKGE_RX_NO_BUF_CTS:
|
|
|
+ case OID_SKGE_TX_NO_BUF_CTS:
|
|
|
+ case OID_SKGE_TX_USED_DESCR_NO:
|
|
|
+ case OID_SKGE_RX_DELIVERED_CTS:
|
|
|
+ case OID_SKGE_RX_OCTETS_DELIV_CTS:
|
|
|
+ case OID_SKGE_RX_HW_ERROR_CTS:
|
|
|
+ case OID_SKGE_TX_HW_ERROR_CTS:
|
|
|
+ case OID_SKGE_IN_ERRORS_CTS:
|
|
|
+ case OID_SKGE_OUT_ERROR_CTS:
|
|
|
+ case OID_SKGE_ERR_RECOVERY_CTS:
|
|
|
+ case OID_SKGE_SYSUPTIME:
|
|
|
+ if (*pLen < sizeof(SK_U64)) {
|
|
|
+
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ /* Checked later */
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Update statistic */
|
|
|
+ if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
|
|
|
+ Id == OID_SKGE_TX_HW_ERROR_CTS ||
|
|
|
+ Id == OID_SKGE_IN_ERRORS_CTS ||
|
|
|
+ Id == OID_SKGE_OUT_ERROR_CTS ||
|
|
|
+ Id == OID_GEN_XMIT_ERROR ||
|
|
|
+ Id == OID_GEN_RCV_ERROR) {
|
|
|
+
|
|
|
+ /* Force the XMAC to update its statistic counters and
|
|
|
+ * Increment semaphore to indicate that an update was
|
|
|
+ * already done.
|
|
|
+ */
|
|
|
+ Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
|
|
|
+ if (Ret != SK_PNMI_ERR_OK) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (Ret);
|
|
|
+ }
|
|
|
+ pAC->Pnmi.MacUpdatedFlag ++;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Some OIDs consist of multiple hardware counters. Those
|
|
|
+ * values which are contained in all of them will be added
|
|
|
+ * now.
|
|
|
+ */
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_SKGE_RX_HW_ERROR_CTS:
|
|
|
+ case OID_SKGE_IN_ERRORS_CTS:
|
|
|
+ case OID_GEN_RCV_ERROR:
|
|
|
+ Val64RxHwErrs =
|
|
|
+ GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
|
|
|
+ GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
|
|
|
+ GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex)+
|
|
|
+ GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
|
|
|
+ GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
|
|
|
+ GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex)+
|
|
|
+ GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
|
|
|
+ GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
|
|
|
+ GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
|
|
|
+ GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
|
|
|
+ GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
|
|
|
+ GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_TX_HW_ERROR_CTS:
|
|
|
+ case OID_SKGE_OUT_ERROR_CTS:
|
|
|
+ case OID_GEN_XMIT_ERROR:
|
|
|
+ Val64TxHwErrs =
|
|
|
+ GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
|
|
|
+ GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex)+
|
|
|
+ GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex)+
|
|
|
+ GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Retrieve value
|
|
|
+ */
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_SKGE_SUPPORTED_LIST:
|
|
|
+ Len = ID_TABLE_SIZE * sizeof(SK_U32);
|
|
|
+ if (*pLen < Len) {
|
|
|
+
|
|
|
+ *pLen = Len;
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ for (Offset = 0, Index = 0; Offset < Len;
|
|
|
+ Offset += sizeof(SK_U32), Index ++) {
|
|
|
+
|
|
|
+ Val32 = (SK_U32)IdTable[Index].Id;
|
|
|
+ SK_PNMI_STORE_U32(pBuf + Offset, Val32);
|
|
|
+ }
|
|
|
+ *pLen = Len;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_PORT_NUMBER:
|
|
|
+ Val32 = (SK_U32)pAC->GIni.GIMacsFound;
|
|
|
+ SK_PNMI_STORE_U32(pBuf, Val32);
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_DEVICE_TYPE:
|
|
|
+ Val32 = (SK_U32)pAC->Pnmi.DeviceType;
|
|
|
+ SK_PNMI_STORE_U32(pBuf, Val32);
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_DRIVER_DESCR:
|
|
|
+ if (pAC->Pnmi.pDriverDescription == NULL) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
|
|
|
+ SK_PNMI_ERR007MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
|
|
|
+ if (Len > SK_PNMI_STRINGLEN1) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
|
|
|
+ SK_PNMI_ERR029MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (*pLen < Len) {
|
|
|
+
|
|
|
+ *pLen = Len;
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ *pBuf = (char)(Len - 1);
|
|
|
+ SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
|
|
|
+ *pLen = Len;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_DRIVER_VERSION:
|
|
|
+ if (pAC->Pnmi.pDriverVersion == NULL) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
|
|
|
+ SK_PNMI_ERR030MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
|
|
|
+ if (Len > SK_PNMI_STRINGLEN1) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
|
|
|
+ SK_PNMI_ERR031MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (*pLen < Len) {
|
|
|
+
|
|
|
+ *pLen = Len;
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ *pBuf = (char)(Len - 1);
|
|
|
+ SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
|
|
|
+ *pLen = Len;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_HW_DESCR:
|
|
|
+ /*
|
|
|
+ * The hardware description is located in the VPD. This
|
|
|
+ * query may move to the initialisation routine. But
|
|
|
+ * the VPD data is cached and therefore a call here
|
|
|
+ * will not make much difference.
|
|
|
+ */
|
|
|
+ Len = 256;
|
|
|
+ if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
|
|
|
+ SK_PNMI_ERR032MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ Len ++;
|
|
|
+ if (Len > SK_PNMI_STRINGLEN1) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
|
|
|
+ SK_PNMI_ERR033MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ if (*pLen < Len) {
|
|
|
+
|
|
|
+ *pLen = Len;
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ *pBuf = (char)(Len - 1);
|
|
|
+ SK_MEMCPY(pBuf + 1, Buf, Len - 1);
|
|
|
+ *pLen = Len;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_HW_VERSION:
|
|
|
+ /* Oh, I love to do some string manipulation */
|
|
|
+ if (*pLen < 5) {
|
|
|
+
|
|
|
+ *pLen = 5;
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
|
|
|
+ pBuf[0] = 4;
|
|
|
+ pBuf[1] = 'v';
|
|
|
+ pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
|
|
|
+ pBuf[3] = '.';
|
|
|
+ pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
|
|
|
+ *pLen = 5;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_CHIPSET:
|
|
|
+ Val16 = pAC->Pnmi.Chipset;
|
|
|
+ SK_PNMI_STORE_U16(pBuf, Val16);
|
|
|
+ *pLen = sizeof(SK_U16);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_BUS_TYPE:
|
|
|
+ *pBuf = (char)SK_PNMI_BUS_PCI;
|
|
|
+ *pLen = sizeof(char);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_BUS_SPEED:
|
|
|
+ *pBuf = pAC->Pnmi.PciBusSpeed;
|
|
|
+ *pLen = sizeof(char);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_BUS_WIDTH:
|
|
|
+ *pBuf = pAC->Pnmi.PciBusWidth;
|
|
|
+ *pLen = sizeof(char);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RESULT:
|
|
|
+ Val32 = pAC->Pnmi.TestResult;
|
|
|
+ SK_PNMI_STORE_U32(pBuf, Val32);
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SENSOR_NUMBER:
|
|
|
+ *pBuf = (char)pAC->I2c.MaxSens;
|
|
|
+ *pLen = sizeof(char);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_CHKSM_NUMBER:
|
|
|
+ *pBuf = SKCS_NUM_PROTOCOLS;
|
|
|
+ *pLen = sizeof(char);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_TRAP_NUMBER:
|
|
|
+ GetTrapQueueLen(pAC, &Len, &Val);
|
|
|
+ Val32 = (SK_U32)Val;
|
|
|
+ SK_PNMI_STORE_U32(pBuf, Val32);
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_TRAP:
|
|
|
+ GetTrapQueueLen(pAC, &Len, &Val);
|
|
|
+ if (*pLen < Len) {
|
|
|
+
|
|
|
+ *pLen = Len;
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ CopyTrapQueue(pAC, pBuf);
|
|
|
+ *pLen = Len;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_MONITOR_NUMBER:
|
|
|
+/* XXX Not yet implemented by RLMT therefore we return zero elements */
|
|
|
+ Val32 = 0;
|
|
|
+ SK_PNMI_STORE_U32(pBuf, Val32);
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_TX_SW_QUEUE_LEN:
|
|
|
+ /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
|
|
|
+ if (MacType == SK_MAC_XMAC) {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
|
|
|
+ pAC->Pnmi.BufPort[1].TxSwQueueLen;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
|
|
|
+ pAC->Pnmi.Port[1].TxSwQueueLen;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ SK_PNMI_STORE_U64(pBuf, Val64);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+
|
|
|
+ case OID_SKGE_TX_SW_QUEUE_MAX:
|
|
|
+ /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
|
|
|
+ if (MacType == SK_MAC_XMAC) {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
|
|
|
+ pAC->Pnmi.BufPort[1].TxSwQueueMax;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
|
|
|
+ pAC->Pnmi.Port[1].TxSwQueueMax;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ SK_PNMI_STORE_U64(pBuf, Val64);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_TX_RETRY:
|
|
|
+ /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
|
|
|
+ if (MacType == SK_MAC_XMAC) {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
|
|
|
+ pAC->Pnmi.BufPort[1].TxRetryCts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = pAC->Pnmi.Port[0].TxRetryCts +
|
|
|
+ pAC->Pnmi.Port[1].TxRetryCts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ SK_PNMI_STORE_U64(pBuf, Val64);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RX_INTR_CTS:
|
|
|
+ /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
|
|
|
+ if (MacType == SK_MAC_XMAC) {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
|
|
|
+ pAC->Pnmi.BufPort[1].RxIntrCts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = pAC->Pnmi.Port[0].RxIntrCts +
|
|
|
+ pAC->Pnmi.Port[1].RxIntrCts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ SK_PNMI_STORE_U64(pBuf, Val64);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_TX_INTR_CTS:
|
|
|
+ /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
|
|
|
+ if (MacType == SK_MAC_XMAC) {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
|
|
|
+ pAC->Pnmi.BufPort[1].TxIntrCts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = pAC->Pnmi.Port[0].TxIntrCts +
|
|
|
+ pAC->Pnmi.Port[1].TxIntrCts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ SK_PNMI_STORE_U64(pBuf, Val64);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RX_NO_BUF_CTS:
|
|
|
+ /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
|
|
|
+ if (MacType == SK_MAC_XMAC) {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
|
|
|
+ pAC->Pnmi.BufPort[1].RxNoBufCts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
|
|
|
+ pAC->Pnmi.Port[1].RxNoBufCts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ SK_PNMI_STORE_U64(pBuf, Val64);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_TX_NO_BUF_CTS:
|
|
|
+ /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
|
|
|
+ if (MacType == SK_MAC_XMAC) {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
|
|
|
+ pAC->Pnmi.BufPort[1].TxNoBufCts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
|
|
|
+ pAC->Pnmi.Port[1].TxNoBufCts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ SK_PNMI_STORE_U64(pBuf, Val64);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_TX_USED_DESCR_NO:
|
|
|
+ /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
|
|
|
+ if (MacType == SK_MAC_XMAC) {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
|
|
|
+ pAC->Pnmi.BufPort[1].TxUsedDescrNo;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
|
|
|
+ pAC->Pnmi.Port[1].TxUsedDescrNo;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ SK_PNMI_STORE_U64(pBuf, Val64);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RX_DELIVERED_CTS:
|
|
|
+ /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
|
|
|
+ if (MacType == SK_MAC_XMAC) {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
|
|
|
+ pAC->Pnmi.BufPort[1].RxDeliveredCts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
|
|
|
+ pAC->Pnmi.Port[1].RxDeliveredCts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ SK_PNMI_STORE_U64(pBuf, Val64);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RX_OCTETS_DELIV_CTS:
|
|
|
+ /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
|
|
|
+ if (MacType == SK_MAC_XMAC) {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
|
|
|
+ pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
|
|
|
+ pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ SK_PNMI_STORE_U64(pBuf, Val64);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RX_HW_ERROR_CTS:
|
|
|
+ SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_TX_HW_ERROR_CTS:
|
|
|
+ SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_IN_ERRORS_CTS:
|
|
|
+ /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
|
|
|
+ if (MacType == SK_MAC_XMAC) {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = Val64RxHwErrs +
|
|
|
+ pAC->Pnmi.BufPort[0].RxNoBufCts +
|
|
|
+ pAC->Pnmi.BufPort[1].RxNoBufCts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = Val64RxHwErrs +
|
|
|
+ pAC->Pnmi.Port[0].RxNoBufCts +
|
|
|
+ pAC->Pnmi.Port[1].RxNoBufCts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ SK_PNMI_STORE_U64(pBuf, Val64);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_OUT_ERROR_CTS:
|
|
|
+ /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
|
|
|
+ if (MacType == SK_MAC_XMAC) {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = Val64TxHwErrs +
|
|
|
+ pAC->Pnmi.BufPort[0].TxNoBufCts +
|
|
|
+ pAC->Pnmi.BufPort[1].TxNoBufCts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = Val64TxHwErrs +
|
|
|
+ pAC->Pnmi.Port[0].TxNoBufCts +
|
|
|
+ pAC->Pnmi.Port[1].TxNoBufCts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ SK_PNMI_STORE_U64(pBuf, Val64);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_ERR_RECOVERY_CTS:
|
|
|
+ /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
|
|
|
+ if (MacType == SK_MAC_XMAC) {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
|
|
|
+ pAC->Pnmi.BufPort[1].ErrRecoveryCts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
|
|
|
+ }
|
|
|
+ /* Single net mode */
|
|
|
+ else {
|
|
|
+ Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
|
|
|
+ pAC->Pnmi.Port[1].ErrRecoveryCts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ SK_PNMI_STORE_U64(pBuf, Val64);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SYSUPTIME:
|
|
|
+ Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
|
|
|
+ Val64 -= pAC->Pnmi.StartUpTime;
|
|
|
+ SK_PNMI_STORE_U64(pBuf, Val64);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_MDB_VERSION:
|
|
|
+ Val32 = SK_PNMI_MDB_VERSION;
|
|
|
+ SK_PNMI_STORE_U32(pBuf, Val32);
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_GEN_RCV_ERROR:
|
|
|
+ /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
|
|
|
+ if (MacType == SK_MAC_XMAC) {
|
|
|
+ Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * by default 32bit values are evaluated
|
|
|
+ */
|
|
|
+ if (!Is64BitReq) {
|
|
|
+ Val32 = (SK_U32)Val64;
|
|
|
+ SK_PNMI_STORE_U32(pBuf, Val32);
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ SK_PNMI_STORE_U64(pBuf, Val64);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_GEN_XMIT_ERROR:
|
|
|
+ /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
|
|
|
+ if (MacType == SK_MAC_XMAC) {
|
|
|
+ Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * by default 32bit values are evaluated
|
|
|
+ */
|
|
|
+ if (!Is64BitReq) {
|
|
|
+ Val32 = (SK_U32)Val64;
|
|
|
+ SK_PNMI_STORE_U32(pBuf, Val32);
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ SK_PNMI_STORE_U64(pBuf, Val64);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_GEN_RCV_NO_BUFFER:
|
|
|
+ /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
|
|
|
+ if (MacType == SK_MAC_XMAC) {
|
|
|
+ Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * by default 32bit values are evaluated
|
|
|
+ */
|
|
|
+ if (!Is64BitReq) {
|
|
|
+ Val32 = (SK_U32)Val64;
|
|
|
+ SK_PNMI_STORE_U32(pBuf, Val32);
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ SK_PNMI_STORE_U64(pBuf, Val64);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_GEN_TRANSMIT_QUEUE_LENGTH:
|
|
|
+ Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
|
|
|
+ SK_PNMI_STORE_U32(pBuf, Val32);
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
|
|
|
+ SK_PNMI_ERR034MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
|
|
|
+ Id == OID_SKGE_TX_HW_ERROR_CTS ||
|
|
|
+ Id == OID_SKGE_IN_ERRORS_CTS ||
|
|
|
+ Id == OID_SKGE_OUT_ERROR_CTS ||
|
|
|
+ Id == OID_GEN_XMIT_ERROR ||
|
|
|
+ Id == OID_GEN_RCV_ERROR) {
|
|
|
+
|
|
|
+ pAC->Pnmi.MacUpdatedFlag --;
|
|
|
+ }
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Get/Presets/Sets the RLMT OIDs.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK The request was successfully performed.
|
|
|
+ * SK_PNMI_ERR_GENERAL A general severe internal error occured.
|
|
|
+ * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
|
|
|
+ * the correct data (e.g. a 32bit value is
|
|
|
+ * needed, but a 16 bit value was passed).
|
|
|
+ * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
|
|
|
+ * value range.
|
|
|
+ * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
|
|
|
+ * exist (e.g. port instance 3 on a two port
|
|
|
+ * adapter.
|
|
|
+ */
|
|
|
+PNMI_STATIC int Rlmt(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+int Action, /* Get/PreSet/Set action */
|
|
|
+SK_U32 Id, /* Object ID that is to be processed */
|
|
|
+char *pBuf, /* Buffer to which to mgmt data will be retrieved */
|
|
|
+unsigned int *pLen, /* On call: buffer length. On return: used buffer */
|
|
|
+SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
|
|
|
+unsigned int TableIndex, /* Index to the Id table */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+ int Ret;
|
|
|
+ unsigned int PhysPortIndex;
|
|
|
+ unsigned int PhysPortMax;
|
|
|
+ SK_EVPARA EventParam;
|
|
|
+ SK_U32 Val32;
|
|
|
+ SK_U64 Val64;
|
|
|
+
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check instance. Only single instance OIDs are allowed here.
|
|
|
+ */
|
|
|
+ if (Instance != (SK_U32)(-1) && Instance != 1) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_UNKNOWN_INST);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Perform the requested action
|
|
|
+ */
|
|
|
+ if (Action == SK_PNMI_GET) {
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check if the buffer length is large enough.
|
|
|
+ */
|
|
|
+
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_MODE:
|
|
|
+ case OID_SKGE_RLMT_PORT_ACTIVE:
|
|
|
+ case OID_SKGE_RLMT_PORT_PREFERRED:
|
|
|
+ if (*pLen < sizeof(SK_U8)) {
|
|
|
+
|
|
|
+ *pLen = sizeof(SK_U8);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_PORT_NUMBER:
|
|
|
+ if (*pLen < sizeof(SK_U32)) {
|
|
|
+
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_CHANGE_CTS:
|
|
|
+ case OID_SKGE_RLMT_CHANGE_TIME:
|
|
|
+ case OID_SKGE_RLMT_CHANGE_ESTIM:
|
|
|
+ case OID_SKGE_RLMT_CHANGE_THRES:
|
|
|
+ if (*pLen < sizeof(SK_U64)) {
|
|
|
+
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
|
|
|
+ SK_PNMI_ERR035MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Update RLMT statistic and increment semaphores to indicate
|
|
|
+ * that an update was already done. Maybe RLMT will hold its
|
|
|
+ * statistic always up to date some time. Then we can
|
|
|
+ * remove this type of call.
|
|
|
+ */
|
|
|
+ if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (Ret);
|
|
|
+ }
|
|
|
+ pAC->Pnmi.RlmtUpdatedFlag ++;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Retrieve Value
|
|
|
+ */
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_MODE:
|
|
|
+ *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
|
|
|
+ *pLen = sizeof(char);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_PORT_NUMBER:
|
|
|
+ Val32 = (SK_U32)pAC->GIni.GIMacsFound;
|
|
|
+ SK_PNMI_STORE_U32(pBuf, Val32);
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_PORT_ACTIVE:
|
|
|
+ *pBuf = 0;
|
|
|
+ /*
|
|
|
+ * If multiple ports may become active this OID
|
|
|
+ * doesn't make sense any more. A new variable in
|
|
|
+ * the port structure should be created. However,
|
|
|
+ * for this variable the first active port is
|
|
|
+ * returned.
|
|
|
+ */
|
|
|
+ PhysPortMax = pAC->GIni.GIMacsFound;
|
|
|
+
|
|
|
+ for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
|
|
|
+ PhysPortIndex ++) {
|
|
|
+
|
|
|
+ if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
|
|
|
+
|
|
|
+ *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ *pLen = sizeof(char);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_PORT_PREFERRED:
|
|
|
+ *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
|
|
|
+ *pLen = sizeof(char);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_CHANGE_CTS:
|
|
|
+ Val64 = pAC->Pnmi.RlmtChangeCts;
|
|
|
+ SK_PNMI_STORE_U64(pBuf, Val64);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_CHANGE_TIME:
|
|
|
+ Val64 = pAC->Pnmi.RlmtChangeTime;
|
|
|
+ SK_PNMI_STORE_U64(pBuf, Val64);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_CHANGE_ESTIM:
|
|
|
+ Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
|
|
|
+ SK_PNMI_STORE_U64(pBuf, Val64);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_CHANGE_THRES:
|
|
|
+ Val64 = pAC->Pnmi.RlmtChangeThreshold;
|
|
|
+ SK_PNMI_STORE_U64(pBuf, Val64);
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
|
|
|
+ ("Rlmt: Unknown OID should be handled before"));
|
|
|
+
|
|
|
+ pAC->Pnmi.RlmtUpdatedFlag --;
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ pAC->Pnmi.RlmtUpdatedFlag --;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Perform a preset or set */
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_MODE:
|
|
|
+ /* Check if the buffer length is plausible */
|
|
|
+ if (*pLen < sizeof(char)) {
|
|
|
+
|
|
|
+ *pLen = sizeof(char);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ /* Check if the value range is correct */
|
|
|
+ if (*pLen != sizeof(char) ||
|
|
|
+ (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
|
|
|
+ *(SK_U8 *)pBuf > 15) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_BAD_VALUE);
|
|
|
+ }
|
|
|
+ /* The preset ends here */
|
|
|
+ if (Action == SK_PNMI_PRESET) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+ }
|
|
|
+ /* Send an event to RLMT to change the mode */
|
|
|
+ SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
|
|
|
+ EventParam.Para32[0] |= (SK_U32)(*pBuf);
|
|
|
+ EventParam.Para32[1] = 0;
|
|
|
+ if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
|
|
|
+ EventParam) > 0) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
|
|
|
+ SK_PNMI_ERR037MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_PORT_PREFERRED:
|
|
|
+ /* Check if the buffer length is plausible */
|
|
|
+ if (*pLen < sizeof(char)) {
|
|
|
+
|
|
|
+ *pLen = sizeof(char);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ /* Check if the value range is correct */
|
|
|
+ if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
|
|
|
+ (SK_U8)pAC->GIni.GIMacsFound) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_BAD_VALUE);
|
|
|
+ }
|
|
|
+ /* The preset ends here */
|
|
|
+ if (Action == SK_PNMI_PRESET) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Send an event to RLMT change the preferred port.
|
|
|
+ * A param of -1 means automatic mode. RLMT will
|
|
|
+ * make the decision which is the preferred port.
|
|
|
+ */
|
|
|
+ SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
|
|
|
+ EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
|
|
|
+ EventParam.Para32[1] = NetIndex;
|
|
|
+ if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
|
|
|
+ EventParam) > 0) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
|
|
|
+ SK_PNMI_ERR038MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_CHANGE_THRES:
|
|
|
+ /* Check if the buffer length is plausible */
|
|
|
+ if (*pLen < sizeof(SK_U64)) {
|
|
|
+
|
|
|
+ *pLen = sizeof(SK_U64);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ * There are not many restrictions to the
|
|
|
+ * value range.
|
|
|
+ */
|
|
|
+ if (*pLen != sizeof(SK_U64)) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_BAD_VALUE);
|
|
|
+ }
|
|
|
+ /* A preset ends here */
|
|
|
+ if (Action == SK_PNMI_PRESET) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ * Store the new threshold, which will be taken
|
|
|
+ * on the next timer event.
|
|
|
+ */
|
|
|
+ SK_PNMI_READ_U64(pBuf, Val64);
|
|
|
+ pAC->Pnmi.RlmtChangeThreshold = Val64;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ /* The other OIDs are not be able for set */
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_READ_ONLY);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Performs get requests on multiple instance variables.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK The request was successfully performed.
|
|
|
+ * SK_PNMI_ERR_GENERAL A general severe internal error occured.
|
|
|
+ * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
|
|
|
+ * the correct data (e.g. a 32bit value is
|
|
|
+ * needed, but a 16 bit value was passed).
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
|
|
|
+ * exist (e.g. port instance 3 on a two port
|
|
|
+ * adapter.
|
|
|
+ */
|
|
|
+PNMI_STATIC int RlmtStat(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+int Action, /* Get/PreSet/Set action */
|
|
|
+SK_U32 Id, /* Object ID that is to be processed */
|
|
|
+char *pBuf, /* Buffer to which to mgmt data will be retrieved */
|
|
|
+unsigned int *pLen, /* On call: buffer length. On return: used buffer */
|
|
|
+SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
|
|
|
+unsigned int TableIndex, /* Index to the Id table */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+ unsigned int PhysPortMax;
|
|
|
+ unsigned int PhysPortIndex;
|
|
|
+ unsigned int Limit;
|
|
|
+ unsigned int Offset;
|
|
|
+ int Ret;
|
|
|
+ SK_U32 Val32;
|
|
|
+ SK_U64 Val64;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Calculate the port indexes from the instance
|
|
|
+ */
|
|
|
+ PhysPortMax = pAC->GIni.GIMacsFound;
|
|
|
+
|
|
|
+ if ((Instance != (SK_U32)(-1))) {
|
|
|
+ /* Check instance range */
|
|
|
+ if ((Instance < 1) || (Instance > PhysPortMax)) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_UNKNOWN_INST);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Single net mode */
|
|
|
+ PhysPortIndex = Instance - 1;
|
|
|
+
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ PhysPortIndex = NetIndex;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Both net modes */
|
|
|
+ Limit = PhysPortIndex + 1;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Single net mode */
|
|
|
+ PhysPortIndex = 0;
|
|
|
+ Limit = PhysPortMax;
|
|
|
+
|
|
|
+ /* Dual net mode */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ PhysPortIndex = NetIndex;
|
|
|
+ Limit = PhysPortIndex + 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Currently only get requests are allowed.
|
|
|
+ */
|
|
|
+ if (Action != SK_PNMI_GET) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_READ_ONLY);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check if the buffer length is large enough.
|
|
|
+ */
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_PORT_INDEX:
|
|
|
+ case OID_SKGE_RLMT_STATUS:
|
|
|
+ if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
|
|
|
+
|
|
|
+ *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_TX_HELLO_CTS:
|
|
|
+ case OID_SKGE_RLMT_RX_HELLO_CTS:
|
|
|
+ case OID_SKGE_RLMT_TX_SP_REQ_CTS:
|
|
|
+ case OID_SKGE_RLMT_RX_SP_CTS:
|
|
|
+ if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
|
|
|
+
|
|
|
+ *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
|
|
|
+ SK_PNMI_ERR039MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Update statistic and increment semaphores to indicate that
|
|
|
+ * an update was already done.
|
|
|
+ */
|
|
|
+ if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (Ret);
|
|
|
+ }
|
|
|
+ pAC->Pnmi.RlmtUpdatedFlag ++;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get value
|
|
|
+ */
|
|
|
+ Offset = 0;
|
|
|
+ for (; PhysPortIndex < Limit; PhysPortIndex ++) {
|
|
|
+
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_PORT_INDEX:
|
|
|
+ Val32 = PhysPortIndex;
|
|
|
+ SK_PNMI_STORE_U32(pBuf + Offset, Val32);
|
|
|
+ Offset += sizeof(SK_U32);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_STATUS:
|
|
|
+ if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
|
|
|
+ SK_RLMT_PS_INIT ||
|
|
|
+ pAC->Rlmt.Port[PhysPortIndex].PortState ==
|
|
|
+ SK_RLMT_PS_DOWN) {
|
|
|
+
|
|
|
+ Val32 = SK_PNMI_RLMT_STATUS_ERROR;
|
|
|
+ }
|
|
|
+ else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
|
|
|
+
|
|
|
+ Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
|
|
|
+ }
|
|
|
+ SK_PNMI_STORE_U32(pBuf + Offset, Val32);
|
|
|
+ Offset += sizeof(SK_U32);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_TX_HELLO_CTS:
|
|
|
+ Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
|
|
|
+ SK_PNMI_STORE_U64(pBuf + Offset, Val64);
|
|
|
+ Offset += sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_RX_HELLO_CTS:
|
|
|
+ Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
|
|
|
+ SK_PNMI_STORE_U64(pBuf + Offset, Val64);
|
|
|
+ Offset += sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_TX_SP_REQ_CTS:
|
|
|
+ Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
|
|
|
+ SK_PNMI_STORE_U64(pBuf + Offset, Val64);
|
|
|
+ Offset += sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_RX_SP_CTS:
|
|
|
+ Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
|
|
|
+ SK_PNMI_STORE_U64(pBuf + Offset, Val64);
|
|
|
+ Offset += sizeof(SK_U64);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
|
|
|
+ ("RlmtStat: Unknown OID should be errored before"));
|
|
|
+
|
|
|
+ pAC->Pnmi.RlmtUpdatedFlag --;
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ *pLen = Offset;
|
|
|
+
|
|
|
+ pAC->Pnmi.RlmtUpdatedFlag --;
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * MacPrivateConf - OID handler function of OIDs concerning the configuration
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Get/Presets/Sets the OIDs concerning the configuration.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK The request was successfully performed.
|
|
|
+ * SK_PNMI_ERR_GENERAL A general severe internal error occured.
|
|
|
+ * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
|
|
|
+ * the correct data (e.g. a 32bit value is
|
|
|
+ * needed, but a 16 bit value was passed).
|
|
|
+ * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
|
|
|
+ * value range.
|
|
|
+ * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
|
|
|
+ * exist (e.g. port instance 3 on a two port
|
|
|
+ * adapter.
|
|
|
+ */
|
|
|
+PNMI_STATIC int MacPrivateConf(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+int Action, /* Get/PreSet/Set action */
|
|
|
+SK_U32 Id, /* Object ID that is to be processed */
|
|
|
+char *pBuf, /* Buffer to which to mgmt data will be retrieved */
|
|
|
+unsigned int *pLen, /* On call: buffer length. On return: used buffer */
|
|
|
+SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
|
|
|
+unsigned int TableIndex, /* Index to the Id table */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+ unsigned int PhysPortMax;
|
|
|
+ unsigned int PhysPortIndex;
|
|
|
+ unsigned int LogPortMax;
|
|
|
+ unsigned int LogPortIndex;
|
|
|
+ unsigned int Limit;
|
|
|
+ unsigned int Offset;
|
|
|
+ char Val8;
|
|
|
+ int Ret;
|
|
|
+ SK_EVPARA EventParam;
|
|
|
+ SK_U32 Val32;
|
|
|
+
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Calculate instance if wished. MAC index 0 is the virtual
|
|
|
+ * MAC.
|
|
|
+ */
|
|
|
+ PhysPortMax = pAC->GIni.GIMacsFound;
|
|
|
+ LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
|
|
|
+
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
|
|
|
+ LogPortMax--;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
|
|
|
+ /* Check instance range */
|
|
|
+ if ((Instance < 1) || (Instance > LogPortMax)) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_UNKNOWN_INST);
|
|
|
+ }
|
|
|
+ LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
|
|
|
+ Limit = LogPortIndex + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
|
|
|
+
|
|
|
+ LogPortIndex = 0;
|
|
|
+ Limit = LogPortMax;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Perform action
|
|
|
+ */
|
|
|
+ if (Action == SK_PNMI_GET) {
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check length
|
|
|
+ */
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_SKGE_PMD:
|
|
|
+ case OID_SKGE_CONNECTOR:
|
|
|
+ case OID_SKGE_LINK_CAP:
|
|
|
+ case OID_SKGE_LINK_MODE:
|
|
|
+ case OID_SKGE_LINK_MODE_STATUS:
|
|
|
+ case OID_SKGE_LINK_STATUS:
|
|
|
+ case OID_SKGE_FLOWCTRL_CAP:
|
|
|
+ case OID_SKGE_FLOWCTRL_MODE:
|
|
|
+ case OID_SKGE_FLOWCTRL_STATUS:
|
|
|
+ case OID_SKGE_PHY_OPERATION_CAP:
|
|
|
+ case OID_SKGE_PHY_OPERATION_MODE:
|
|
|
+ case OID_SKGE_PHY_OPERATION_STATUS:
|
|
|
+ case OID_SKGE_SPEED_CAP:
|
|
|
+ case OID_SKGE_SPEED_MODE:
|
|
|
+ case OID_SKGE_SPEED_STATUS:
|
|
|
+ if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
|
|
|
+
|
|
|
+ *pLen = (Limit - LogPortIndex) *
|
|
|
+ sizeof(SK_U8);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_MTU:
|
|
|
+ if (*pLen < sizeof(SK_U32)) {
|
|
|
+
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
|
|
|
+ SK_PNMI_ERR041MSG);
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Update statistic and increment semaphore to indicate
|
|
|
+ * that an update was already done.
|
|
|
+ */
|
|
|
+ if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (Ret);
|
|
|
+ }
|
|
|
+ pAC->Pnmi.SirqUpdatedFlag ++;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get value
|
|
|
+ */
|
|
|
+ Offset = 0;
|
|
|
+ for (; LogPortIndex < Limit; LogPortIndex ++) {
|
|
|
+
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_SKGE_PMD:
|
|
|
+ *(pBuf + Offset) = pAC->Pnmi.PMD;
|
|
|
+ Offset += sizeof(char);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_CONNECTOR:
|
|
|
+ *(pBuf + Offset) = pAC->Pnmi.Connector;
|
|
|
+ Offset += sizeof(char);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_LINK_CAP:
|
|
|
+ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
|
|
|
+ if (LogPortIndex == 0) {
|
|
|
+
|
|
|
+ /* Get value for virtual port */
|
|
|
+ VirtualConf(pAC, IoC, Id, pBuf +
|
|
|
+ Offset);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Get value for physical ports */
|
|
|
+ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
|
|
|
+ pAC, LogPortIndex);
|
|
|
+
|
|
|
+ *(pBuf + Offset) = pAC->GIni.GP[
|
|
|
+ PhysPortIndex].PLinkCap;
|
|
|
+ }
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ else { /* DualNetMode */
|
|
|
+
|
|
|
+ *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkCap;
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_LINK_MODE:
|
|
|
+ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
|
|
|
+ if (LogPortIndex == 0) {
|
|
|
+
|
|
|
+ /* Get value for virtual port */
|
|
|
+ VirtualConf(pAC, IoC, Id, pBuf +
|
|
|
+ Offset);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Get value for physical ports */
|
|
|
+ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
|
|
|
+ pAC, LogPortIndex);
|
|
|
+
|
|
|
+ *(pBuf + Offset) = pAC->GIni.GP[
|
|
|
+ PhysPortIndex].PLinkModeConf;
|
|
|
+ }
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ else { /* DualNetMode */
|
|
|
+
|
|
|
+ *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkModeConf;
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_LINK_MODE_STATUS:
|
|
|
+ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
|
|
|
+ if (LogPortIndex == 0) {
|
|
|
+
|
|
|
+ /* Get value for virtual port */
|
|
|
+ VirtualConf(pAC, IoC, Id, pBuf +
|
|
|
+ Offset);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Get value for physical port */
|
|
|
+ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
|
|
|
+ pAC, LogPortIndex);
|
|
|
+
|
|
|
+ *(pBuf + Offset) =
|
|
|
+ CalculateLinkModeStatus(pAC,
|
|
|
+ IoC, PhysPortIndex);
|
|
|
+ }
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ else { /* DualNetMode */
|
|
|
+ *(pBuf + Offset) = CalculateLinkModeStatus(pAC, IoC, NetIndex);
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_LINK_STATUS:
|
|
|
+ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
|
|
|
+ if (LogPortIndex == 0) {
|
|
|
+
|
|
|
+ /* Get value for virtual port */
|
|
|
+ VirtualConf(pAC, IoC, Id, pBuf +
|
|
|
+ Offset);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Get value for physical ports */
|
|
|
+ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
|
|
|
+ pAC, LogPortIndex);
|
|
|
+
|
|
|
+ *(pBuf + Offset) =
|
|
|
+ CalculateLinkStatus(pAC,
|
|
|
+ IoC, PhysPortIndex);
|
|
|
+ }
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ else { /* DualNetMode */
|
|
|
+
|
|
|
+ *(pBuf + Offset) = CalculateLinkStatus(pAC, IoC, NetIndex);
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_FLOWCTRL_CAP:
|
|
|
+ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
|
|
|
+ if (LogPortIndex == 0) {
|
|
|
+
|
|
|
+ /* Get value for virtual port */
|
|
|
+ VirtualConf(pAC, IoC, Id, pBuf +
|
|
|
+ Offset);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Get value for physical ports */
|
|
|
+ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
|
|
|
+ pAC, LogPortIndex);
|
|
|
+
|
|
|
+ *(pBuf + Offset) = pAC->GIni.GP[
|
|
|
+ PhysPortIndex].PFlowCtrlCap;
|
|
|
+ }
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ else { /* DualNetMode */
|
|
|
+
|
|
|
+ *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_FLOWCTRL_MODE:
|
|
|
+ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
|
|
|
+ if (LogPortIndex == 0) {
|
|
|
+
|
|
|
+ /* Get value for virtual port */
|
|
|
+ VirtualConf(pAC, IoC, Id, pBuf +
|
|
|
+ Offset);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Get value for physical port */
|
|
|
+ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
|
|
|
+ pAC, LogPortIndex);
|
|
|
+
|
|
|
+ *(pBuf + Offset) = pAC->GIni.GP[
|
|
|
+ PhysPortIndex].PFlowCtrlMode;
|
|
|
+ }
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ else { /* DualNetMode */
|
|
|
+
|
|
|
+ *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_FLOWCTRL_STATUS:
|
|
|
+ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
|
|
|
+ if (LogPortIndex == 0) {
|
|
|
+
|
|
|
+ /* Get value for virtual port */
|
|
|
+ VirtualConf(pAC, IoC, Id, pBuf +
|
|
|
+ Offset);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Get value for physical port */
|
|
|
+ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
|
|
|
+ pAC, LogPortIndex);
|
|
|
+
|
|
|
+ *(pBuf + Offset) = pAC->GIni.GP[
|
|
|
+ PhysPortIndex].PFlowCtrlStatus;
|
|
|
+ }
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ else { /* DualNetMode */
|
|
|
+
|
|
|
+ *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_PHY_OPERATION_CAP:
|
|
|
+ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
|
|
|
+ if (LogPortIndex == 0) {
|
|
|
+
|
|
|
+ /* Get value for virtual port */
|
|
|
+ VirtualConf(pAC, IoC, Id, pBuf +
|
|
|
+ Offset);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Get value for physical ports */
|
|
|
+ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
|
|
|
+ pAC, LogPortIndex);
|
|
|
+
|
|
|
+ *(pBuf + Offset) = pAC->GIni.GP[
|
|
|
+ PhysPortIndex].PMSCap;
|
|
|
+ }
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ else { /* DualNetMode */
|
|
|
+
|
|
|
+ *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSCap;
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_PHY_OPERATION_MODE:
|
|
|
+ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
|
|
|
+ if (LogPortIndex == 0) {
|
|
|
+
|
|
|
+ /* Get value for virtual port */
|
|
|
+ VirtualConf(pAC, IoC, Id, pBuf + Offset);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Get value for physical port */
|
|
|
+ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
|
|
|
+ pAC, LogPortIndex);
|
|
|
+
|
|
|
+ *(pBuf + Offset) = pAC->GIni.GP[
|
|
|
+ PhysPortIndex].PMSMode;
|
|
|
+ }
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ else { /* DualNetMode */
|
|
|
+
|
|
|
+ *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSMode;
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_PHY_OPERATION_STATUS:
|
|
|
+ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
|
|
|
+ if (LogPortIndex == 0) {
|
|
|
+
|
|
|
+ /* Get value for virtual port */
|
|
|
+ VirtualConf(pAC, IoC, Id, pBuf + Offset);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Get value for physical port */
|
|
|
+ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
|
|
|
+ pAC, LogPortIndex);
|
|
|
+
|
|
|
+ *(pBuf + Offset) = pAC->GIni.GP[
|
|
|
+ PhysPortIndex].PMSStatus;
|
|
|
+ }
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+
|
|
|
+ *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSStatus;
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SPEED_CAP:
|
|
|
+ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
|
|
|
+ if (LogPortIndex == 0) {
|
|
|
+
|
|
|
+ /* Get value for virtual port */
|
|
|
+ VirtualConf(pAC, IoC, Id, pBuf +
|
|
|
+ Offset);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Get value for physical ports */
|
|
|
+ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
|
|
|
+ pAC, LogPortIndex);
|
|
|
+
|
|
|
+ *(pBuf + Offset) = pAC->GIni.GP[
|
|
|
+ PhysPortIndex].PLinkSpeedCap;
|
|
|
+ }
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ else { /* DualNetMode */
|
|
|
+
|
|
|
+ *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SPEED_MODE:
|
|
|
+ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
|
|
|
+ if (LogPortIndex == 0) {
|
|
|
+
|
|
|
+ /* Get value for virtual port */
|
|
|
+ VirtualConf(pAC, IoC, Id, pBuf + Offset);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Get value for physical port */
|
|
|
+ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
|
|
|
+ pAC, LogPortIndex);
|
|
|
+
|
|
|
+ *(pBuf + Offset) = pAC->GIni.GP[
|
|
|
+ PhysPortIndex].PLinkSpeed;
|
|
|
+ }
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ else { /* DualNetMode */
|
|
|
+
|
|
|
+ *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeed;
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SPEED_STATUS:
|
|
|
+ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
|
|
|
+ if (LogPortIndex == 0) {
|
|
|
+
|
|
|
+ /* Get value for virtual port */
|
|
|
+ VirtualConf(pAC, IoC, Id, pBuf + Offset);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Get value for physical port */
|
|
|
+ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
|
|
|
+ pAC, LogPortIndex);
|
|
|
+
|
|
|
+ *(pBuf + Offset) = pAC->GIni.GP[
|
|
|
+ PhysPortIndex].PLinkSpeedUsed;
|
|
|
+ }
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ else { /* DualNetMode */
|
|
|
+
|
|
|
+ *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
|
|
|
+ Offset += sizeof(char);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_MTU:
|
|
|
+ Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
|
|
|
+ SK_PNMI_STORE_U32(pBuf + Offset, Val32);
|
|
|
+ Offset += sizeof(SK_U32);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
|
|
|
+ ("MacPrivateConf: Unknown OID should be handled before"));
|
|
|
+
|
|
|
+ pAC->Pnmi.SirqUpdatedFlag --;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ *pLen = Offset;
|
|
|
+ pAC->Pnmi.SirqUpdatedFlag --;
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * From here SET or PRESET action. Check if the passed
|
|
|
+ * buffer length is plausible.
|
|
|
+ */
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_SKGE_LINK_MODE:
|
|
|
+ case OID_SKGE_FLOWCTRL_MODE:
|
|
|
+ case OID_SKGE_PHY_OPERATION_MODE:
|
|
|
+ case OID_SKGE_SPEED_MODE:
|
|
|
+ if (*pLen < Limit - LogPortIndex) {
|
|
|
+
|
|
|
+ *pLen = Limit - LogPortIndex;
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ if (*pLen != Limit - LogPortIndex) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_BAD_VALUE);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_MTU:
|
|
|
+ if (*pLen < sizeof(SK_U32)) {
|
|
|
+
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ if (*pLen != sizeof(SK_U32)) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_BAD_VALUE);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_READ_ONLY);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Perform preset or set
|
|
|
+ */
|
|
|
+ Offset = 0;
|
|
|
+ for (; LogPortIndex < Limit; LogPortIndex ++) {
|
|
|
+
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_SKGE_LINK_MODE:
|
|
|
+ /* Check the value range */
|
|
|
+ Val8 = *(pBuf + Offset);
|
|
|
+ if (Val8 == 0) {
|
|
|
+
|
|
|
+ Offset += sizeof(char);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (Val8 < SK_LMODE_HALF ||
|
|
|
+ (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
|
|
|
+ (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_BAD_VALUE);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* The preset ends here */
|
|
|
+ if (Action == SK_PNMI_PRESET) {
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (LogPortIndex == 0) {
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The virtual port consists of all currently
|
|
|
+ * active ports. Find them and send an event
|
|
|
+ * with the new link mode to SIRQ.
|
|
|
+ */
|
|
|
+ for (PhysPortIndex = 0;
|
|
|
+ PhysPortIndex < PhysPortMax;
|
|
|
+ PhysPortIndex ++) {
|
|
|
+
|
|
|
+ if (!pAC->Pnmi.Port[PhysPortIndex].
|
|
|
+ ActiveFlag) {
|
|
|
+
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ EventParam.Para32[0] = PhysPortIndex;
|
|
|
+ EventParam.Para32[1] = (SK_U32)Val8;
|
|
|
+ if (SkGeSirqEvent(pAC, IoC,
|
|
|
+ SK_HWEV_SET_LMODE,
|
|
|
+ EventParam) > 0) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW,
|
|
|
+ SK_PNMI_ERR043,
|
|
|
+ SK_PNMI_ERR043MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /*
|
|
|
+ * Send an event with the new link mode to
|
|
|
+ * the SIRQ module.
|
|
|
+ */
|
|
|
+ EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
|
|
|
+ pAC, LogPortIndex);
|
|
|
+ EventParam.Para32[1] = (SK_U32)Val8;
|
|
|
+ if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
|
|
|
+ EventParam) > 0) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW,
|
|
|
+ SK_PNMI_ERR043,
|
|
|
+ SK_PNMI_ERR043MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Offset += sizeof(char);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_FLOWCTRL_MODE:
|
|
|
+ /* Check the value range */
|
|
|
+ Val8 = *(pBuf + Offset);
|
|
|
+ if (Val8 == 0) {
|
|
|
+
|
|
|
+ Offset += sizeof(char);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (Val8 < SK_FLOW_MODE_NONE ||
|
|
|
+ (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
|
|
|
+ (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_BAD_VALUE);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* The preset ends here */
|
|
|
+ if (Action == SK_PNMI_PRESET) {
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (LogPortIndex == 0) {
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The virtual port consists of all currently
|
|
|
+ * active ports. Find them and send an event
|
|
|
+ * with the new flow control mode to SIRQ.
|
|
|
+ */
|
|
|
+ for (PhysPortIndex = 0;
|
|
|
+ PhysPortIndex < PhysPortMax;
|
|
|
+ PhysPortIndex ++) {
|
|
|
+
|
|
|
+ if (!pAC->Pnmi.Port[PhysPortIndex].
|
|
|
+ ActiveFlag) {
|
|
|
+
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ EventParam.Para32[0] = PhysPortIndex;
|
|
|
+ EventParam.Para32[1] = (SK_U32)Val8;
|
|
|
+ if (SkGeSirqEvent(pAC, IoC,
|
|
|
+ SK_HWEV_SET_FLOWMODE,
|
|
|
+ EventParam) > 0) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW,
|
|
|
+ SK_PNMI_ERR044,
|
|
|
+ SK_PNMI_ERR044MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /*
|
|
|
+ * Send an event with the new flow control
|
|
|
+ * mode to the SIRQ module.
|
|
|
+ */
|
|
|
+ EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
|
|
|
+ pAC, LogPortIndex);
|
|
|
+ EventParam.Para32[1] = (SK_U32)Val8;
|
|
|
+ if (SkGeSirqEvent(pAC, IoC,
|
|
|
+ SK_HWEV_SET_FLOWMODE, EventParam)
|
|
|
+ > 0) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW,
|
|
|
+ SK_PNMI_ERR044,
|
|
|
+ SK_PNMI_ERR044MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Offset += sizeof(char);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_PHY_OPERATION_MODE :
|
|
|
+ /* Check the value range */
|
|
|
+ Val8 = *(pBuf + Offset);
|
|
|
+ if (Val8 == 0) {
|
|
|
+ /* mode of this port remains unchanged */
|
|
|
+ Offset += sizeof(char);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (Val8 < SK_MS_MODE_AUTO ||
|
|
|
+ (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
|
|
|
+ (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_BAD_VALUE);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* The preset ends here */
|
|
|
+ if (Action == SK_PNMI_PRESET) {
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (LogPortIndex == 0) {
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The virtual port consists of all currently
|
|
|
+ * active ports. Find them and send an event
|
|
|
+ * with new master/slave (role) mode to SIRQ.
|
|
|
+ */
|
|
|
+ for (PhysPortIndex = 0;
|
|
|
+ PhysPortIndex < PhysPortMax;
|
|
|
+ PhysPortIndex ++) {
|
|
|
+
|
|
|
+ if (!pAC->Pnmi.Port[PhysPortIndex].
|
|
|
+ ActiveFlag) {
|
|
|
+
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ EventParam.Para32[0] = PhysPortIndex;
|
|
|
+ EventParam.Para32[1] = (SK_U32)Val8;
|
|
|
+ if (SkGeSirqEvent(pAC, IoC,
|
|
|
+ SK_HWEV_SET_ROLE,
|
|
|
+ EventParam) > 0) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW,
|
|
|
+ SK_PNMI_ERR042,
|
|
|
+ SK_PNMI_ERR042MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /*
|
|
|
+ * Send an event with the new master/slave
|
|
|
+ * (role) mode to the SIRQ module.
|
|
|
+ */
|
|
|
+ EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
|
|
|
+ pAC, LogPortIndex);
|
|
|
+ EventParam.Para32[1] = (SK_U32)Val8;
|
|
|
+ if (SkGeSirqEvent(pAC, IoC,
|
|
|
+ SK_HWEV_SET_ROLE, EventParam) > 0) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW,
|
|
|
+ SK_PNMI_ERR042,
|
|
|
+ SK_PNMI_ERR042MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Offset += sizeof(char);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SPEED_MODE:
|
|
|
+ /* Check the value range */
|
|
|
+ Val8 = *(pBuf + Offset);
|
|
|
+ if (Val8 == 0) {
|
|
|
+
|
|
|
+ Offset += sizeof(char);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (Val8 < (SK_LSPEED_AUTO) ||
|
|
|
+ (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) ||
|
|
|
+ (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_BAD_VALUE);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* The preset ends here */
|
|
|
+ if (Action == SK_PNMI_PRESET) {
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (LogPortIndex == 0) {
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The virtual port consists of all currently
|
|
|
+ * active ports. Find them and send an event
|
|
|
+ * with the new flow control mode to SIRQ.
|
|
|
+ */
|
|
|
+ for (PhysPortIndex = 0;
|
|
|
+ PhysPortIndex < PhysPortMax;
|
|
|
+ PhysPortIndex ++) {
|
|
|
+
|
|
|
+ if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
|
|
|
+
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ EventParam.Para32[0] = PhysPortIndex;
|
|
|
+ EventParam.Para32[1] = (SK_U32)Val8;
|
|
|
+ if (SkGeSirqEvent(pAC, IoC,
|
|
|
+ SK_HWEV_SET_SPEED,
|
|
|
+ EventParam) > 0) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW,
|
|
|
+ SK_PNMI_ERR045,
|
|
|
+ SK_PNMI_ERR045MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /*
|
|
|
+ * Send an event with the new flow control
|
|
|
+ * mode to the SIRQ module.
|
|
|
+ */
|
|
|
+ EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
|
|
|
+ pAC, LogPortIndex);
|
|
|
+ EventParam.Para32[1] = (SK_U32)Val8;
|
|
|
+ if (SkGeSirqEvent(pAC, IoC,
|
|
|
+ SK_HWEV_SET_SPEED,
|
|
|
+ EventParam) > 0) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW,
|
|
|
+ SK_PNMI_ERR045,
|
|
|
+ SK_PNMI_ERR045MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Offset += sizeof(char);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_MTU :
|
|
|
+ /* Check the value range */
|
|
|
+ Val32 = *(SK_U32*)(pBuf + Offset);
|
|
|
+ if (Val32 == 0) {
|
|
|
+ /* mtu of this port remains unchanged */
|
|
|
+ Offset += sizeof(SK_U32);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_BAD_VALUE);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* The preset ends here */
|
|
|
+ if (Action == SK_PNMI_PRESET) {
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ Offset += sizeof(SK_U32);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
|
|
|
+ ("MacPrivateConf: Unknown OID should be handled before set"));
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * Monitor - OID handler function for RLMT_MONITOR_XXX
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Because RLMT currently does not support the monitoring of
|
|
|
+ * remote adapter cards, we return always an empty table.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK The request was successfully performed.
|
|
|
+ * SK_PNMI_ERR_GENERAL A general severe internal error occured.
|
|
|
+ * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
|
|
|
+ * the correct data (e.g. a 32bit value is
|
|
|
+ * needed, but a 16 bit value was passed).
|
|
|
+ * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
|
|
|
+ * value range.
|
|
|
+ * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
|
|
|
+ * exist (e.g. port instance 3 on a two port
|
|
|
+ * adapter.
|
|
|
+ */
|
|
|
+PNMI_STATIC int Monitor(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+int Action, /* Get/PreSet/Set action */
|
|
|
+SK_U32 Id, /* Object ID that is to be processed */
|
|
|
+char *pBuf, /* Buffer to which to mgmt data will be retrieved */
|
|
|
+unsigned int *pLen, /* On call: buffer length. On return: used buffer */
|
|
|
+SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
|
|
|
+unsigned int TableIndex, /* Index to the Id table */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+ unsigned int Index;
|
|
|
+ unsigned int Limit;
|
|
|
+ unsigned int Offset;
|
|
|
+ unsigned int Entries;
|
|
|
+
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Calculate instance if wished.
|
|
|
+ */
|
|
|
+/* XXX Not yet implemented. Return always an empty table. */
|
|
|
+ Entries = 0;
|
|
|
+
|
|
|
+ if ((Instance != (SK_U32)(-1))) {
|
|
|
+
|
|
|
+ if ((Instance < 1) || (Instance > Entries)) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_UNKNOWN_INST);
|
|
|
+ }
|
|
|
+
|
|
|
+ Index = (unsigned int)Instance - 1;
|
|
|
+ Limit = (unsigned int)Instance;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ Index = 0;
|
|
|
+ Limit = Entries;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get/Set value
|
|
|
+ */
|
|
|
+ if (Action == SK_PNMI_GET) {
|
|
|
+
|
|
|
+ for (Offset=0; Index < Limit; Index ++) {
|
|
|
+
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_SKGE_RLMT_MONITOR_INDEX:
|
|
|
+ case OID_SKGE_RLMT_MONITOR_ADDR:
|
|
|
+ case OID_SKGE_RLMT_MONITOR_ERRS:
|
|
|
+ case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
|
|
|
+ case OID_SKGE_RLMT_MONITOR_ADMIN:
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
|
|
|
+ SK_PNMI_ERR046MSG);
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ *pLen = Offset;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Only MONITOR_ADMIN can be set */
|
|
|
+ if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_READ_ONLY);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Check if the length is plausible */
|
|
|
+ if (*pLen < (Limit - Index)) {
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ /* Okay, we have a wide value range */
|
|
|
+ if (*pLen != (Limit - Index)) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_BAD_VALUE);
|
|
|
+ }
|
|
|
+/*
|
|
|
+ for (Offset=0; Index < Limit; Index ++) {
|
|
|
+ }
|
|
|
+*/
|
|
|
+/*
|
|
|
+ * XXX Not yet implemented. Return always BAD_VALUE, because the table
|
|
|
+ * is empty.
|
|
|
+ */
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_BAD_VALUE);
|
|
|
+ }
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * VirtualConf - Calculates the values of configuration OIDs for virtual port
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * We handle here the get of the configuration group OIDs, which are
|
|
|
+ * a little bit complicated. The virtual port consists of all currently
|
|
|
+ * active physical ports. If multiple ports are active and configured
|
|
|
+ * differently we get in some trouble to return a single value. So we
|
|
|
+ * get the value of the first active port and compare it with that of
|
|
|
+ * the other active ports. If they are not the same, we return a value
|
|
|
+ * that indicates that the state is indeterminated.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * Nothing
|
|
|
+ */
|
|
|
+PNMI_STATIC void VirtualConf(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+SK_U32 Id, /* Object ID that is to be processed */
|
|
|
+char *pBuf) /* Buffer to which to mgmt data will be retrieved */
|
|
|
+{
|
|
|
+ unsigned int PhysPortMax;
|
|
|
+ unsigned int PhysPortIndex;
|
|
|
+ SK_U8 Val8;
|
|
|
+ SK_BOOL PortActiveFlag;
|
|
|
+
|
|
|
+
|
|
|
+ *pBuf = 0;
|
|
|
+ PortActiveFlag = SK_FALSE;
|
|
|
+ PhysPortMax = pAC->GIni.GIMacsFound;
|
|
|
+
|
|
|
+ for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
|
|
|
+ PhysPortIndex ++) {
|
|
|
+
|
|
|
+ /* Check if the physical port is active */
|
|
|
+ if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
|
|
|
+
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ PortActiveFlag = SK_TRUE;
|
|
|
+
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_SKGE_LINK_CAP:
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Different capabilities should not happen, but
|
|
|
+ * in the case of the cases OR them all together.
|
|
|
+ * From a curious point of view the virtual port
|
|
|
+ * is capable of all found capabilities.
|
|
|
+ */
|
|
|
+ *pBuf |= pAC->GIni.GP[PhysPortIndex].PLinkCap;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_LINK_MODE:
|
|
|
+ /* Check if it is the first active port */
|
|
|
+ if (*pBuf == 0) {
|
|
|
+
|
|
|
+ *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If we find an active port with a different link
|
|
|
+ * mode than the first one we return a value that
|
|
|
+ * indicates that the link mode is indeterminated.
|
|
|
+ */
|
|
|
+ if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkModeConf
|
|
|
+ ) {
|
|
|
+
|
|
|
+ *pBuf = SK_LMODE_INDETERMINATED;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_LINK_MODE_STATUS:
|
|
|
+ /* Get the link mode of the physical port */
|
|
|
+ Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
|
|
|
+
|
|
|
+ /* Check if it is the first active port */
|
|
|
+ if (*pBuf == 0) {
|
|
|
+
|
|
|
+ *pBuf = Val8;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If we find an active port with a different link
|
|
|
+ * mode status than the first one we return a value
|
|
|
+ * that indicates that the link mode status is
|
|
|
+ * indeterminated.
|
|
|
+ */
|
|
|
+ if (*pBuf != Val8) {
|
|
|
+
|
|
|
+ *pBuf = SK_LMODE_STAT_INDETERMINATED;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_LINK_STATUS:
|
|
|
+ /* Get the link status of the physical port */
|
|
|
+ Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
|
|
|
+
|
|
|
+ /* Check if it is the first active port */
|
|
|
+ if (*pBuf == 0) {
|
|
|
+
|
|
|
+ *pBuf = Val8;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If we find an active port with a different link
|
|
|
+ * status than the first one, we return a value
|
|
|
+ * that indicates that the link status is
|
|
|
+ * indeterminated.
|
|
|
+ */
|
|
|
+ if (*pBuf != Val8) {
|
|
|
+
|
|
|
+ *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_FLOWCTRL_CAP:
|
|
|
+ /* Check if it is the first active port */
|
|
|
+ if (*pBuf == 0) {
|
|
|
+
|
|
|
+ *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * From a curious point of view the virtual port
|
|
|
+ * is capable of all found capabilities.
|
|
|
+ */
|
|
|
+ *pBuf |= pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_FLOWCTRL_MODE:
|
|
|
+ /* Check if it is the first active port */
|
|
|
+ if (*pBuf == 0) {
|
|
|
+
|
|
|
+ *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If we find an active port with a different flow
|
|
|
+ * control mode than the first one, we return a value
|
|
|
+ * that indicates that the mode is indeterminated.
|
|
|
+ */
|
|
|
+ if (*pBuf != pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode) {
|
|
|
+
|
|
|
+ *pBuf = SK_FLOW_MODE_INDETERMINATED;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_FLOWCTRL_STATUS:
|
|
|
+ /* Check if it is the first active port */
|
|
|
+ if (*pBuf == 0) {
|
|
|
+
|
|
|
+ *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If we find an active port with a different flow
|
|
|
+ * control status than the first one, we return a
|
|
|
+ * value that indicates that the status is
|
|
|
+ * indeterminated.
|
|
|
+ */
|
|
|
+ if (*pBuf != pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus) {
|
|
|
+
|
|
|
+ *pBuf = SK_FLOW_STAT_INDETERMINATED;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_PHY_OPERATION_CAP:
|
|
|
+ /* Check if it is the first active port */
|
|
|
+ if (*pBuf == 0) {
|
|
|
+
|
|
|
+ *pBuf = pAC->GIni.GP[PhysPortIndex].PMSCap;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * From a curious point of view the virtual port
|
|
|
+ * is capable of all found capabilities.
|
|
|
+ */
|
|
|
+ *pBuf |= pAC->GIni.GP[PhysPortIndex].PMSCap;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_PHY_OPERATION_MODE:
|
|
|
+ /* Check if it is the first active port */
|
|
|
+ if (*pBuf == 0) {
|
|
|
+
|
|
|
+ *pBuf = pAC->GIni.GP[PhysPortIndex].PMSMode;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If we find an active port with a different master/
|
|
|
+ * slave mode than the first one, we return a value
|
|
|
+ * that indicates that the mode is indeterminated.
|
|
|
+ */
|
|
|
+ if (*pBuf != pAC->GIni.GP[PhysPortIndex].PMSMode) {
|
|
|
+
|
|
|
+ *pBuf = SK_MS_MODE_INDETERMINATED;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_PHY_OPERATION_STATUS:
|
|
|
+ /* Check if it is the first active port */
|
|
|
+ if (*pBuf == 0) {
|
|
|
+
|
|
|
+ *pBuf = pAC->GIni.GP[PhysPortIndex].PMSStatus;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If we find an active port with a different master/
|
|
|
+ * slave status than the first one, we return a
|
|
|
+ * value that indicates that the status is
|
|
|
+ * indeterminated.
|
|
|
+ */
|
|
|
+ if (*pBuf != pAC->GIni.GP[PhysPortIndex].PMSStatus) {
|
|
|
+
|
|
|
+ *pBuf = SK_MS_STAT_INDETERMINATED;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SPEED_MODE:
|
|
|
+ /* Check if it is the first active port */
|
|
|
+ if (*pBuf == 0) {
|
|
|
+
|
|
|
+ *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If we find an active port with a different flow
|
|
|
+ * control mode than the first one, we return a value
|
|
|
+ * that indicates that the mode is indeterminated.
|
|
|
+ */
|
|
|
+ if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkSpeed) {
|
|
|
+
|
|
|
+ *pBuf = SK_LSPEED_INDETERMINATED;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SPEED_STATUS:
|
|
|
+ /* Check if it is the first active port */
|
|
|
+ if (*pBuf == 0) {
|
|
|
+
|
|
|
+ *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If we find an active port with a different flow
|
|
|
+ * control status than the first one, we return a
|
|
|
+ * value that indicates that the status is
|
|
|
+ * indeterminated.
|
|
|
+ */
|
|
|
+ if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed) {
|
|
|
+
|
|
|
+ *pBuf = SK_LSPEED_STAT_INDETERMINATED;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If no port is active return an indeterminated answer
|
|
|
+ */
|
|
|
+ if (!PortActiveFlag) {
|
|
|
+
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_SKGE_LINK_CAP:
|
|
|
+ *pBuf = SK_LMODE_CAP_INDETERMINATED;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_LINK_MODE:
|
|
|
+ *pBuf = SK_LMODE_INDETERMINATED;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_LINK_MODE_STATUS:
|
|
|
+ *pBuf = SK_LMODE_STAT_INDETERMINATED;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_LINK_STATUS:
|
|
|
+ *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_FLOWCTRL_CAP:
|
|
|
+ case OID_SKGE_FLOWCTRL_MODE:
|
|
|
+ *pBuf = SK_FLOW_MODE_INDETERMINATED;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_FLOWCTRL_STATUS:
|
|
|
+ *pBuf = SK_FLOW_STAT_INDETERMINATED;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_PHY_OPERATION_CAP:
|
|
|
+ *pBuf = SK_MS_CAP_INDETERMINATED;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_PHY_OPERATION_MODE:
|
|
|
+ *pBuf = SK_MS_MODE_INDETERMINATED;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_PHY_OPERATION_STATUS:
|
|
|
+ *pBuf = SK_MS_STAT_INDETERMINATED;
|
|
|
+ break;
|
|
|
+ case OID_SKGE_SPEED_CAP:
|
|
|
+ *pBuf = SK_LSPEED_CAP_INDETERMINATED;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SPEED_MODE:
|
|
|
+ *pBuf = SK_LSPEED_INDETERMINATED;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_SPEED_STATUS:
|
|
|
+ *pBuf = SK_LSPEED_STAT_INDETERMINATED;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * CalculateLinkStatus - Determins the link status of a physical port
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Determins the link status the following way:
|
|
|
+ * LSTAT_PHY_DOWN: Link is down
|
|
|
+ * LSTAT_AUTONEG: Auto-negotiation failed
|
|
|
+ * LSTAT_LOG_DOWN: Link is up but RLMT did not yet put the port
|
|
|
+ * logically up.
|
|
|
+ * LSTAT_LOG_UP: RLMT marked the port as up
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * Link status of physical port
|
|
|
+ */
|
|
|
+PNMI_STATIC SK_U8 CalculateLinkStatus(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+unsigned int PhysPortIndex) /* Physical port index */
|
|
|
+{
|
|
|
+ SK_U8 Result;
|
|
|
+
|
|
|
+
|
|
|
+ if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
|
|
|
+
|
|
|
+ Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
|
|
|
+ }
|
|
|
+ else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
|
|
|
+
|
|
|
+ Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
|
|
|
+ }
|
|
|
+ else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
|
|
|
+
|
|
|
+ Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
|
|
|
+ }
|
|
|
+
|
|
|
+ return (Result);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * CalculateLinkModeStatus - Determins the link mode status of a phys. port
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * The COMMON module only tells us if the mode is half or full duplex.
|
|
|
+ * But in the decade of auto sensing it is usefull for the user to
|
|
|
+ * know if the mode was negotiated or forced. Therefore we have a
|
|
|
+ * look to the mode, which was last used by the negotiation process.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * The link mode status
|
|
|
+ */
|
|
|
+PNMI_STATIC SK_U8 CalculateLinkModeStatus(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+unsigned int PhysPortIndex) /* Physical port index */
|
|
|
+{
|
|
|
+ SK_U8 Result;
|
|
|
+
|
|
|
+
|
|
|
+ /* Get the current mode, which can be full or half duplex */
|
|
|
+ Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
|
|
|
+
|
|
|
+ /* Check if no valid mode could be found (link is down) */
|
|
|
+ if (Result < SK_LMODE_STAT_HALF) {
|
|
|
+
|
|
|
+ Result = SK_LMODE_STAT_UNKNOWN;
|
|
|
+ }
|
|
|
+ else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Auto-negotiation was used to bring up the link. Change
|
|
|
+ * the already found duplex status that it indicates
|
|
|
+ * auto-negotiation was involved.
|
|
|
+ */
|
|
|
+ if (Result == SK_LMODE_STAT_HALF) {
|
|
|
+
|
|
|
+ Result = SK_LMODE_STAT_AUTOHALF;
|
|
|
+ }
|
|
|
+ else if (Result == SK_LMODE_STAT_FULL) {
|
|
|
+
|
|
|
+ Result = SK_LMODE_STAT_AUTOFULL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (Result);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * GetVpdKeyArr - Obtain an array of VPD keys
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Read the VPD keys and build an array of VPD keys, which are
|
|
|
+ * easy to access.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK Task successfully performed.
|
|
|
+ * SK_PNMI_ERR_GENERAL Something went wrong.
|
|
|
+ */
|
|
|
+PNMI_STATIC int GetVpdKeyArr(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+char *pKeyArr, /* Ptr KeyArray */
|
|
|
+unsigned int KeyArrLen, /* Length of array in bytes */
|
|
|
+unsigned int *pKeyNo) /* Number of keys */
|
|
|
+{
|
|
|
+ unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE;
|
|
|
+ char BufKeys[SK_PNMI_VPD_BUFSIZE];
|
|
|
+ unsigned int StartOffset;
|
|
|
+ unsigned int Offset;
|
|
|
+ int Index;
|
|
|
+ int Ret;
|
|
|
+
|
|
|
+
|
|
|
+ SK_MEMSET(pKeyArr, 0, KeyArrLen);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get VPD key list
|
|
|
+ */
|
|
|
+ Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
|
|
|
+ (int *)pKeyNo);
|
|
|
+ if (Ret > 0) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
|
|
|
+ SK_PNMI_ERR014MSG);
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ /* If no keys are available return now */
|
|
|
+ if (*pKeyNo == 0 || BufKeysLen == 0) {
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ * If the key list is too long for us trunc it and give a
|
|
|
+ * errorlog notification. This case should not happen because
|
|
|
+ * the maximum number of keys is limited due to RAM limitations
|
|
|
+ */
|
|
|
+ if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
|
|
|
+ SK_PNMI_ERR015MSG);
|
|
|
+
|
|
|
+ *pKeyNo = SK_PNMI_VPD_ENTRIES;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Now build an array of fixed string length size and copy
|
|
|
+ * the keys together.
|
|
|
+ */
|
|
|
+ for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
|
|
|
+ Offset ++) {
|
|
|
+
|
|
|
+ if (BufKeys[Offset] != 0) {
|
|
|
+
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
|
|
|
+ SK_PNMI_ERR016MSG);
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
|
|
|
+ &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
|
|
|
+
|
|
|
+ Index ++;
|
|
|
+ StartOffset = Offset + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Last key not zero terminated? Get it anyway */
|
|
|
+ if (StartOffset < Offset) {
|
|
|
+
|
|
|
+ SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
|
|
|
+ &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
|
|
|
+ }
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * SirqUpdate - Let the SIRQ update its internal values
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Just to be sure that the SIRQ module holds its internal data
|
|
|
+ * structures up to date, we send an update event before we make
|
|
|
+ * any access.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK Task successfully performed.
|
|
|
+ * SK_PNMI_ERR_GENERAL Something went wrong.
|
|
|
+ */
|
|
|
+PNMI_STATIC int SirqUpdate(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC) /* IO context handle */
|
|
|
+{
|
|
|
+ SK_EVPARA EventParam;
|
|
|
+
|
|
|
+
|
|
|
+ /* Was the module already updated during the current PNMI call? */
|
|
|
+ if (pAC->Pnmi.SirqUpdatedFlag > 0) {
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Send an synchronuous update event to the module */
|
|
|
+ SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
|
|
|
+ if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
|
|
|
+ SK_PNMI_ERR047MSG);
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * RlmtUpdate - Let the RLMT update its internal values
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Just to be sure that the RLMT module holds its internal data
|
|
|
+ * structures up to date, we send an update event before we make
|
|
|
+ * any access.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK Task successfully performed.
|
|
|
+ * SK_PNMI_ERR_GENERAL Something went wrong.
|
|
|
+ */
|
|
|
+PNMI_STATIC int RlmtUpdate(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+ SK_EVPARA EventParam;
|
|
|
+
|
|
|
+
|
|
|
+ /* Was the module already updated during the current PNMI call? */
|
|
|
+ if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Send an synchronuous update event to the module */
|
|
|
+ SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
|
|
|
+ EventParam.Para32[0] = NetIndex;
|
|
|
+ EventParam.Para32[1] = (SK_U32)-1;
|
|
|
+ if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
|
|
|
+
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
|
|
|
+ SK_PNMI_ERR048MSG);
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * MacUpdate - Force the XMAC to output the current statistic
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * The XMAC holds its statistic internally. To obtain the current
|
|
|
+ * values we send a command so that the statistic data will
|
|
|
+ * be written to apredefined memory area on the adapter.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK Task successfully performed.
|
|
|
+ * SK_PNMI_ERR_GENERAL Something went wrong.
|
|
|
+ */
|
|
|
+PNMI_STATIC int MacUpdate(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+unsigned int FirstMac, /* Index of the first Mac to be updated */
|
|
|
+unsigned int LastMac) /* Index of the last Mac to be updated */
|
|
|
+{
|
|
|
+ unsigned int MacIndex;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Were the statistics already updated during the
|
|
|
+ * current PNMI call?
|
|
|
+ */
|
|
|
+ if (pAC->Pnmi.MacUpdatedFlag > 0) {
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Send an update command to all MACs specified */
|
|
|
+ for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 2002-09-13 pweber: Freeze the current sw counters.
|
|
|
+ * (That should be done as close as
|
|
|
+ * possible to the update of the
|
|
|
+ * hw counters)
|
|
|
+ */
|
|
|
+ if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
|
|
|
+ pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 2002-09-13 pweber: Update the hw counter */
|
|
|
+ if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * GetStatVal - Retrieve an XMAC statistic counter
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Retrieves the statistic counter of a virtual or physical port. The
|
|
|
+ * virtual port is identified by the index 0. It consists of all
|
|
|
+ * currently active ports. To obtain the counter value for this port
|
|
|
+ * we must add the statistic counter of all active ports. To grant
|
|
|
+ * continuous counter values for the virtual port even when port
|
|
|
+ * switches occur we must additionally add a delta value, which was
|
|
|
+ * calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * Requested statistic value
|
|
|
+ */
|
|
|
+PNMI_STATIC SK_U64 GetStatVal(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+unsigned int LogPortIndex, /* Index of the logical Port to be processed */
|
|
|
+unsigned int StatIndex, /* Index to statistic value */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+ unsigned int PhysPortIndex;
|
|
|
+ unsigned int PhysPortMax;
|
|
|
+ SK_U64 Val = 0;
|
|
|
+
|
|
|
+
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
|
|
|
+
|
|
|
+ PhysPortIndex = NetIndex;
|
|
|
+ Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
|
|
|
+ }
|
|
|
+ else { /* Single Net mode */
|
|
|
+
|
|
|
+ if (LogPortIndex == 0) {
|
|
|
+
|
|
|
+ PhysPortMax = pAC->GIni.GIMacsFound;
|
|
|
+
|
|
|
+ /* Add counter of all active ports */
|
|
|
+ for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
|
|
|
+ PhysPortIndex ++) {
|
|
|
+
|
|
|
+ if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
|
|
|
+
|
|
|
+ Val += GetPhysStatVal(pAC, IoC, PhysPortIndex,
|
|
|
+ StatIndex);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Correct value because of port switches */
|
|
|
+ Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Get counter value of physical port */
|
|
|
+ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
|
|
|
+ Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return (Val);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * GetPhysStatVal - Get counter value for physical port
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Builds a 64bit counter value. Except for the octet counters
|
|
|
+ * the lower 32bit are counted in hardware and the upper 32bit
|
|
|
+ * in software by monitoring counter overflow interrupts in the
|
|
|
+ * event handler. To grant continous counter values during XMAC
|
|
|
+ * resets (caused by a workaround) we must add a delta value.
|
|
|
+ * The delta was calculated in the event handler when a
|
|
|
+ * SK_PNMI_EVT_XMAC_RESET was received.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * Counter value
|
|
|
+ */
|
|
|
+PNMI_STATIC SK_U64 GetPhysStatVal(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+unsigned int PhysPortIndex, /* Index of the logical Port to be processed */
|
|
|
+unsigned int StatIndex) /* Index to statistic value */
|
|
|
+{
|
|
|
+ SK_U64 Val = 0;
|
|
|
+ SK_U32 LowVal = 0;
|
|
|
+ SK_U32 HighVal = 0;
|
|
|
+ SK_U16 Word;
|
|
|
+ int MacType;
|
|
|
+
|
|
|
+ SK_PNMI_PORT *pPnmiPrt;
|
|
|
+ SK_GEMACFUNC *pFnMac;
|
|
|
+
|
|
|
+ MacType = pAC->GIni.GIMacType;
|
|
|
+
|
|
|
+ /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
|
|
|
+ if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
|
|
|
+ pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex];
|
|
|
+ }
|
|
|
+
|
|
|
+ pFnMac = &pAC->GIni.GIFunc;
|
|
|
+
|
|
|
+ switch (StatIndex) {
|
|
|
+ case SK_PNMI_HTX:
|
|
|
+ case SK_PNMI_HRX:
|
|
|
+ /* Not supported by GMAC */
|
|
|
+ if (MacType == SK_MAC_GMAC) {
|
|
|
+ return (Val);
|
|
|
+ }
|
|
|
+
|
|
|
+ (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
|
|
|
+ StatAddr[StatIndex][MacType].Reg,
|
|
|
+ &LowVal);
|
|
|
+ HighVal = pPnmiPrt->CounterHigh[StatIndex];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_HTX_OCTET:
|
|
|
+ case SK_PNMI_HRX_OCTET:
|
|
|
+ (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
|
|
|
+ StatAddr[StatIndex][MacType].Reg,
|
|
|
+ &HighVal);
|
|
|
+ (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
|
|
|
+ StatAddr[StatIndex + 1][MacType].Reg,
|
|
|
+ &LowVal);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_HTX_BURST:
|
|
|
+ case SK_PNMI_HTX_EXCESS_DEF:
|
|
|
+ case SK_PNMI_HTX_CARRIER:
|
|
|
+ /* Not supported by GMAC */
|
|
|
+ if (MacType == SK_MAC_GMAC) {
|
|
|
+ return (Val);
|
|
|
+ }
|
|
|
+
|
|
|
+ (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
|
|
|
+ StatAddr[StatIndex][MacType].Reg,
|
|
|
+ &LowVal);
|
|
|
+ HighVal = pPnmiPrt->CounterHigh[StatIndex];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_HTX_MACC:
|
|
|
+ /* GMAC only supports PAUSE MAC control frames */
|
|
|
+ if (MacType == SK_MAC_GMAC) {
|
|
|
+ Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, SK_PNMI_HTX_PMACC);
|
|
|
+
|
|
|
+ return (Val);
|
|
|
+ }
|
|
|
+
|
|
|
+ (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
|
|
|
+ StatAddr[StatIndex][MacType].Reg,
|
|
|
+ &LowVal);
|
|
|
+ HighVal = pPnmiPrt->CounterHigh[StatIndex];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_HTX_COL:
|
|
|
+ case SK_PNMI_HRX_UNDERSIZE:
|
|
|
+ /* Not supported by XMAC */
|
|
|
+ if (MacType == SK_MAC_XMAC) {
|
|
|
+ return (Val);
|
|
|
+ }
|
|
|
+
|
|
|
+ (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
|
|
|
+ StatAddr[StatIndex][MacType].Reg,
|
|
|
+ &LowVal);
|
|
|
+ HighVal = pPnmiPrt->CounterHigh[StatIndex];
|
|
|
+ break;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ case SK_PNMI_HTX_DEFFERAL:
|
|
|
+ /* Not supported by GMAC */
|
|
|
+ if (MacType == SK_MAC_GMAC) {
|
|
|
+ return (Val);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * XMAC counts frames with deferred transmission
|
|
|
+ * even in full-duplex mode.
|
|
|
+ *
|
|
|
+ * In full-duplex mode the counter remains constant!
|
|
|
+ */
|
|
|
+ if ((pAC->GIni.GP[PhysPortIndex].PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) ||
|
|
|
+ (pAC->GIni.GP[PhysPortIndex].PLinkModeStatus == SK_LMODE_STAT_FULL)) {
|
|
|
+
|
|
|
+ LowVal = 0;
|
|
|
+ HighVal = 0;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Otherwise get contents of hardware register. */
|
|
|
+ (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
|
|
|
+ StatAddr[SK_PNMI_HTX_DEFFERAL][MacType].Reg,
|
|
|
+ &LowVal);
|
|
|
+ HighVal = pPnmiPrt->CounterHigh[StatIndex];
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_HRX_BADOCTET:
|
|
|
+ /* Not supported by XMAC */
|
|
|
+ if (MacType == SK_MAC_XMAC) {
|
|
|
+ return (Val);
|
|
|
+ }
|
|
|
+
|
|
|
+ (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
|
|
|
+ StatAddr[StatIndex][MacType].Reg,
|
|
|
+ &HighVal);
|
|
|
+ (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
|
|
|
+ StatAddr[StatIndex + 1][MacType].Reg,
|
|
|
+ &LowVal);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_HTX_OCTETLOW:
|
|
|
+ case SK_PNMI_HRX_OCTETLOW:
|
|
|
+ case SK_PNMI_HRX_BADOCTETLOW:
|
|
|
+ return (Val);
|
|
|
+
|
|
|
+ case SK_PNMI_HRX_LONGFRAMES:
|
|
|
+ /* For XMAC the SW counter is managed by PNMI */
|
|
|
+ if (MacType == SK_MAC_XMAC) {
|
|
|
+ return (pPnmiPrt->StatRxLongFrameCts);
|
|
|
+ }
|
|
|
+
|
|
|
+ (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
|
|
|
+ StatAddr[StatIndex][MacType].Reg,
|
|
|
+ &LowVal);
|
|
|
+ HighVal = pPnmiPrt->CounterHigh[StatIndex];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_HRX_TOO_LONG:
|
|
|
+ (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
|
|
|
+ StatAddr[StatIndex][MacType].Reg,
|
|
|
+ &LowVal);
|
|
|
+ HighVal = pPnmiPrt->CounterHigh[StatIndex];
|
|
|
+
|
|
|
+ Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
|
|
|
+
|
|
|
+ switch (MacType) {
|
|
|
+ case SK_MAC_GMAC:
|
|
|
+ /* For GMAC the SW counter is additionally managed by PNMI */
|
|
|
+ Val += pPnmiPrt->StatRxFrameTooLongCts;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_MAC_XMAC:
|
|
|
+ /*
|
|
|
+ * Frames longer than IEEE 802.3 frame max size are counted
|
|
|
+ * by XMAC in frame_too_long counter even reception of long
|
|
|
+ * frames was enabled and the frame was correct.
|
|
|
+ * So correct the value by subtracting RxLongFrame counter.
|
|
|
+ */
|
|
|
+ Val -= pPnmiPrt->StatRxLongFrameCts;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ LowVal = (SK_U32)Val;
|
|
|
+ HighVal = (SK_U32)(Val >> 32);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_HRX_SHORTS:
|
|
|
+ /* Not supported by GMAC */
|
|
|
+ if (MacType == SK_MAC_GMAC) {
|
|
|
+ /* GM_RXE_FRAG?? */
|
|
|
+ return (Val);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * XMAC counts short frame errors even if link down (#10620)
|
|
|
+ *
|
|
|
+ * If link-down the counter remains constant
|
|
|
+ */
|
|
|
+ if (pAC->GIni.GP[PhysPortIndex].PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
|
|
|
+
|
|
|
+ /* Otherwise get incremental difference */
|
|
|
+ (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
|
|
|
+ StatAddr[StatIndex][MacType].Reg,
|
|
|
+ &LowVal);
|
|
|
+ HighVal = pPnmiPrt->CounterHigh[StatIndex];
|
|
|
+
|
|
|
+ Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
|
|
|
+ Val -= pPnmiPrt->RxShortZeroMark;
|
|
|
+
|
|
|
+ LowVal = (SK_U32)Val;
|
|
|
+ HighVal = (SK_U32)(Val >> 32);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_HRX_MACC:
|
|
|
+ case SK_PNMI_HRX_MACC_UNKWN:
|
|
|
+ case SK_PNMI_HRX_BURST:
|
|
|
+ case SK_PNMI_HRX_MISSED:
|
|
|
+ case SK_PNMI_HRX_FRAMING:
|
|
|
+ case SK_PNMI_HRX_CARRIER:
|
|
|
+ case SK_PNMI_HRX_IRLENGTH:
|
|
|
+ case SK_PNMI_HRX_SYMBOL:
|
|
|
+ case SK_PNMI_HRX_CEXT:
|
|
|
+ /* Not supported by GMAC */
|
|
|
+ if (MacType == SK_MAC_GMAC) {
|
|
|
+ /* GM_RXE_FRAG?? */
|
|
|
+ return (Val);
|
|
|
+ }
|
|
|
+
|
|
|
+ (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
|
|
|
+ StatAddr[StatIndex][MacType].Reg,
|
|
|
+ &LowVal);
|
|
|
+ HighVal = pPnmiPrt->CounterHigh[StatIndex];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_HRX_PMACC_ERR:
|
|
|
+ /* For GMAC the SW counter is managed by PNMI */
|
|
|
+ if (MacType == SK_MAC_GMAC) {
|
|
|
+ return (pPnmiPrt->StatRxPMaccErr);
|
|
|
+ }
|
|
|
+
|
|
|
+ (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
|
|
|
+ StatAddr[StatIndex][MacType].Reg,
|
|
|
+ &LowVal);
|
|
|
+ HighVal = pPnmiPrt->CounterHigh[StatIndex];
|
|
|
+ break;
|
|
|
+
|
|
|
+ /* SW counter managed by PNMI */
|
|
|
+ case SK_PNMI_HTX_SYNC:
|
|
|
+ LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
|
|
|
+ HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
|
|
|
+ break;
|
|
|
+
|
|
|
+ /* SW counter managed by PNMI */
|
|
|
+ case SK_PNMI_HTX_SYNC_OCTET:
|
|
|
+ LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
|
|
|
+ HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SK_PNMI_HRX_FCS:
|
|
|
+ /*
|
|
|
+ * Broadcom filters fcs errors and counts it in
|
|
|
+ * Receive Error Counter register
|
|
|
+ */
|
|
|
+ if (pAC->GIni.GP[PhysPortIndex].PhyType == SK_PHY_BCOM) {
|
|
|
+ /* do not read while not initialized (PHY_READ hangs!)*/
|
|
|
+ if (pAC->GIni.GP[PhysPortIndex].PState) {
|
|
|
+ PHY_READ(IoC, &pAC->GIni.GP[PhysPortIndex],
|
|
|
+ PhysPortIndex, PHY_BCOM_RE_CTR,
|
|
|
+ &Word);
|
|
|
+
|
|
|
+ LowVal = Word;
|
|
|
+ }
|
|
|
+ HighVal = pPnmiPrt->CounterHigh[StatIndex];
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
|
|
|
+ StatAddr[StatIndex][MacType].Reg,
|
|
|
+ &LowVal);
|
|
|
+ HighVal = pPnmiPrt->CounterHigh[StatIndex];
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
|
|
|
+ StatAddr[StatIndex][MacType].Reg,
|
|
|
+ &LowVal);
|
|
|
+ HighVal = pPnmiPrt->CounterHigh[StatIndex];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
|
|
|
+
|
|
|
+ /* Correct value because of possible XMAC reset. XMAC Errata #2 */
|
|
|
+ Val += pPnmiPrt->CounterOffset[StatIndex];
|
|
|
+
|
|
|
+ return (Val);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * ResetCounter - Set all counters and timestamps to zero
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Notifies other common modules which store statistic data to
|
|
|
+ * reset their counters and finally reset our own counters.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * Nothing
|
|
|
+ */
|
|
|
+PNMI_STATIC void ResetCounter(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+SK_U32 NetIndex)
|
|
|
+{
|
|
|
+ unsigned int PhysPortIndex;
|
|
|
+ SK_EVPARA EventParam;
|
|
|
+
|
|
|
+
|
|
|
+ SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
|
|
|
+
|
|
|
+ /* Notify sensor module */
|
|
|
+ SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
|
|
|
+
|
|
|
+ /* Notify RLMT module */
|
|
|
+ EventParam.Para32[0] = NetIndex;
|
|
|
+ EventParam.Para32[1] = (SK_U32)-1;
|
|
|
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
|
|
|
+ EventParam.Para32[1] = 0;
|
|
|
+
|
|
|
+ /* Notify SIRQ module */
|
|
|
+ SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
|
|
|
+
|
|
|
+ /* Notify CSUM module */
|
|
|
+#ifdef SK_USE_CSUM
|
|
|
+ EventParam.Para32[0] = NetIndex;
|
|
|
+ EventParam.Para32[1] = (SK_U32)-1;
|
|
|
+ SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
|
|
|
+ EventParam);
|
|
|
+#endif
|
|
|
+
|
|
|
+ /* Clear XMAC statistic */
|
|
|
+ for (PhysPortIndex = 0; PhysPortIndex <
|
|
|
+ (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
|
|
|
+
|
|
|
+ (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex);
|
|
|
+
|
|
|
+ SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
|
|
|
+ 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
|
|
|
+ SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
|
|
|
+ CounterOffset, 0, sizeof(pAC->Pnmi.Port[
|
|
|
+ PhysPortIndex].CounterOffset));
|
|
|
+ SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
|
|
|
+ 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
|
|
|
+ SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
|
|
|
+ StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
|
|
|
+ PhysPortIndex].StatSyncOctetsCts));
|
|
|
+ SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
|
|
|
+ StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
|
|
|
+ PhysPortIndex].StatRxLongFrameCts));
|
|
|
+ SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
|
|
|
+ StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[
|
|
|
+ PhysPortIndex].StatRxFrameTooLongCts));
|
|
|
+ SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
|
|
|
+ StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[
|
|
|
+ PhysPortIndex].StatRxPMaccErr));
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Clear local statistics
|
|
|
+ */
|
|
|
+ SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
|
|
|
+ sizeof(pAC->Pnmi.VirtualCounterOffset));
|
|
|
+ pAC->Pnmi.RlmtChangeCts = 0;
|
|
|
+ pAC->Pnmi.RlmtChangeTime = 0;
|
|
|
+ SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
|
|
|
+ sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
|
|
|
+ pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
|
|
|
+ pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
|
|
|
+ pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
|
|
|
+ pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
|
|
|
+ pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
|
|
|
+ pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
|
|
|
+ pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
|
|
|
+ pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
|
|
|
+ pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
|
|
|
+ pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
|
|
|
+ pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
|
|
|
+ pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * GetTrapEntry - Get an entry in the trap buffer
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * The trap buffer stores various events. A user application somehow
|
|
|
+ * gets notified that an event occured and retrieves the trap buffer
|
|
|
+ * contens (or simply polls the buffer). The buffer is organized as
|
|
|
+ * a ring which stores the newest traps at the beginning. The oldest
|
|
|
+ * traps are overwritten by the newest ones. Each trap entry has a
|
|
|
+ * unique number, so that applications may detect new trap entries.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * A pointer to the trap entry
|
|
|
+ */
|
|
|
+PNMI_STATIC char* GetTrapEntry(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_U32 TrapId, /* SNMP ID of the trap */
|
|
|
+unsigned int Size) /* Space needed for trap entry */
|
|
|
+{
|
|
|
+ unsigned int BufPad = pAC->Pnmi.TrapBufPad;
|
|
|
+ unsigned int BufFree = pAC->Pnmi.TrapBufFree;
|
|
|
+ unsigned int Beg = pAC->Pnmi.TrapQueueBeg;
|
|
|
+ unsigned int End = pAC->Pnmi.TrapQueueEnd;
|
|
|
+ char *pBuf = &pAC->Pnmi.TrapBuf[0];
|
|
|
+ int Wrap;
|
|
|
+ unsigned int NeededSpace;
|
|
|
+ unsigned int EntrySize;
|
|
|
+ SK_U32 Val32;
|
|
|
+ SK_U64 Val64;
|
|
|
+
|
|
|
+
|
|
|
+ /* Last byte of entry will get a copy of the entry length */
|
|
|
+ Size ++;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Calculate needed buffer space */
|
|
|
+ if (Beg >= Size) {
|
|
|
+
|
|
|
+ NeededSpace = Size;
|
|
|
+ Wrap = SK_FALSE;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ NeededSpace = Beg + Size;
|
|
|
+ Wrap = SK_TRUE;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check if enough buffer space is provided. Otherwise
|
|
|
+ * free some entries. Leave one byte space between begin
|
|
|
+ * and end of buffer to make it possible to detect whether
|
|
|
+ * the buffer is full or empty
|
|
|
+ */
|
|
|
+ while (BufFree < NeededSpace + 1) {
|
|
|
+
|
|
|
+ if (End == 0) {
|
|
|
+
|
|
|
+ End = SK_PNMI_TRAP_QUEUE_LEN;
|
|
|
+ }
|
|
|
+
|
|
|
+ EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
|
|
|
+ BufFree += EntrySize;
|
|
|
+ End -= EntrySize;
|
|
|
+#ifdef DEBUG
|
|
|
+ SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
|
|
|
+#endif
|
|
|
+ if (End == BufPad) {
|
|
|
+#ifdef DEBUG
|
|
|
+ SK_MEMSET(pBuf, (char)(-1), End);
|
|
|
+#endif
|
|
|
+ BufFree += End;
|
|
|
+ End = 0;
|
|
|
+ BufPad = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Insert new entry as first entry. Newest entries are
|
|
|
+ * stored at the beginning of the queue.
|
|
|
+ */
|
|
|
+ if (Wrap) {
|
|
|
+
|
|
|
+ BufPad = Beg;
|
|
|
+ Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ Beg = Beg - Size;
|
|
|
+ }
|
|
|
+ BufFree -= NeededSpace;
|
|
|
+
|
|
|
+ /* Save the current offsets */
|
|
|
+ pAC->Pnmi.TrapQueueBeg = Beg;
|
|
|
+ pAC->Pnmi.TrapQueueEnd = End;
|
|
|
+ pAC->Pnmi.TrapBufPad = BufPad;
|
|
|
+ pAC->Pnmi.TrapBufFree = BufFree;
|
|
|
+
|
|
|
+ /* Initialize the trap entry */
|
|
|
+ *(pBuf + Beg + Size - 1) = (char)Size;
|
|
|
+ *(pBuf + Beg) = (char)Size;
|
|
|
+ Val32 = (pAC->Pnmi.TrapUnique) ++;
|
|
|
+ SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
|
|
|
+ SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
|
|
|
+ Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
|
|
|
+ SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
|
|
|
+
|
|
|
+ return (pBuf + Beg);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * CopyTrapQueue - Copies the trap buffer for the TRAP OID
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * On a query of the TRAP OID the trap buffer contents will be
|
|
|
+ * copied continuously to the request buffer, which must be large
|
|
|
+ * enough. No length check is performed.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * Nothing
|
|
|
+ */
|
|
|
+PNMI_STATIC void CopyTrapQueue(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+char *pDstBuf) /* Buffer to which the queued traps will be copied */
|
|
|
+{
|
|
|
+ unsigned int BufPad = pAC->Pnmi.TrapBufPad;
|
|
|
+ unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
|
|
|
+ unsigned int End = pAC->Pnmi.TrapQueueEnd;
|
|
|
+ char *pBuf = &pAC->Pnmi.TrapBuf[0];
|
|
|
+ unsigned int Len;
|
|
|
+ unsigned int DstOff = 0;
|
|
|
+
|
|
|
+
|
|
|
+ while (Trap != End) {
|
|
|
+
|
|
|
+ Len = (unsigned int)*(pBuf + Trap);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Last byte containing a copy of the length will
|
|
|
+ * not be copied.
|
|
|
+ */
|
|
|
+ *(pDstBuf + DstOff) = (char)(Len - 1);
|
|
|
+ SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
|
|
|
+ DstOff += Len - 1;
|
|
|
+
|
|
|
+ Trap += Len;
|
|
|
+ if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
|
|
|
+
|
|
|
+ Trap = BufPad;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * GetTrapQueueLen - Get the length of the trap buffer
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Evaluates the number of currently stored traps and the needed
|
|
|
+ * buffer size to retrieve them.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * Nothing
|
|
|
+ */
|
|
|
+PNMI_STATIC void GetTrapQueueLen(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+unsigned int *pLen, /* Length in Bytes of all queued traps */
|
|
|
+unsigned int *pEntries) /* Returns number of trapes stored in queue */
|
|
|
+{
|
|
|
+ unsigned int BufPad = pAC->Pnmi.TrapBufPad;
|
|
|
+ unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
|
|
|
+ unsigned int End = pAC->Pnmi.TrapQueueEnd;
|
|
|
+ char *pBuf = &pAC->Pnmi.TrapBuf[0];
|
|
|
+ unsigned int Len;
|
|
|
+ unsigned int Entries = 0;
|
|
|
+ unsigned int TotalLen = 0;
|
|
|
+
|
|
|
+
|
|
|
+ while (Trap != End) {
|
|
|
+
|
|
|
+ Len = (unsigned int)*(pBuf + Trap);
|
|
|
+ TotalLen += Len - 1;
|
|
|
+ Entries ++;
|
|
|
+
|
|
|
+ Trap += Len;
|
|
|
+ if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
|
|
|
+
|
|
|
+ Trap = BufPad;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ *pEntries = Entries;
|
|
|
+ *pLen = TotalLen;
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * QueueSimpleTrap - Store a simple trap to the trap buffer
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * A simple trap is a trap with now additional data. It consists
|
|
|
+ * simply of a trap code.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * Nothing
|
|
|
+ */
|
|
|
+PNMI_STATIC void QueueSimpleTrap(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_U32 TrapId) /* Type of sensor trap */
|
|
|
+{
|
|
|
+ GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * QueueSensorTrap - Stores a sensor trap in the trap buffer
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Gets an entry in the trap buffer and fills it with sensor related
|
|
|
+ * data.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * Nothing
|
|
|
+ */
|
|
|
+PNMI_STATIC void QueueSensorTrap(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_U32 TrapId, /* Type of sensor trap */
|
|
|
+unsigned int SensorIndex) /* Index of sensor which caused the trap */
|
|
|
+{
|
|
|
+ char *pBuf;
|
|
|
+ unsigned int Offset;
|
|
|
+ unsigned int DescrLen;
|
|
|
+ SK_U32 Val32;
|
|
|
+
|
|
|
+
|
|
|
+ /* Get trap buffer entry */
|
|
|
+ DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
|
|
|
+ pBuf = GetTrapEntry(pAC, TrapId,
|
|
|
+ SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
|
|
|
+ Offset = SK_PNMI_TRAP_SIMPLE_LEN;
|
|
|
+
|
|
|
+ /* Store additionally sensor trap related data */
|
|
|
+ Val32 = OID_SKGE_SENSOR_INDEX;
|
|
|
+ SK_PNMI_STORE_U32(pBuf + Offset, Val32);
|
|
|
+ *(pBuf + Offset + 4) = 4;
|
|
|
+ Val32 = (SK_U32)SensorIndex;
|
|
|
+ SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
|
|
|
+ Offset += 9;
|
|
|
+
|
|
|
+ Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
|
|
|
+ SK_PNMI_STORE_U32(pBuf + Offset, Val32);
|
|
|
+ *(pBuf + Offset + 4) = (char)DescrLen;
|
|
|
+ SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
|
|
|
+ DescrLen);
|
|
|
+ Offset += DescrLen + 5;
|
|
|
+
|
|
|
+ Val32 = OID_SKGE_SENSOR_TYPE;
|
|
|
+ SK_PNMI_STORE_U32(pBuf + Offset, Val32);
|
|
|
+ *(pBuf + Offset + 4) = 1;
|
|
|
+ *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
|
|
|
+ Offset += 6;
|
|
|
+
|
|
|
+ Val32 = OID_SKGE_SENSOR_VALUE;
|
|
|
+ SK_PNMI_STORE_U32(pBuf + Offset, Val32);
|
|
|
+ *(pBuf + Offset + 4) = 4;
|
|
|
+ Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
|
|
|
+ SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Nothing further to explain.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * Nothing
|
|
|
+ */
|
|
|
+PNMI_STATIC void QueueRlmtNewMacTrap(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+unsigned int ActiveMac) /* Index (0..n) of the currently active port */
|
|
|
+{
|
|
|
+ char *pBuf;
|
|
|
+ SK_U32 Val32;
|
|
|
+
|
|
|
+
|
|
|
+ pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
|
|
|
+ SK_PNMI_TRAP_RLMT_CHANGE_LEN);
|
|
|
+
|
|
|
+ Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
|
|
|
+ SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
|
|
|
+ *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
|
|
|
+ *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Nothing further to explain.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * Nothing
|
|
|
+ */
|
|
|
+PNMI_STATIC void QueueRlmtPortTrap(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_U32 TrapId, /* Type of RLMT port trap */
|
|
|
+unsigned int PortIndex) /* Index of the port, which changed its state */
|
|
|
+{
|
|
|
+ char *pBuf;
|
|
|
+ SK_U32 Val32;
|
|
|
+
|
|
|
+
|
|
|
+ pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
|
|
|
+
|
|
|
+ Val32 = OID_SKGE_RLMT_PORT_INDEX;
|
|
|
+ SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
|
|
|
+ *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
|
|
|
+ *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
|
|
|
+}
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * CopyMac - Copies a MAC address
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * Nothing further to explain.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * Nothing
|
|
|
+ */
|
|
|
+PNMI_STATIC void CopyMac(
|
|
|
+char *pDst, /* Pointer to destination buffer */
|
|
|
+SK_MAC_ADDR *pMac) /* Pointer of Source */
|
|
|
+{
|
|
|
+ int i;
|
|
|
+
|
|
|
+
|
|
|
+ for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
|
|
|
+
|
|
|
+ *(pDst + i) = pMac->a[i];
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+#ifdef SK_POWER_MGMT
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * PowerManagement - OID handler function of PowerManagement OIDs
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * The code is simple. No description necessary.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK The request was successfully performed.
|
|
|
+ * SK_PNMI_ERR_GENERAL A general severe internal error occured.
|
|
|
+ * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
|
|
|
+ * the correct data (e.g. a 32bit value is
|
|
|
+ * needed, but a 16 bit value was passed).
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
|
|
|
+ * exist (e.g. port instance 3 on a two port
|
|
|
+ * adapter.
|
|
|
+ */
|
|
|
+
|
|
|
+PNMI_STATIC int PowerManagement(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+int Action, /* Get/PreSet/Set action */
|
|
|
+SK_U32 Id, /* Object ID that is to be processed */
|
|
|
+char *pBuf, /* Buffer to which to mgmt data will be retrieved */
|
|
|
+unsigned int *pLen, /* On call: buffer length. On return: used buffer */
|
|
|
+SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
|
|
|
+unsigned int TableIndex, /* Index to the Id table */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
|
|
|
+{
|
|
|
+
|
|
|
+ SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check instance. We only handle single instance variables
|
|
|
+ */
|
|
|
+ if (Instance != (SK_U32)(-1) && Instance != 1) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_UNKNOWN_INST);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Perform action
|
|
|
+ */
|
|
|
+ if (Action == SK_PNMI_GET) {
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check length
|
|
|
+ */
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_PNP_CAPABILITIES:
|
|
|
+ if (*pLen < sizeof(SK_PNP_CAPABILITIES)) {
|
|
|
+
|
|
|
+ *pLen = sizeof(SK_PNP_CAPABILITIES);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_PNP_QUERY_POWER:
|
|
|
+ case OID_PNP_ENABLE_WAKE_UP:
|
|
|
+ if (*pLen < sizeof(SK_U32)) {
|
|
|
+
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_PNP_SET_POWER:
|
|
|
+ case OID_PNP_ADD_WAKE_UP_PATTERN:
|
|
|
+ case OID_PNP_REMOVE_WAKE_UP_PATTERN:
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040,
|
|
|
+ SK_PNMI_ERR040MSG);
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get value
|
|
|
+ */
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_PNP_CAPABILITIES:
|
|
|
+ RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_PNP_QUERY_POWER:
|
|
|
+ /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
|
|
|
+ the miniport to indicate whether it can transition its NIC
|
|
|
+ to the low-power state.
|
|
|
+ A miniport driver must always return NDIS_STATUS_SUCCESS
|
|
|
+ to a query of OID_PNP_QUERY_POWER. */
|
|
|
+ RetCode = SK_PNMI_ERR_OK;
|
|
|
+ break;
|
|
|
+
|
|
|
+ /* NDIS handles these OIDs as write-only.
|
|
|
+ * So in case of get action the buffer with written length = 0
|
|
|
+ * is returned
|
|
|
+ */
|
|
|
+ case OID_PNP_SET_POWER:
|
|
|
+ case OID_PNP_ADD_WAKE_UP_PATTERN:
|
|
|
+ case OID_PNP_REMOVE_WAKE_UP_PATTERN:
|
|
|
+ *pLen = 0;
|
|
|
+ RetCode = SK_PNMI_ERR_OK;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_PNP_ENABLE_WAKE_UP:
|
|
|
+ RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ RetCode = SK_PNMI_ERR_GENERAL;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return (RetCode);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * From here SET or PRESET action. Check if the passed
|
|
|
+ * buffer length is plausible.
|
|
|
+ */
|
|
|
+ switch (Id) {
|
|
|
+ case OID_PNP_SET_POWER:
|
|
|
+ case OID_PNP_ENABLE_WAKE_UP:
|
|
|
+ if (*pLen < sizeof(SK_U32)) {
|
|
|
+
|
|
|
+ *pLen = sizeof(SK_U32);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ if (*pLen != sizeof(SK_U32)) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_BAD_VALUE);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_PNP_ADD_WAKE_UP_PATTERN:
|
|
|
+ case OID_PNP_REMOVE_WAKE_UP_PATTERN:
|
|
|
+ if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) {
|
|
|
+
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_BAD_VALUE);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_READ_ONLY);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Perform preset or set
|
|
|
+ */
|
|
|
+
|
|
|
+ /* POWER module does not support PRESET action */
|
|
|
+ if (Action == SK_PNMI_PRESET) {
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (Id) {
|
|
|
+ case OID_PNP_SET_POWER:
|
|
|
+ RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_PNP_ADD_WAKE_UP_PATTERN:
|
|
|
+ RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_PNP_REMOVE_WAKE_UP_PATTERN:
|
|
|
+ RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_PNP_ENABLE_WAKE_UP:
|
|
|
+ RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ RetCode = SK_PNMI_ERR_GENERAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ return (RetCode);
|
|
|
+}
|
|
|
+#endif /* SK_POWER_MGMT */
|
|
|
+
|
|
|
+
|
|
|
+/*****************************************************************************
|
|
|
+ *
|
|
|
+ * Vct - OID handler function of OIDs
|
|
|
+ *
|
|
|
+ * Description:
|
|
|
+ * The code is simple. No description necessary.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ * SK_PNMI_ERR_OK The request was performed successfully.
|
|
|
+ * SK_PNMI_ERR_GENERAL A general severe internal error occured.
|
|
|
+ * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
|
|
|
+ * the correct data (e.g. a 32bit value is
|
|
|
+ * needed, but a 16 bit value was passed).
|
|
|
+ * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
|
|
|
+ * exist (e.g. port instance 3 on a two port
|
|
|
+ * adapter).
|
|
|
+ * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed.
|
|
|
+ *
|
|
|
+ */
|
|
|
+
|
|
|
+PNMI_STATIC int Vct(
|
|
|
+SK_AC *pAC, /* Pointer to adapter context */
|
|
|
+SK_IOC IoC, /* IO context handle */
|
|
|
+int Action, /* Get/PreSet/Set action */
|
|
|
+SK_U32 Id, /* Object ID that is to be processed */
|
|
|
+char *pBuf, /* Buffer to which the mgmt data will be copied */
|
|
|
+unsigned int *pLen, /* On call: buffer length. On return: used buffer */
|
|
|
+SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */
|
|
|
+unsigned int TableIndex, /* Index to the Id table */
|
|
|
+SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
|
|
|
+{
|
|
|
+ SK_GEPORT *pPrt;
|
|
|
+ SK_PNMI_VCT *pVctBackupData;
|
|
|
+ SK_U32 LogPortMax;
|
|
|
+ SK_U32 PhysPortMax;
|
|
|
+ SK_U32 PhysPortIndex;
|
|
|
+ SK_U32 Limit;
|
|
|
+ SK_U32 Offset;
|
|
|
+ SK_BOOL Link;
|
|
|
+ SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
|
|
|
+ int i;
|
|
|
+ SK_EVPARA Para;
|
|
|
+ SK_U32 CableLength;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Calculate the port indexes from the instance.
|
|
|
+ */
|
|
|
+ PhysPortMax = pAC->GIni.GIMacsFound;
|
|
|
+ LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
|
|
|
+
|
|
|
+ /* Dual net mode? */
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ LogPortMax--;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((Instance != (SK_U32) (-1))) {
|
|
|
+ /* Check instance range. */
|
|
|
+ if ((Instance < 2) || (Instance > LogPortMax)) {
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_UNKNOWN_INST);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
|
|
|
+ PhysPortIndex = NetIndex;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ PhysPortIndex = Instance - 2;
|
|
|
+ }
|
|
|
+ Limit = PhysPortIndex + 1;
|
|
|
+ }
|
|
|
+ else { /*
|
|
|
+ * Instance == (SK_U32) (-1), get all Instances of that OID.
|
|
|
+ *
|
|
|
+ * Not implemented yet. May be used in future releases.
|
|
|
+ */
|
|
|
+ PhysPortIndex = 0;
|
|
|
+ Limit = PhysPortMax;
|
|
|
+ }
|
|
|
+
|
|
|
+ pPrt = &pAC->GIni.GP[PhysPortIndex];
|
|
|
+ if (pPrt->PHWLinkUp) {
|
|
|
+ Link = SK_TRUE;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ Link = SK_FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check MAC type.
|
|
|
+ */
|
|
|
+ if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Initialize backup data pointer. */
|
|
|
+ pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check action type.
|
|
|
+ */
|
|
|
+ if (Action == SK_PNMI_GET) {
|
|
|
+ /*
|
|
|
+ * Check length.
|
|
|
+ */
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_SKGE_VCT_GET:
|
|
|
+ if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
|
|
|
+ *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_VCT_STATUS:
|
|
|
+ if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
|
|
|
+ *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get value.
|
|
|
+ */
|
|
|
+ Offset = 0;
|
|
|
+ for (; PhysPortIndex < Limit; PhysPortIndex++) {
|
|
|
+ switch (Id) {
|
|
|
+
|
|
|
+ case OID_SKGE_VCT_GET:
|
|
|
+ if ((Link == SK_FALSE) &&
|
|
|
+ (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
|
|
|
+ RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
|
|
|
+ if (RetCode == 0) {
|
|
|
+ pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
|
|
|
+ pAC->Pnmi.VctStatus[PhysPortIndex] |=
|
|
|
+ (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
|
|
|
+
|
|
|
+ /* Copy results for later use to PNMI struct. */
|
|
|
+ for (i = 0; i < 4; i++) {
|
|
|
+ if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
|
|
|
+ if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
|
|
|
+ pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
|
|
|
+ CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ CableLength = 0;
|
|
|
+ }
|
|
|
+ pVctBackupData->PMdiPairLen[i] = CableLength;
|
|
|
+ pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
|
|
|
+ }
|
|
|
+
|
|
|
+ Para.Para32[0] = PhysPortIndex;
|
|
|
+ Para.Para32[1] = -1;
|
|
|
+ SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
|
|
|
+ SkEventDispatcher(pAC, IoC);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ ; /* VCT test is running. */
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Get all results. */
|
|
|
+ CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
|
|
|
+ Offset += sizeof(SK_U8);
|
|
|
+ *(pBuf + Offset) = pPrt->PCableLen;
|
|
|
+ Offset += sizeof(SK_U8);
|
|
|
+ for (i = 0; i < 4; i++) {
|
|
|
+ SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
|
|
|
+ Offset += sizeof(SK_U32);
|
|
|
+ }
|
|
|
+ for (i = 0; i < 4; i++) {
|
|
|
+ *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
|
|
|
+ Offset += sizeof(SK_U8);
|
|
|
+ }
|
|
|
+
|
|
|
+ RetCode = SK_PNMI_ERR_OK;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OID_SKGE_VCT_STATUS:
|
|
|
+ CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
|
|
|
+ Offset += sizeof(SK_U8);
|
|
|
+ RetCode = SK_PNMI_ERR_OK;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ } /* for */
|
|
|
+ *pLen = Offset;
|
|
|
+ return (RetCode);
|
|
|
+
|
|
|
+ } /* if SK_PNMI_GET */
|
|
|
+
|
|
|
+ /*
|
|
|
+ * From here SET or PRESET action. Check if the passed
|
|
|
+ * buffer length is plausible.
|
|
|
+ */
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check length.
|
|
|
+ */
|
|
|
+ switch (Id) {
|
|
|
+ case OID_SKGE_VCT_SET:
|
|
|
+ if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
|
|
|
+ *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
|
|
|
+ return (SK_PNMI_ERR_TOO_SHORT);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Perform preset or set.
|
|
|
+ */
|
|
|
+
|
|
|
+ /* VCT does not support PRESET action. */
|
|
|
+ if (Action == SK_PNMI_PRESET) {
|
|
|
+ return (SK_PNMI_ERR_OK);
|
|
|
+ }
|
|
|
+
|
|
|
+ Offset = 0;
|
|
|
+ for (; PhysPortIndex < Limit; PhysPortIndex++) {
|
|
|
+ switch (Id) {
|
|
|
+ case OID_SKGE_VCT_SET: /* Start VCT test. */
|
|
|
+ if (Link == SK_FALSE) {
|
|
|
+ SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
|
|
|
+
|
|
|
+ RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
|
|
|
+ if (RetCode == 0) { /* RetCode: 0 => Start! */
|
|
|
+ pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
|
|
|
+ pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
|
|
|
+ pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Start VCT timer counter.
|
|
|
+ */
|
|
|
+ SK_MEMSET((char *) &Para, 0, sizeof(Para));
|
|
|
+ Para.Para32[0] = PhysPortIndex;
|
|
|
+ Para.Para32[1] = -1;
|
|
|
+ SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
|
|
|
+ 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
|
|
|
+ SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
|
|
|
+ RetCode = SK_PNMI_ERR_OK;
|
|
|
+ }
|
|
|
+ else { /* RetCode: 2 => Running! */
|
|
|
+ SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
|
|
|
+ RetCode = SK_PNMI_ERR_OK;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else { /* RetCode: 4 => Link! */
|
|
|
+ RetCode = 4;
|
|
|
+ SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
|
|
|
+ RetCode = SK_PNMI_ERR_OK;
|
|
|
+ }
|
|
|
+ Offset += sizeof(SK_U32);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ *pLen = 0;
|
|
|
+ return (SK_PNMI_ERR_GENERAL);
|
|
|
+ }
|
|
|
+ } /* for */
|
|
|
+ *pLen = Offset;
|
|
|
+ return (RetCode);
|
|
|
+
|
|
|
+} /* Vct */
|
|
|
+
|
|
|
+
|
|
|
+PNMI_STATIC void CheckVctStatus(
|
|
|
+SK_AC *pAC,
|
|
|
+SK_IOC IoC,
|
|
|
+char *pBuf,
|
|
|
+SK_U32 Offset,
|
|
|
+SK_U32 PhysPortIndex)
|
|
|
+{
|
|
|
+ SK_GEPORT *pPrt;
|
|
|
+ SK_PNMI_VCT *pVctData;
|
|
|
+ SK_U32 RetCode;
|
|
|
+ SK_U8 LinkSpeedUsed;
|
|
|
+
|
|
|
+ pPrt = &pAC->GIni.GP[PhysPortIndex];
|
|
|
+
|
|
|
+ pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
|
|
|
+ pVctData->VctStatus = SK_PNMI_VCT_NONE;
|
|
|
+
|
|
|
+ if (!pPrt->PHWLinkUp) {
|
|
|
+
|
|
|
+ /* Was a VCT test ever made before? */
|
|
|
+ if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
|
|
|
+ if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
|
|
|
+ pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Check VCT test status. */
|
|
|
+ RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
|
|
|
+ if (RetCode == 2) { /* VCT test is running. */
|
|
|
+ pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
|
|
|
+ }
|
|
|
+ else { /* VCT data was copied to pAC here. Check PENDING state. */
|
|
|
+ if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
|
|
|
+ pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
|
|
|
+ pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+
|
|
|
+ /* Was a VCT test ever made before? */
|
|
|
+ if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
|
|
|
+ pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
|
|
|
+ pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* DSP only valid in 100/1000 modes. */
|
|
|
+ LinkSpeedUsed = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
|
|
|
+ if (LinkSpeedUsed != SK_LSPEED_STAT_10MBPS) {
|
|
|
+ pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+} /* CheckVctStatus */
|