| /***************************************************************************** |
| * |
| * 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. |
| * |
| ****************************************************************************/ |
| |
| |
| #include <config.h> |
| |
| #ifdef CONFIG_SK98 |
| |
| 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)) { |
|