2005-04-16 15:20:36 -07:00
/*****************************************************************************
*
* Name : skgepnmi . c
* Project : GEnesis , PCI Gigabit Ethernet Adapter
* Version : $ Revision : 1.111 $
* Date : $ Date : 2003 / 09 / 15 13 : 35 : 35 $
* Purpose : Private Network Management Interface
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/******************************************************************************
*
* ( C ) Copyright 1998 - 2002 SysKonnect GmbH .
* ( C ) Copyright 2002 - 2003 Marvell .
*
* 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 .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifndef _lint
static const char SysKonnectFileId [ ] =
" @(#) $Id: skgepnmi.c,v 1.111 2003/09/15 13:35:35 tschilli Exp $ (C) Marvell. " ;
# endif /* !_lint */
# 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 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 ) ;
int SkPnmiGenIoctl ( SK_AC * pAC , SK_IOC IoC , void * pBuf ,
unsigned int * pLen , SK_U32 NetIndex ) ;
/*
* 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_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 ) ) ;
}
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 ) ) ;
}
# 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 + + ) {
pAC - > GIni . GP [ PortIndex ] . 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 .
*/
2006-01-09 18:34:08 -08:00
static int SkPnmiGetVar (
2005-04-16 15:20:36 -07:00
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 the management data will be copied */
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 always 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
2006-01-10 00:08:17 +01:00
* new value . This is useful to check if a set might be successfull .
2005-04-16 15:20:36 -07:00
* If the instance - 1 is passed , an array of values is supposed and
* all instances 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 32 bit 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 .
*/
2006-01-09 18:34:08 -08:00
static int SkPnmiPreSetVar (
2005-04-16 15:20:36 -07:00
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 the management data will be copied */
unsigned int * pLen , /* Total length of management data */
SK_U32 Instance , /* Instance (1..n) that is to be set or -1 */
SK_U32 NetIndex ) /* NetIndex (0..n), in single net mode always 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
2006-01-10 00:08:17 +01:00
* new value . This is useful to check if a set might be successfull .
2005-04-16 15:20:36 -07:00
* If the instance - 1 is passed , an array of values is supposed and
* all instances 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 32 bit 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 to which the management data will be copied */
unsigned int * pLen , /* Total length of management data */
SK_U32 Instance , /* Instance (1..n) that is to be set or -1 */
SK_U32 NetIndex ) /* NetIndex (0..n), in single net mode always 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 to which the management data will be copied. */
unsigned int * pLen , /* Length of buffer */
SK_U32 NetIndex ) /* NetIndex (0..n), in single net mode always 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
2006-01-10 00:08:17 +01:00
* new value . This is useful to check if a set might be successfull .
2005-04-16 15:20:36 -07:00
* 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 32 bit 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 always 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 32 bit 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 always 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 /* DEBUG */
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 /* DEBUG */
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 :
if ( MacType = = SK_MAC_XMAC ) {
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 :
if ( MacType = = SK_MAC_XMAC ) {
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 /* DEBUG */
/*
* 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 /* DEBUG */
/*
* 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 /* DEBUG */
/*
* 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 /* DEBUG */
/*
* 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 initialization 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 /* DEBUG */
/*
* Set all counters and timestamps to zero .
* The according NetIndex is required as a
* parameter of the event .
*/
ResetCounter ( pAC , IoC , NetIndex ) ;
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 /* DEBUG */
/*
* 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 ( MacType = = 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 /* DEBUG */
/*
* 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 ( MacType = = 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 /* DEBUG */
/*
* 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 /* DEBUG */
/*
* 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 - > PMdiPairSts [ i ] = = SK_PNMI_VCT_NORMAL_CABLE ) {
if ( ( pPrt - > PMdiPairLen [ i ] > 35 ) & &
( pPrt - > PMdiPairLen [ i ] < 0xff ) ) {
pPrt - > PMdiPairSts [ i ] = SK_PNMI_VCT_IMPEDANCE_MISMATCH ;
}
}
if ( ( pPrt - > PMdiPairLen [ i ] > 35 ) & &
( pPrt - > PMdiPairLen [ i ] ! = 0xff ) ) {
CableLength = 1000 *
( ( ( 175 * pPrt - > PMdiPairLen [ i ] ) / 210 ) - 28 ) ;
}
else {
CableLength = 0 ;
}
pVctBackupData - > PMdiPairLen [ i ] = CableLength ;
pVctBackupData - > PMdiPairSts [ i ] = pPrt - > PMdiPairSts [ i ] ;
}
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 at 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 used for the management data transfer */
unsigned int * pLen , /* Total length of pBuf management data */
SK_U32 Instance , /* Instance (1..n) that is to be set or -1 */
SK_U32 NetIndex ) /* NetIndex (0..n), in single net mode always 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 , /* PRESET/SET action to be performed */
char * pBuf , /* Buffer used for the management data transfer */
unsigned int * pLen , /* Length of pBuf management data buffer */
SK_U32 NetIndex ) /* NetIndex (0..n), in single net mode always 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 32 bit 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 used for the management data transfer */
unsigned int * pLen , /* On call: pBuf 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 always 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 32 bit 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 used for the management data transfer */
unsigned int * pLen , /* On call: pBuf 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 always 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 32 bit 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 used for the management data transfer */
unsigned int * pLen , /* On call: pBuf 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 always 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 64 bit 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 MAC 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 32 bit 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 used for the management data transfer */
unsigned int * pLen , /* On call: pBuf 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 always zero */
{
unsigned int LogPortMax ;
unsigned int LogPortIndex ;
unsigned int PhysPortMax ;
unsigned int Limit ;
unsigned int Offset ;
int MacType ;
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 ) ;
MacType = pAC - > GIni . GIMacType ;
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 MAC 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 :
if ( MacType = = SK_MAC_GMAC ) {
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 ) ;
}
else {
StatVal = GetStatVal ( pAC , IoC , LogPortIndex ,
IdTable [ TableIndex ] . Param , NetIndex ) ;
}
break ;
case OID_SKGE_STAT_TX :
if ( MacType = = SK_MAC_GMAC ) {
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 ,
IdTable [ TableIndex ] . Param , NetIndex ) ;
}
break ;
default :
StatVal = GetStatVal ( pAC , IoC , LogPortIndex ,
IdTable [ TableIndex ] . Param , NetIndex ) ;
}
SK_PNMI_STORE_U64 ( pBuf + Offset , StatVal ) ;
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 32 bit 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 used for the management data transfer */
unsigned int * pLen , /* On call: pBuf 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 always zero */
{
int Ret ;
unsigned int LogPortMax ;
unsigned int PhysPortMax ;
unsigned int LogPortIndex ;
unsigned int PhysPortIndex ;
unsigned int Limit ;
unsigned int Offset = 0 ;
/*
* Calculate instance if wished . MAC index 0 is the virtual
* MAC .
*/
PhysPortMax = pAC - > GIni . GIMacsFound ;
LogPortMax = SK_PNMI_PORT_PHYS2LOG ( PhysPortMax ) ;
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) { /* Dual net mode */
LogPortMax - - ;
}
if ( ( Instance ! = ( SK_U32 ) ( - 1 ) ) ) { /* Only one specific instance is queried */
/* Check instance range */
if ( ( Instance < 1 ) | | ( Instance > LogPortMax ) ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_UNKNOWN_INST ) ;
}
LogPortIndex = SK_PNMI_PORT_INST2LOG ( Instance ) ;
Limit = LogPortIndex + 1 ;
}
else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
LogPortIndex = 0 ;
Limit = LogPortMax ;
}
/*
* Perform Action
*/
if ( Action = = SK_PNMI_GET ) {
/* Check length */
if ( * pLen < ( Limit - LogPortIndex ) * 6 ) {
* pLen = ( Limit - LogPortIndex ) * 6 ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
/*
* Get value
*/
for ( ; LogPortIndex < Limit ; LogPortIndex + + ) {
switch ( Id ) {
case OID_SKGE_PHYS_CUR_ADDR :
if ( LogPortIndex = = 0 ) {
CopyMac ( pBuf + Offset , & pAC - > Addr . Net [ NetIndex ] . CurrentMacAddress ) ;
}
else {
PhysPortIndex = SK_PNMI_PORT_LOG2PHYS ( pAC , LogPortIndex ) ;
CopyMac ( pBuf + Offset ,
& pAC - > Addr . Port [ PhysPortIndex ] . CurrentMacAddress ) ;
}
Offset + = 6 ;
break ;
case OID_SKGE_PHYS_FAC_ADDR :
if ( LogPortIndex = = 0 ) {
CopyMac ( pBuf + Offset ,
& pAC - > Addr . Net [ NetIndex ] . PermanentMacAddress ) ;
}
else {
PhysPortIndex = SK_PNMI_PORT_LOG2PHYS (
pAC , LogPortIndex ) ;
CopyMac ( pBuf + Offset ,
& pAC - > Addr . Port [ PhysPortIndex ] . PermanentMacAddress ) ;
}
Offset + = 6 ;
break ;
default :
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR008 ,
SK_PNMI_ERR008MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
}
* pLen = Offset ;
}
else {
/*
* The logical MAC address may not be changed only
* the physical ones
*/
if ( Id = = OID_SKGE_PHYS_FAC_ADDR ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_READ_ONLY ) ;
}
/*
* Only the current address may be changed
*/
if ( Id ! = OID_SKGE_PHYS_CUR_ADDR ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR009 ,
SK_PNMI_ERR009MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
/* Check length */
if ( * pLen < ( Limit - LogPortIndex ) * 6 ) {
* pLen = ( Limit - LogPortIndex ) * 6 ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
if ( * pLen > ( Limit - LogPortIndex ) * 6 ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_BAD_VALUE ) ;
}
/*
* Check Action
*/
if ( Action = = SK_PNMI_PRESET ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_OK ) ;
}
/*
* Set OID_SKGE_MAC_CUR_ADDR
*/
for ( ; LogPortIndex < Limit ; LogPortIndex + + , Offset + = 6 ) {
/*
* A set to virtual port and set of broadcast
* address will be ignored
*/
if ( LogPortIndex = = 0 | | SK_MEMCMP ( pBuf + Offset ,
" \xff \xff \xff \xff \xff \xff " , 6 ) = = 0 ) {
continue ;
}
PhysPortIndex = SK_PNMI_PORT_LOG2PHYS ( pAC ,
LogPortIndex ) ;
Ret = SkAddrOverride ( pAC , IoC , PhysPortIndex ,
( SK_MAC_ADDR * ) ( pBuf + Offset ) ,
( LogPortIndex = = 0 ? SK_ADDR_VIRTUAL_ADDRESS :
SK_ADDR_PHYSICAL_ADDRESS ) ) ;
if ( Ret ! = SK_ADDR_OVERRIDE_SUCCESS ) {
return ( SK_PNMI_ERR_GENERAL ) ;
}
}
* pLen = Offset ;
}
return ( SK_PNMI_ERR_OK ) ;
}
/*****************************************************************************
*
* CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
*
* Description :
* Retrieves the statistic values of the CSUM module . The CSUM data
* structure must be available in the SK_AC even if the CSUM module
* is not included , because PNMI reads the statistic data from the
* CSUM part of SK_AC directly .
*
* Returns :
* SK_PNMI_ERR_OK The request was successfully performed .
* SK_PNMI_ERR_GENERAL A general severe internal error occured .
* SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
* the correct data ( e . g . a 32 bit value is
* needed , but a 16 bit value was passed ) .
* SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn ' t
* exist ( e . g . port instance 3 on a two port
* adapter .
*/
PNMI_STATIC int CsumStat (
SK_AC * pAC , /* Pointer to adapter context */
SK_IOC IoC , /* IO context handle */
int Action , /* GET/PRESET/SET action */
SK_U32 Id , /* Object ID that is to be processed */
char * pBuf , /* Buffer used for the management data transfer */
unsigned int * pLen , /* On call: pBuf 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 always zero */
{
unsigned int Index ;
unsigned int Limit ;
unsigned int Offset = 0 ;
SK_U64 StatVal ;
/*
* Calculate instance if wished
*/
if ( Instance ! = ( SK_U32 ) ( - 1 ) ) {
if ( ( Instance < 1 ) | | ( Instance > SKCS_NUM_PROTOCOLS ) ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_UNKNOWN_INST ) ;
}
Index = ( unsigned int ) Instance - 1 ;
Limit = Index + 1 ;
}
else {
Index = 0 ;
Limit = SKCS_NUM_PROTOCOLS ;
}
/*
* Check action
*/
if ( Action ! = SK_PNMI_GET ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_READ_ONLY ) ;
}
/* Check length */
if ( * pLen < ( Limit - Index ) * sizeof ( SK_U64 ) ) {
* pLen = ( Limit - Index ) * sizeof ( SK_U64 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
/*
* Get value
*/
for ( ; Index < Limit ; Index + + ) {
switch ( Id ) {
case OID_SKGE_CHKSM_RX_OK_CTS :
StatVal = pAC - > Csum . ProtoStats [ NetIndex ] [ Index ] . RxOkCts ;
break ;
case OID_SKGE_CHKSM_RX_UNABLE_CTS :
StatVal = pAC - > Csum . ProtoStats [ NetIndex ] [ Index ] . RxUnableCts ;
break ;
case OID_SKGE_CHKSM_RX_ERR_CTS :
StatVal = pAC - > Csum . ProtoStats [ NetIndex ] [ Index ] . RxErrCts ;
break ;
case OID_SKGE_CHKSM_TX_OK_CTS :
StatVal = pAC - > Csum . ProtoStats [ NetIndex ] [ Index ] . TxOkCts ;
break ;
case OID_SKGE_CHKSM_TX_UNABLE_CTS :
StatVal = pAC - > Csum . ProtoStats [ NetIndex ] [ Index ] . TxUnableCts ;
break ;
default :
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR010 ,
SK_PNMI_ERR010MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
SK_PNMI_STORE_U64 ( pBuf + Offset , StatVal ) ;
Offset + = sizeof ( SK_U64 ) ;
}
/*
* Store used buffer space
*/
* pLen = Offset ;
return ( SK_PNMI_ERR_OK ) ;
}
/*****************************************************************************
*
* SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
*
* Description :
* Retrieves the statistic values of the I2C module , which handles
* the temperature and voltage sensors .
*
* Returns :
* SK_PNMI_ERR_OK The request was successfully performed .
* SK_PNMI_ERR_GENERAL A general severe internal error occured .
* SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
* the correct data ( e . g . a 32 bit value is
* needed , but a 16 bit value was passed ) .
* SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn ' t
* exist ( e . g . port instance 3 on a two port
* adapter .
*/
PNMI_STATIC int SensorStat (
SK_AC * pAC , /* Pointer to adapter context */
SK_IOC IoC , /* IO context handle */
int Action , /* GET/PRESET/SET action */
SK_U32 Id , /* Object ID that is to be processed */
char * pBuf , /* Buffer used for the management data transfer */
unsigned int * pLen , /* On call: pBuf 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 always zero */
{
unsigned int i ;
unsigned int Index ;
unsigned int Limit ;
unsigned int Offset ;
unsigned int Len ;
SK_U32 Val32 ;
SK_U64 Val64 ;
/*
* Calculate instance if wished
*/
if ( ( Instance ! = ( SK_U32 ) ( - 1 ) ) ) {
if ( ( Instance < 1 ) | | ( Instance > ( SK_U32 ) pAC - > I2c . MaxSens ) ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_UNKNOWN_INST ) ;
}
Index = ( unsigned int ) Instance - 1 ;
Limit = ( unsigned int ) Instance ;
}
else {
Index = 0 ;
Limit = ( unsigned int ) pAC - > I2c . MaxSens ;
}
/*
* Check action
*/
if ( Action ! = SK_PNMI_GET ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_READ_ONLY ) ;
}
/* Check length */
switch ( Id ) {
case OID_SKGE_SENSOR_VALUE :
case OID_SKGE_SENSOR_WAR_THRES_LOW :
case OID_SKGE_SENSOR_WAR_THRES_UPP :
case OID_SKGE_SENSOR_ERR_THRES_LOW :
case OID_SKGE_SENSOR_ERR_THRES_UPP :
if ( * pLen < ( Limit - Index ) * sizeof ( SK_U32 ) ) {
* pLen = ( Limit - Index ) * sizeof ( SK_U32 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
break ;
case OID_SKGE_SENSOR_DESCR :
for ( Offset = 0 , i = Index ; i < Limit ; i + + ) {
Len = ( unsigned int )
SK_STRLEN ( pAC - > I2c . SenTable [ i ] . SenDesc ) + 1 ;
if ( Len > = SK_PNMI_STRINGLEN2 ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR011 ,
SK_PNMI_ERR011MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
Offset + = Len ;
}
if ( * pLen < Offset ) {
* pLen = Offset ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
break ;
case OID_SKGE_SENSOR_INDEX :
case OID_SKGE_SENSOR_TYPE :
case OID_SKGE_SENSOR_STATUS :
if ( * pLen < Limit - Index ) {
* pLen = Limit - Index ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
break ;
case OID_SKGE_SENSOR_WAR_CTS :
case OID_SKGE_SENSOR_WAR_TIME :
case OID_SKGE_SENSOR_ERR_CTS :
case OID_SKGE_SENSOR_ERR_TIME :
if ( * pLen < ( Limit - Index ) * sizeof ( SK_U64 ) ) {
* pLen = ( Limit - Index ) * sizeof ( SK_U64 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
break ;
default :
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR012 ,
SK_PNMI_ERR012MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
/*
* Get value
*/
for ( Offset = 0 ; Index < Limit ; Index + + ) {
switch ( Id ) {
case OID_SKGE_SENSOR_INDEX :
* ( pBuf + Offset ) = ( char ) Index ;
Offset + = sizeof ( char ) ;
break ;
case OID_SKGE_SENSOR_DESCR :
Len = SK_STRLEN ( pAC - > I2c . SenTable [ Index ] . SenDesc ) ;
SK_MEMCPY ( pBuf + Offset + 1 ,
pAC - > I2c . SenTable [ Index ] . SenDesc , Len ) ;
* ( pBuf + Offset ) = ( char ) Len ;
Offset + = Len + 1 ;
break ;
case OID_SKGE_SENSOR_TYPE :
* ( pBuf + Offset ) =
( char ) pAC - > I2c . SenTable [ Index ] . SenType ;
Offset + = sizeof ( char ) ;
break ;
case OID_SKGE_SENSOR_VALUE :
Val32 = ( SK_U32 ) pAC - > I2c . SenTable [ Index ] . SenValue ;
SK_PNMI_STORE_U32 ( pBuf + Offset , Val32 ) ;
Offset + = sizeof ( SK_U32 ) ;
break ;
case OID_SKGE_SENSOR_WAR_THRES_LOW :
Val32 = ( SK_U32 ) pAC - > I2c . SenTable [ Index ] .
SenThreWarnLow ;
SK_PNMI_STORE_U32 ( pBuf + Offset , Val32 ) ;
Offset + = sizeof ( SK_U32 ) ;
break ;
case OID_SKGE_SENSOR_WAR_THRES_UPP :
Val32 = ( SK_U32 ) pAC - > I2c . SenTable [ Index ] .
SenThreWarnHigh ;
SK_PNMI_STORE_U32 ( pBuf + Offset , Val32 ) ;
Offset + = sizeof ( SK_U32 ) ;
break ;
case OID_SKGE_SENSOR_ERR_THRES_LOW :
Val32 = ( SK_U32 ) pAC - > I2c . SenTable [ Index ] .
SenThreErrLow ;
SK_PNMI_STORE_U32 ( pBuf + Offset , Val32 ) ;
Offset + = sizeof ( SK_U32 ) ;
break ;
case OID_SKGE_SENSOR_ERR_THRES_UPP :
Val32 = pAC - > I2c . SenTable [ Index ] . SenThreErrHigh ;
SK_PNMI_STORE_U32 ( pBuf + Offset , Val32 ) ;
Offset + = sizeof ( SK_U32 ) ;
break ;
case OID_SKGE_SENSOR_STATUS :
* ( pBuf + Offset ) =
( char ) pAC - > I2c . SenTable [ Index ] . SenErrFlag ;
Offset + = sizeof ( char ) ;
break ;
case OID_SKGE_SENSOR_WAR_CTS :
Val64 = pAC - > I2c . SenTable [ Index ] . SenWarnCts ;
SK_PNMI_STORE_U64 ( pBuf + Offset , Val64 ) ;
Offset + = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_SENSOR_ERR_CTS :
Val64 = pAC - > I2c . SenTable [ Index ] . SenErrCts ;
SK_PNMI_STORE_U64 ( pBuf + Offset , Val64 ) ;
Offset + = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_SENSOR_WAR_TIME :
Val64 = SK_PNMI_HUNDREDS_SEC ( pAC - > I2c . SenTable [ Index ] .
SenBegWarnTS ) ;
SK_PNMI_STORE_U64 ( pBuf + Offset , Val64 ) ;
Offset + = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_SENSOR_ERR_TIME :
Val64 = SK_PNMI_HUNDREDS_SEC ( pAC - > I2c . SenTable [ Index ] .
SenBegErrTS ) ;
SK_PNMI_STORE_U64 ( pBuf + Offset , Val64 ) ;
Offset + = sizeof ( SK_U64 ) ;
break ;
default :
SK_DBG_MSG ( pAC , SK_DBGMOD_PNMI , SK_DBGCAT_ERR ,
( " SensorStat: Unknown OID should be handled before " ) ) ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
}
/*
* Store used buffer space
*/
* pLen = Offset ;
return ( SK_PNMI_ERR_OK ) ;
}
/*****************************************************************************
*
* Vpd - OID handler function of OID_SKGE_VPD_XXX
*
* Description :
* Get / preset / set of VPD data . As instance the name of a VPD key
* can be passed . The Instance parameter is a SK_U32 and can be
* used as a string buffer for the VPD key , because their maximum
* length is 4 byte .
*
* Returns :
* SK_PNMI_ERR_OK The request was successfully performed .
* SK_PNMI_ERR_GENERAL A general severe internal error occured .
* SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
* the correct data ( e . g . a 32 bit value is
* needed , but a 16 bit value was passed ) .
* SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
* value range .
* SK_PNMI_ERR_READ_ONLY The OID is read - only and cannot be set .
* SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn ' t
* exist ( e . g . port instance 3 on a two port
* adapter .
*/
PNMI_STATIC int Vpd (
SK_AC * pAC , /* Pointer to adapter context */
SK_IOC IoC , /* IO context handle */
int Action , /* GET/PRESET/SET action */
SK_U32 Id , /* Object ID that is to be processed */
char * pBuf , /* Buffer used for the management data transfer */
unsigned int * pLen , /* On call: pBuf 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 always zero */
{
SK_VPD_STATUS * pVpdStatus ;
unsigned int BufLen ;
char Buf [ 256 ] ;
char KeyArr [ SK_PNMI_VPD_ENTRIES ] [ SK_PNMI_VPD_KEY_SIZE ] ;
char KeyStr [ SK_PNMI_VPD_KEY_SIZE ] ;
unsigned int KeyNo ;
unsigned int Offset ;
unsigned int Index ;
unsigned int FirstIndex ;
unsigned int LastIndex ;
unsigned int Len ;
int Ret ;
SK_U32 Val32 ;
/*
* Get array of all currently stored VPD keys
*/
Ret = GetVpdKeyArr ( pAC , IoC , & KeyArr [ 0 ] [ 0 ] , sizeof ( KeyArr ) , & KeyNo ) ;
if ( Ret ! = SK_PNMI_ERR_OK ) {
* pLen = 0 ;
return ( Ret ) ;
}
/*
* If instance is not - 1 , try to find the requested VPD key for
* the multiple instance variables . The other OIDs as for example
* OID VPD_ACTION are single instance variables and must be
* handled separatly .
*/
FirstIndex = 0 ;
LastIndex = KeyNo ;
if ( ( Instance ! = ( SK_U32 ) ( - 1 ) ) ) {
if ( Id = = OID_SKGE_VPD_KEY | | Id = = OID_SKGE_VPD_VALUE | |
Id = = OID_SKGE_VPD_ACCESS ) {
SK_STRNCPY ( KeyStr , ( char * ) & Instance , 4 ) ;
KeyStr [ 4 ] = 0 ;
for ( Index = 0 ; Index < KeyNo ; Index + + ) {
if ( SK_STRCMP ( KeyStr , KeyArr [ Index ] ) = = 0 ) {
FirstIndex = Index ;
LastIndex = Index + 1 ;
break ;
}
}
if ( Index = = KeyNo ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_UNKNOWN_INST ) ;
}
}
else if ( Instance ! = 1 ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_UNKNOWN_INST ) ;
}
}
/*
* Get value , if a query should be performed
*/
if ( Action = = SK_PNMI_GET ) {
switch ( Id ) {
case OID_SKGE_VPD_FREE_BYTES :
/* Check length of buffer */
if ( * pLen < sizeof ( SK_U32 ) ) {
* pLen = sizeof ( SK_U32 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
/* Get number of free bytes */
pVpdStatus = VpdStat ( pAC , IoC ) ;
if ( pVpdStatus = = NULL ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR017 ,
SK_PNMI_ERR017MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
if ( ( pVpdStatus - > vpd_status & VPD_VALID ) = = 0 ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR018 ,
SK_PNMI_ERR018MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
Val32 = ( SK_U32 ) pVpdStatus - > vpd_free_rw ;
SK_PNMI_STORE_U32 ( pBuf , Val32 ) ;
* pLen = sizeof ( SK_U32 ) ;
break ;
case OID_SKGE_VPD_ENTRIES_LIST :
/* Check length */
for ( Len = 0 , Index = 0 ; Index < KeyNo ; Index + + ) {
Len + = SK_STRLEN ( KeyArr [ Index ] ) + 1 ;
}
if ( * pLen < Len ) {
* pLen = Len ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
/* Get value */
* ( pBuf ) = ( char ) Len - 1 ;
for ( Offset = 1 , Index = 0 ; Index < KeyNo ; Index + + ) {
Len = SK_STRLEN ( KeyArr [ Index ] ) ;
SK_MEMCPY ( pBuf + Offset , KeyArr [ Index ] , Len ) ;
Offset + = Len ;
if ( Index < KeyNo - 1 ) {
* ( pBuf + Offset ) = ' ' ;
Offset + + ;
}
}
* pLen = Offset ;
break ;
case OID_SKGE_VPD_ENTRIES_NUMBER :
/* Check length */
if ( * pLen < sizeof ( SK_U32 ) ) {
* pLen = sizeof ( SK_U32 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
Val32 = ( SK_U32 ) KeyNo ;
SK_PNMI_STORE_U32 ( pBuf , Val32 ) ;
* pLen = sizeof ( SK_U32 ) ;
break ;
case OID_SKGE_VPD_KEY :
/* Check buffer length, if it is large enough */
for ( Len = 0 , Index = FirstIndex ;
Index < LastIndex ; Index + + ) {
Len + = SK_STRLEN ( KeyArr [ Index ] ) + 1 ;
}
if ( * pLen < Len ) {
* pLen = Len ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
/*
* Get the key to an intermediate buffer , because
* we have to prepend a length byte .
*/
for ( Offset = 0 , Index = FirstIndex ;
Index < LastIndex ; Index + + ) {
Len = SK_STRLEN ( KeyArr [ Index ] ) ;
* ( pBuf + Offset ) = ( char ) Len ;
SK_MEMCPY ( pBuf + Offset + 1 , KeyArr [ Index ] ,
Len ) ;
Offset + = Len + 1 ;
}
* pLen = Offset ;
break ;
case OID_SKGE_VPD_VALUE :
/* Check the buffer length if it is large enough */
for ( Offset = 0 , Index = FirstIndex ;
Index < LastIndex ; Index + + ) {
BufLen = 256 ;
if ( VpdRead ( pAC , IoC , KeyArr [ Index ] , Buf ,
( int * ) & BufLen ) > 0 | |
BufLen > = SK_PNMI_VPD_DATALEN ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW ,
SK_PNMI_ERR021 ,
SK_PNMI_ERR021MSG ) ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
Offset + = BufLen + 1 ;
}
if ( * pLen < Offset ) {
* pLen = Offset ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
/*
* Get the value to an intermediate buffer , because
* we have to prepend a length byte .
*/
for ( Offset = 0 , Index = FirstIndex ;
Index < LastIndex ; Index + + ) {
BufLen = 256 ;
if ( VpdRead ( pAC , IoC , KeyArr [ Index ] , Buf ,
( int * ) & BufLen ) > 0 | |
BufLen > = SK_PNMI_VPD_DATALEN ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW ,
SK_PNMI_ERR022 ,
SK_PNMI_ERR022MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
* ( pBuf + Offset ) = ( char ) BufLen ;
SK_MEMCPY ( pBuf + Offset + 1 , Buf , BufLen ) ;
Offset + = BufLen + 1 ;
}
* pLen = Offset ;
break ;
case OID_SKGE_VPD_ACCESS :
if ( * pLen < LastIndex - FirstIndex ) {
* pLen = LastIndex - FirstIndex ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
for ( Offset = 0 , Index = FirstIndex ;
Index < LastIndex ; Index + + ) {
if ( VpdMayWrite ( KeyArr [ Index ] ) ) {
* ( pBuf + Offset ) = SK_PNMI_VPD_RW ;
}
else {
* ( pBuf + Offset ) = SK_PNMI_VPD_RO ;
}
Offset + + ;
}
* pLen = Offset ;
break ;
case OID_SKGE_VPD_ACTION :
Offset = LastIndex - FirstIndex ;
if ( * pLen < Offset ) {
* pLen = Offset ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
SK_MEMSET ( pBuf , 0 , Offset ) ;
* pLen = Offset ;
break ;
default :
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR023 ,
SK_PNMI_ERR023MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
}
else {
/* The only OID which can be set is VPD_ACTION */
if ( Id ! = OID_SKGE_VPD_ACTION ) {
if ( Id = = OID_SKGE_VPD_FREE_BYTES | |
Id = = OID_SKGE_VPD_ENTRIES_LIST | |
Id = = OID_SKGE_VPD_ENTRIES_NUMBER | |
Id = = OID_SKGE_VPD_KEY | |
Id = = OID_SKGE_VPD_VALUE | |
Id = = OID_SKGE_VPD_ACCESS ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_READ_ONLY ) ;
}
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR024 ,
SK_PNMI_ERR024MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
/*
* From this point we handle VPD_ACTION . Check the buffer
* length . It should at least have the size of one byte .
*/
if ( * pLen < 1 ) {
* pLen = 1 ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
/*
* The first byte contains the VPD action type we should
* perform .
*/
switch ( * pBuf ) {
case SK_PNMI_VPD_IGNORE :
/* Nothing to do */
break ;
case SK_PNMI_VPD_CREATE :
/*
* We have to create a new VPD entry or we modify
* an existing one . Check first the buffer length .
*/
if ( * pLen < 4 ) {
* pLen = 4 ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
KeyStr [ 0 ] = pBuf [ 1 ] ;
KeyStr [ 1 ] = pBuf [ 2 ] ;
KeyStr [ 2 ] = 0 ;
/*
* Is the entry writable or does it belong to the
* read - only area ?
*/
if ( ! VpdMayWrite ( KeyStr ) ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_BAD_VALUE ) ;
}
Offset = ( int ) pBuf [ 3 ] & 0xFF ;
SK_MEMCPY ( Buf , pBuf + 4 , Offset ) ;
Buf [ Offset ] = 0 ;
/* A preset ends here */
if ( Action = = SK_PNMI_PRESET ) {
return ( SK_PNMI_ERR_OK ) ;
}
/* Write the new entry or modify an existing one */
Ret = VpdWrite ( pAC , IoC , KeyStr , Buf ) ;
if ( Ret = = SK_PNMI_VPD_NOWRITE ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_BAD_VALUE ) ;
}
else if ( Ret ! = SK_PNMI_VPD_OK ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR025 ,
SK_PNMI_ERR025MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
/*
* Perform an update of the VPD data . This is
* not mandantory , but just to be sure .
*/
Ret = VpdUpdate ( pAC , IoC ) ;
if ( Ret ! = SK_PNMI_VPD_OK ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR026 ,
SK_PNMI_ERR026MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
break ;
case SK_PNMI_VPD_DELETE :
/* Check if the buffer size is plausible */
if ( * pLen < 3 ) {
* pLen = 3 ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
if ( * pLen > 3 ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_BAD_VALUE ) ;
}
KeyStr [ 0 ] = pBuf [ 1 ] ;
KeyStr [ 1 ] = pBuf [ 2 ] ;
KeyStr [ 2 ] = 0 ;
/* Find the passed key in the array */
for ( Index = 0 ; Index < KeyNo ; Index + + ) {
if ( SK_STRCMP ( KeyStr , KeyArr [ Index ] ) = = 0 ) {
break ;
}
}
/*
* If we cannot find the key it is wrong , so we
* return an appropriate error value .
*/
if ( Index = = KeyNo ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_BAD_VALUE ) ;
}
if ( Action = = SK_PNMI_PRESET ) {
return ( SK_PNMI_ERR_OK ) ;
}
/* Ok, you wanted it and you will get it */
Ret = VpdDelete ( pAC , IoC , KeyStr ) ;
if ( Ret ! = SK_PNMI_VPD_OK ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR027 ,
SK_PNMI_ERR027MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
/*
* Perform an update of the VPD data . This is
* not mandantory , but just to be sure .
*/
Ret = VpdUpdate ( pAC , IoC ) ;
if ( Ret ! = SK_PNMI_VPD_OK ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR028 ,
SK_PNMI_ERR028MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
break ;
default :
* pLen = 0 ;
return ( SK_PNMI_ERR_BAD_VALUE ) ;
}
}
return ( SK_PNMI_ERR_OK ) ;
}
/*****************************************************************************
*
* General - OID handler function of various single instance OIDs
*
* Description :
* The code is simple . No description necessary .
*
* Returns :
* SK_PNMI_ERR_OK The request was successfully performed .
* SK_PNMI_ERR_GENERAL A general severe internal error occured .
* SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
* the correct data ( e . g . a 32 bit value is
* needed , but a 16 bit value was passed ) .
* SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn ' t
* exist ( e . g . port instance 3 on a two port
* adapter .
*/
PNMI_STATIC int General (
SK_AC * pAC , /* Pointer to adapter context */
SK_IOC IoC , /* IO context handle */
int Action , /* GET/PRESET/SET action */
SK_U32 Id , /* Object ID that is to be processed */
char * pBuf , /* Buffer used for the management data transfer */
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 always zero */
{
int Ret ;
unsigned int Index ;
unsigned int Len ;
unsigned int Offset ;
unsigned int Val ;
SK_U8 Val8 ;
SK_U16 Val16 ;
SK_U32 Val32 ;
SK_U64 Val64 ;
SK_U64 Val64RxHwErrs = 0 ;
SK_U64 Val64TxHwErrs = 0 ;
SK_BOOL Is64BitReq = SK_FALSE ;
char Buf [ 256 ] ;
int MacType ;
/*
* Check instance . We only handle single instance variables .
*/
if ( Instance ! = ( SK_U32 ) ( - 1 ) & & Instance ! = 1 ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_UNKNOWN_INST ) ;
}
/*
* Check action . We only allow get requests .
*/
if ( Action ! = SK_PNMI_GET ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_READ_ONLY ) ;
}
MacType = pAC - > GIni . GIMacType ;
/*
* Check length for the various supported OIDs
*/
switch ( Id ) {
case OID_GEN_XMIT_ERROR :
case OID_GEN_RCV_ERROR :
case OID_GEN_RCV_NO_BUFFER :
# ifndef SK_NDIS_64BIT_CTR
if ( * pLen < sizeof ( SK_U32 ) ) {
* pLen = sizeof ( SK_U32 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
# else /* SK_NDIS_64BIT_CTR */
/*
* for compatibility , at least 32 bit are required for oid
*/
if ( * pLen < sizeof ( SK_U32 ) ) {
/*
* but indicate handling for 64 bit values ,
* if insufficient space is provided
*/
* pLen = sizeof ( SK_U64 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
Is64BitReq = ( * pLen < sizeof ( SK_U64 ) ) ? SK_FALSE : SK_TRUE ;
# endif /* SK_NDIS_64BIT_CTR */
break ;
case OID_SKGE_PORT_NUMBER :
case OID_SKGE_DEVICE_TYPE :
case OID_SKGE_RESULT :
case OID_SKGE_RLMT_MONITOR_NUMBER :
case OID_GEN_TRANSMIT_QUEUE_LENGTH :
case OID_SKGE_TRAP_NUMBER :
case OID_SKGE_MDB_VERSION :
case OID_SKGE_BOARDLEVEL :
case OID_SKGE_CHIPID :
case OID_SKGE_RAMSIZE :
if ( * pLen < sizeof ( SK_U32 ) ) {
* pLen = sizeof ( SK_U32 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
break ;
case OID_SKGE_CHIPSET :
if ( * pLen < sizeof ( SK_U16 ) ) {
* pLen = sizeof ( SK_U16 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
break ;
case OID_SKGE_BUS_TYPE :
case OID_SKGE_BUS_SPEED :
case OID_SKGE_BUS_WIDTH :
case OID_SKGE_SENSOR_NUMBER :
case OID_SKGE_CHKSM_NUMBER :
case OID_SKGE_VAUXAVAIL :
if ( * pLen < sizeof ( SK_U8 ) ) {
* pLen = sizeof ( SK_U8 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
break ;
case OID_SKGE_TX_SW_QUEUE_LEN :
case OID_SKGE_TX_SW_QUEUE_MAX :
case OID_SKGE_TX_RETRY :
case OID_SKGE_RX_INTR_CTS :
case OID_SKGE_TX_INTR_CTS :
case OID_SKGE_RX_NO_BUF_CTS :
case OID_SKGE_TX_NO_BUF_CTS :
case OID_SKGE_TX_USED_DESCR_NO :
case OID_SKGE_RX_DELIVERED_CTS :
case OID_SKGE_RX_OCTETS_DELIV_CTS :
case OID_SKGE_RX_HW_ERROR_CTS :
case OID_SKGE_TX_HW_ERROR_CTS :
case OID_SKGE_IN_ERRORS_CTS :
case OID_SKGE_OUT_ERROR_CTS :
case OID_SKGE_ERR_RECOVERY_CTS :
case OID_SKGE_SYSUPTIME :
if ( * pLen < sizeof ( SK_U64 ) ) {
* pLen = sizeof ( SK_U64 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
break ;
default :
/* Checked later */
break ;
}
/* Update statistic */
if ( Id = = OID_SKGE_RX_HW_ERROR_CTS | |
Id = = OID_SKGE_TX_HW_ERROR_CTS | |
Id = = OID_SKGE_IN_ERRORS_CTS | |
Id = = OID_SKGE_OUT_ERROR_CTS | |
Id = = OID_GEN_XMIT_ERROR | |
Id = = OID_GEN_RCV_ERROR ) {
/* Force the XMAC to update its statistic counters and
* Increment semaphore to indicate that an update was
* already done .
*/
Ret = MacUpdate ( pAC , IoC , 0 , pAC - > GIni . GIMacsFound - 1 ) ;
if ( Ret ! = SK_PNMI_ERR_OK ) {
* pLen = 0 ;
return ( Ret ) ;
}
pAC - > Pnmi . MacUpdatedFlag + + ;
/*
* Some OIDs consist of multiple hardware counters . Those
* values which are contained in all of them will be added
* now .
*/
switch ( Id ) {
case OID_SKGE_RX_HW_ERROR_CTS :
case OID_SKGE_IN_ERRORS_CTS :
case OID_GEN_RCV_ERROR :
Val64RxHwErrs =
GetStatVal ( pAC , IoC , 0 , SK_PNMI_HRX_MISSED , NetIndex ) +
GetStatVal ( pAC , IoC , 0 , SK_PNMI_HRX_FRAMING , NetIndex ) +
GetStatVal ( pAC , IoC , 0 , SK_PNMI_HRX_OVERFLOW , NetIndex ) +
GetStatVal ( pAC , IoC , 0 , SK_PNMI_HRX_JABBER , NetIndex ) +
GetStatVal ( pAC , IoC , 0 , SK_PNMI_HRX_CARRIER , NetIndex ) +
GetStatVal ( pAC , IoC , 0 , SK_PNMI_HRX_IRLENGTH , NetIndex ) +
GetStatVal ( pAC , IoC , 0 , SK_PNMI_HRX_SYMBOL , NetIndex ) +
GetStatVal ( pAC , IoC , 0 , SK_PNMI_HRX_SHORTS , NetIndex ) +
GetStatVal ( pAC , IoC , 0 , SK_PNMI_HRX_RUNT , NetIndex ) +
GetStatVal ( pAC , IoC , 0 , SK_PNMI_HRX_TOO_LONG , NetIndex ) +
GetStatVal ( pAC , IoC , 0 , SK_PNMI_HRX_FCS , NetIndex ) +
GetStatVal ( pAC , IoC , 0 , SK_PNMI_HRX_CEXT , NetIndex ) ;
break ;
case OID_SKGE_TX_HW_ERROR_CTS :
case OID_SKGE_OUT_ERROR_CTS :
case OID_GEN_XMIT_ERROR :
Val64TxHwErrs =
GetStatVal ( pAC , IoC , 0 , SK_PNMI_HTX_EXCESS_COL , NetIndex ) +
GetStatVal ( pAC , IoC , 0 , SK_PNMI_HTX_LATE_COL , NetIndex ) +
GetStatVal ( pAC , IoC , 0 , SK_PNMI_HTX_UNDERRUN , NetIndex ) +
GetStatVal ( pAC , IoC , 0 , SK_PNMI_HTX_CARRIER , NetIndex ) ;
break ;
}
}
/*
* Retrieve value
*/
switch ( Id ) {
case OID_SKGE_SUPPORTED_LIST :
Len = ID_TABLE_SIZE * sizeof ( SK_U32 ) ;
if ( * pLen < Len ) {
* pLen = Len ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
for ( Offset = 0 , Index = 0 ; Offset < Len ;
Offset + = sizeof ( SK_U32 ) , Index + + ) {
Val32 = ( SK_U32 ) IdTable [ Index ] . Id ;
SK_PNMI_STORE_U32 ( pBuf + Offset , Val32 ) ;
}
* pLen = Len ;
break ;
case OID_SKGE_BOARDLEVEL :
Val32 = ( SK_U32 ) pAC - > GIni . GILevel ;
SK_PNMI_STORE_U32 ( pBuf , Val32 ) ;
* pLen = sizeof ( SK_U32 ) ;
break ;
case OID_SKGE_PORT_NUMBER :
Val32 = ( SK_U32 ) pAC - > GIni . GIMacsFound ;
SK_PNMI_STORE_U32 ( pBuf , Val32 ) ;
* pLen = sizeof ( SK_U32 ) ;
break ;
case OID_SKGE_DEVICE_TYPE :
Val32 = ( SK_U32 ) pAC - > Pnmi . DeviceType ;
SK_PNMI_STORE_U32 ( pBuf , Val32 ) ;
* pLen = sizeof ( SK_U32 ) ;
break ;
case OID_SKGE_DRIVER_DESCR :
if ( pAC - > Pnmi . pDriverDescription = = NULL ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR007 ,
SK_PNMI_ERR007MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
Len = SK_STRLEN ( pAC - > Pnmi . pDriverDescription ) + 1 ;
if ( Len > SK_PNMI_STRINGLEN1 ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR029 ,
SK_PNMI_ERR029MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
if ( * pLen < Len ) {
* pLen = Len ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
* pBuf = ( char ) ( Len - 1 ) ;
SK_MEMCPY ( pBuf + 1 , pAC - > Pnmi . pDriverDescription , Len - 1 ) ;
* pLen = Len ;
break ;
case OID_SKGE_DRIVER_VERSION :
if ( pAC - > Pnmi . pDriverVersion = = NULL ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR030 ,
SK_PNMI_ERR030MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
Len = SK_STRLEN ( pAC - > Pnmi . pDriverVersion ) + 1 ;
if ( Len > SK_PNMI_STRINGLEN1 ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR031 ,
SK_PNMI_ERR031MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
if ( * pLen < Len ) {
* pLen = Len ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
* pBuf = ( char ) ( Len - 1 ) ;
SK_MEMCPY ( pBuf + 1 , pAC - > Pnmi . pDriverVersion , Len - 1 ) ;
* pLen = Len ;
break ;
case OID_SKGE_DRIVER_RELDATE :
if ( pAC - > Pnmi . pDriverReleaseDate = = NULL ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR030 ,
SK_PNMI_ERR053MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
Len = SK_STRLEN ( pAC - > Pnmi . pDriverReleaseDate ) + 1 ;
if ( Len > SK_PNMI_STRINGLEN1 ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR031 ,
SK_PNMI_ERR054MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
if ( * pLen < Len ) {
* pLen = Len ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
* pBuf = ( char ) ( Len - 1 ) ;
SK_MEMCPY ( pBuf + 1 , pAC - > Pnmi . pDriverReleaseDate , Len - 1 ) ;
* pLen = Len ;
break ;
case OID_SKGE_DRIVER_FILENAME :
if ( pAC - > Pnmi . pDriverFileName = = NULL ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR030 ,
SK_PNMI_ERR055MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
Len = SK_STRLEN ( pAC - > Pnmi . pDriverFileName ) + 1 ;
if ( Len > SK_PNMI_STRINGLEN1 ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR031 ,
SK_PNMI_ERR056MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
if ( * pLen < Len ) {
* pLen = Len ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
* pBuf = ( char ) ( Len - 1 ) ;
SK_MEMCPY ( pBuf + 1 , pAC - > Pnmi . pDriverFileName , Len - 1 ) ;
* pLen = Len ;
break ;
case OID_SKGE_HW_DESCR :
/*
* The hardware description is located in the VPD . This
* query may move to the initialisation routine . But
* the VPD data is cached and therefore a call here
* will not make much difference .
*/
Len = 256 ;
if ( VpdRead ( pAC , IoC , VPD_NAME , Buf , ( int * ) & Len ) > 0 ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR032 ,
SK_PNMI_ERR032MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
Len + + ;
if ( Len > SK_PNMI_STRINGLEN1 ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR033 ,
SK_PNMI_ERR033MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
if ( * pLen < Len ) {
* pLen = Len ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
* pBuf = ( char ) ( Len - 1 ) ;
SK_MEMCPY ( pBuf + 1 , Buf , Len - 1 ) ;
* pLen = Len ;
break ;
case OID_SKGE_HW_VERSION :
/* Oh, I love to do some string manipulation */
if ( * pLen < 5 ) {
* pLen = 5 ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
Val8 = ( SK_U8 ) pAC - > GIni . GIPciHwRev ;
pBuf [ 0 ] = 4 ;
pBuf [ 1 ] = ' v ' ;
pBuf [ 2 ] = ( char ) ( 0x30 | ( ( Val8 > > 4 ) & 0x0F ) ) ;
pBuf [ 3 ] = ' . ' ;
pBuf [ 4 ] = ( char ) ( 0x30 | ( Val8 & 0x0F ) ) ;
* pLen = 5 ;
break ;
case OID_SKGE_CHIPSET :
Val16 = pAC - > Pnmi . Chipset ;
SK_PNMI_STORE_U16 ( pBuf , Val16 ) ;
* pLen = sizeof ( SK_U16 ) ;
break ;
case OID_SKGE_CHIPID :
Val32 = pAC - > GIni . GIChipId ;
SK_PNMI_STORE_U32 ( pBuf , Val32 ) ;
* pLen = sizeof ( SK_U32 ) ;
break ;
case OID_SKGE_RAMSIZE :
Val32 = pAC - > GIni . GIRamSize ;
SK_PNMI_STORE_U32 ( pBuf , Val32 ) ;
* pLen = sizeof ( SK_U32 ) ;
break ;
case OID_SKGE_VAUXAVAIL :
* pBuf = ( char ) pAC - > GIni . GIVauxAvail ;
* pLen = sizeof ( char ) ;
break ;
case OID_SKGE_BUS_TYPE :
* pBuf = ( char ) SK_PNMI_BUS_PCI ;
* pLen = sizeof ( char ) ;
break ;
case OID_SKGE_BUS_SPEED :
* pBuf = pAC - > Pnmi . PciBusSpeed ;
* pLen = sizeof ( char ) ;
break ;
case OID_SKGE_BUS_WIDTH :
* pBuf = pAC - > Pnmi . PciBusWidth ;
* pLen = sizeof ( char ) ;
break ;
case OID_SKGE_RESULT :
Val32 = pAC - > Pnmi . TestResult ;
SK_PNMI_STORE_U32 ( pBuf , Val32 ) ;
* pLen = sizeof ( SK_U32 ) ;
break ;
case OID_SKGE_SENSOR_NUMBER :
* pBuf = ( char ) pAC - > I2c . MaxSens ;
* pLen = sizeof ( char ) ;
break ;
case OID_SKGE_CHKSM_NUMBER :
* pBuf = SKCS_NUM_PROTOCOLS ;
* pLen = sizeof ( char ) ;
break ;
case OID_SKGE_TRAP_NUMBER :
GetTrapQueueLen ( pAC , & Len , & Val ) ;
Val32 = ( SK_U32 ) Val ;
SK_PNMI_STORE_U32 ( pBuf , Val32 ) ;
* pLen = sizeof ( SK_U32 ) ;
break ;
case OID_SKGE_TRAP :
GetTrapQueueLen ( pAC , & Len , & Val ) ;
if ( * pLen < Len ) {
* pLen = Len ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
CopyTrapQueue ( pAC , pBuf ) ;
* pLen = Len ;
break ;
case OID_SKGE_RLMT_MONITOR_NUMBER :
/* XXX Not yet implemented by RLMT therefore we return zero elements */
Val32 = 0 ;
SK_PNMI_STORE_U32 ( pBuf , Val32 ) ;
* pLen = sizeof ( SK_U32 ) ;
break ;
case OID_SKGE_TX_SW_QUEUE_LEN :
/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
if ( MacType = = SK_MAC_XMAC ) {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = pAC - > Pnmi . BufPort [ NetIndex ] . TxSwQueueLen ;
}
/* Single net mode */
else {
Val64 = pAC - > Pnmi . BufPort [ 0 ] . TxSwQueueLen +
pAC - > Pnmi . BufPort [ 1 ] . TxSwQueueLen ;
}
}
else {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = pAC - > Pnmi . Port [ NetIndex ] . TxSwQueueLen ;
}
/* Single net mode */
else {
Val64 = pAC - > Pnmi . Port [ 0 ] . TxSwQueueLen +
pAC - > Pnmi . Port [ 1 ] . TxSwQueueLen ;
}
}
SK_PNMI_STORE_U64 ( pBuf , Val64 ) ;
* pLen = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_TX_SW_QUEUE_MAX :
/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
if ( MacType = = SK_MAC_XMAC ) {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = pAC - > Pnmi . BufPort [ NetIndex ] . TxSwQueueMax ;
}
/* Single net mode */
else {
Val64 = pAC - > Pnmi . BufPort [ 0 ] . TxSwQueueMax +
pAC - > Pnmi . BufPort [ 1 ] . TxSwQueueMax ;
}
}
else {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = pAC - > Pnmi . Port [ NetIndex ] . TxSwQueueMax ;
}
/* Single net mode */
else {
Val64 = pAC - > Pnmi . Port [ 0 ] . TxSwQueueMax +
pAC - > Pnmi . Port [ 1 ] . TxSwQueueMax ;
}
}
SK_PNMI_STORE_U64 ( pBuf , Val64 ) ;
* pLen = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_TX_RETRY :
/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
if ( MacType = = SK_MAC_XMAC ) {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = pAC - > Pnmi . BufPort [ NetIndex ] . TxRetryCts ;
}
/* Single net mode */
else {
Val64 = pAC - > Pnmi . BufPort [ 0 ] . TxRetryCts +
pAC - > Pnmi . BufPort [ 1 ] . TxRetryCts ;
}
}
else {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = pAC - > Pnmi . Port [ NetIndex ] . TxRetryCts ;
}
/* Single net mode */
else {
Val64 = pAC - > Pnmi . Port [ 0 ] . TxRetryCts +
pAC - > Pnmi . Port [ 1 ] . TxRetryCts ;
}
}
SK_PNMI_STORE_U64 ( pBuf , Val64 ) ;
* pLen = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_RX_INTR_CTS :
/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
if ( MacType = = SK_MAC_XMAC ) {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = pAC - > Pnmi . BufPort [ NetIndex ] . RxIntrCts ;
}
/* Single net mode */
else {
Val64 = pAC - > Pnmi . BufPort [ 0 ] . RxIntrCts +
pAC - > Pnmi . BufPort [ 1 ] . RxIntrCts ;
}
}
else {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = pAC - > Pnmi . Port [ NetIndex ] . RxIntrCts ;
}
/* Single net mode */
else {
Val64 = pAC - > Pnmi . Port [ 0 ] . RxIntrCts +
pAC - > Pnmi . Port [ 1 ] . RxIntrCts ;
}
}
SK_PNMI_STORE_U64 ( pBuf , Val64 ) ;
* pLen = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_TX_INTR_CTS :
/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
if ( MacType = = SK_MAC_XMAC ) {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = pAC - > Pnmi . BufPort [ NetIndex ] . TxIntrCts ;
}
/* Single net mode */
else {
Val64 = pAC - > Pnmi . BufPort [ 0 ] . TxIntrCts +
pAC - > Pnmi . BufPort [ 1 ] . TxIntrCts ;
}
}
else {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = pAC - > Pnmi . Port [ NetIndex ] . TxIntrCts ;
}
/* Single net mode */
else {
Val64 = pAC - > Pnmi . Port [ 0 ] . TxIntrCts +
pAC - > Pnmi . Port [ 1 ] . TxIntrCts ;
}
}
SK_PNMI_STORE_U64 ( pBuf , Val64 ) ;
* pLen = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_RX_NO_BUF_CTS :
/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
if ( MacType = = SK_MAC_XMAC ) {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = pAC - > Pnmi . BufPort [ NetIndex ] . RxNoBufCts ;
}
/* Single net mode */
else {
Val64 = pAC - > Pnmi . BufPort [ 0 ] . RxNoBufCts +
pAC - > Pnmi . BufPort [ 1 ] . RxNoBufCts ;
}
}
else {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = pAC - > Pnmi . Port [ NetIndex ] . RxNoBufCts ;
}
/* Single net mode */
else {
Val64 = pAC - > Pnmi . Port [ 0 ] . RxNoBufCts +
pAC - > Pnmi . Port [ 1 ] . RxNoBufCts ;
}
}
SK_PNMI_STORE_U64 ( pBuf , Val64 ) ;
* pLen = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_TX_NO_BUF_CTS :
/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
if ( MacType = = SK_MAC_XMAC ) {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = pAC - > Pnmi . BufPort [ NetIndex ] . TxNoBufCts ;
}
/* Single net mode */
else {
Val64 = pAC - > Pnmi . BufPort [ 0 ] . TxNoBufCts +
pAC - > Pnmi . BufPort [ 1 ] . TxNoBufCts ;
}
}
else {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = pAC - > Pnmi . Port [ NetIndex ] . TxNoBufCts ;
}
/* Single net mode */
else {
Val64 = pAC - > Pnmi . Port [ 0 ] . TxNoBufCts +
pAC - > Pnmi . Port [ 1 ] . TxNoBufCts ;
}
}
SK_PNMI_STORE_U64 ( pBuf , Val64 ) ;
* pLen = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_TX_USED_DESCR_NO :
/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
if ( MacType = = SK_MAC_XMAC ) {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = pAC - > Pnmi . BufPort [ NetIndex ] . TxUsedDescrNo ;
}
/* Single net mode */
else {
Val64 = pAC - > Pnmi . BufPort [ 0 ] . TxUsedDescrNo +
pAC - > Pnmi . BufPort [ 1 ] . TxUsedDescrNo ;
}
}
else {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = pAC - > Pnmi . Port [ NetIndex ] . TxUsedDescrNo ;
}
/* Single net mode */
else {
Val64 = pAC - > Pnmi . Port [ 0 ] . TxUsedDescrNo +
pAC - > Pnmi . Port [ 1 ] . TxUsedDescrNo ;
}
}
SK_PNMI_STORE_U64 ( pBuf , Val64 ) ;
* pLen = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_RX_DELIVERED_CTS :
/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
if ( MacType = = SK_MAC_XMAC ) {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = pAC - > Pnmi . BufPort [ NetIndex ] . RxDeliveredCts ;
}
/* Single net mode */
else {
Val64 = pAC - > Pnmi . BufPort [ 0 ] . RxDeliveredCts +
pAC - > Pnmi . BufPort [ 1 ] . RxDeliveredCts ;
}
}
else {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = pAC - > Pnmi . Port [ NetIndex ] . RxDeliveredCts ;
}
/* Single net mode */
else {
Val64 = pAC - > Pnmi . Port [ 0 ] . RxDeliveredCts +
pAC - > Pnmi . Port [ 1 ] . RxDeliveredCts ;
}
}
SK_PNMI_STORE_U64 ( pBuf , Val64 ) ;
* pLen = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_RX_OCTETS_DELIV_CTS :
/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
if ( MacType = = SK_MAC_XMAC ) {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = pAC - > Pnmi . BufPort [ NetIndex ] . RxOctetsDeliveredCts ;
}
/* Single net mode */
else {
Val64 = pAC - > Pnmi . BufPort [ 0 ] . RxOctetsDeliveredCts +
pAC - > Pnmi . BufPort [ 1 ] . RxOctetsDeliveredCts ;
}
}
else {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = pAC - > Pnmi . Port [ NetIndex ] . RxOctetsDeliveredCts ;
}
/* Single net mode */
else {
Val64 = pAC - > Pnmi . Port [ 0 ] . RxOctetsDeliveredCts +
pAC - > Pnmi . Port [ 1 ] . RxOctetsDeliveredCts ;
}
}
SK_PNMI_STORE_U64 ( pBuf , Val64 ) ;
* pLen = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_RX_HW_ERROR_CTS :
SK_PNMI_STORE_U64 ( pBuf , Val64RxHwErrs ) ;
* pLen = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_TX_HW_ERROR_CTS :
SK_PNMI_STORE_U64 ( pBuf , Val64TxHwErrs ) ;
* pLen = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_IN_ERRORS_CTS :
/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
if ( MacType = = SK_MAC_XMAC ) {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = Val64RxHwErrs + pAC - > Pnmi . BufPort [ NetIndex ] . RxNoBufCts ;
}
/* Single net mode */
else {
Val64 = Val64RxHwErrs +
pAC - > Pnmi . BufPort [ 0 ] . RxNoBufCts +
pAC - > Pnmi . BufPort [ 1 ] . RxNoBufCts ;
}
}
else {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = Val64RxHwErrs + pAC - > Pnmi . Port [ NetIndex ] . RxNoBufCts ;
}
/* Single net mode */
else {
Val64 = Val64RxHwErrs +
pAC - > Pnmi . Port [ 0 ] . RxNoBufCts +
pAC - > Pnmi . Port [ 1 ] . RxNoBufCts ;
}
}
SK_PNMI_STORE_U64 ( pBuf , Val64 ) ;
* pLen = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_OUT_ERROR_CTS :
/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
if ( MacType = = SK_MAC_XMAC ) {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = Val64TxHwErrs + pAC - > Pnmi . BufPort [ NetIndex ] . TxNoBufCts ;
}
/* Single net mode */
else {
Val64 = Val64TxHwErrs +
pAC - > Pnmi . BufPort [ 0 ] . TxNoBufCts +
pAC - > Pnmi . BufPort [ 1 ] . TxNoBufCts ;
}
}
else {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = Val64TxHwErrs + pAC - > Pnmi . Port [ NetIndex ] . TxNoBufCts ;
}
/* Single net mode */
else {
Val64 = Val64TxHwErrs +
pAC - > Pnmi . Port [ 0 ] . TxNoBufCts +
pAC - > Pnmi . Port [ 1 ] . TxNoBufCts ;
}
}
SK_PNMI_STORE_U64 ( pBuf , Val64 ) ;
* pLen = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_ERR_RECOVERY_CTS :
/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
if ( MacType = = SK_MAC_XMAC ) {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = pAC - > Pnmi . BufPort [ NetIndex ] . ErrRecoveryCts ;
}
/* Single net mode */
else {
Val64 = pAC - > Pnmi . BufPort [ 0 ] . ErrRecoveryCts +
pAC - > Pnmi . BufPort [ 1 ] . ErrRecoveryCts ;
}
}
else {
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
Val64 = pAC - > Pnmi . Port [ NetIndex ] . ErrRecoveryCts ;
}
/* Single net mode */
else {
Val64 = pAC - > Pnmi . Port [ 0 ] . ErrRecoveryCts +
pAC - > Pnmi . Port [ 1 ] . ErrRecoveryCts ;
}
}
SK_PNMI_STORE_U64 ( pBuf , Val64 ) ;
* pLen = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_SYSUPTIME :
Val64 = SK_PNMI_HUNDREDS_SEC ( SkOsGetTime ( pAC ) ) ;
Val64 - = pAC - > Pnmi . StartUpTime ;
SK_PNMI_STORE_U64 ( pBuf , Val64 ) ;
* pLen = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_MDB_VERSION :
Val32 = SK_PNMI_MDB_VERSION ;
SK_PNMI_STORE_U32 ( pBuf , Val32 ) ;
* pLen = sizeof ( SK_U32 ) ;
break ;
case OID_GEN_RCV_ERROR :
/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
if ( MacType = = SK_MAC_XMAC ) {
Val64 = Val64RxHwErrs + pAC - > Pnmi . BufPort [ NetIndex ] . RxNoBufCts ;
}
else {
Val64 = Val64RxHwErrs + pAC - > Pnmi . Port [ NetIndex ] . RxNoBufCts ;
}
/*
* by default 32 bit values are evaluated
*/
if ( ! Is64BitReq ) {
Val32 = ( SK_U32 ) Val64 ;
SK_PNMI_STORE_U32 ( pBuf , Val32 ) ;
* pLen = sizeof ( SK_U32 ) ;
}
else {
SK_PNMI_STORE_U64 ( pBuf , Val64 ) ;
* pLen = sizeof ( SK_U64 ) ;
}
break ;
case OID_GEN_XMIT_ERROR :
/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
if ( MacType = = SK_MAC_XMAC ) {
Val64 = Val64TxHwErrs + pAC - > Pnmi . BufPort [ NetIndex ] . TxNoBufCts ;
}
else {
Val64 = Val64TxHwErrs + pAC - > Pnmi . Port [ NetIndex ] . TxNoBufCts ;
}
/*
* by default 32 bit values are evaluated
*/
if ( ! Is64BitReq ) {
Val32 = ( SK_U32 ) Val64 ;
SK_PNMI_STORE_U32 ( pBuf , Val32 ) ;
* pLen = sizeof ( SK_U32 ) ;
}
else {
SK_PNMI_STORE_U64 ( pBuf , Val64 ) ;
* pLen = sizeof ( SK_U64 ) ;
}
break ;
case OID_GEN_RCV_NO_BUFFER :
/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
if ( MacType = = SK_MAC_XMAC ) {
Val64 = pAC - > Pnmi . BufPort [ NetIndex ] . RxNoBufCts ;
}
else {
Val64 = pAC - > Pnmi . Port [ NetIndex ] . RxNoBufCts ;
}
/*
* by default 32 bit values are evaluated
*/
if ( ! Is64BitReq ) {
Val32 = ( SK_U32 ) Val64 ;
SK_PNMI_STORE_U32 ( pBuf , Val32 ) ;
* pLen = sizeof ( SK_U32 ) ;
}
else {
SK_PNMI_STORE_U64 ( pBuf , Val64 ) ;
* pLen = sizeof ( SK_U64 ) ;
}
break ;
case OID_GEN_TRANSMIT_QUEUE_LENGTH :
Val32 = ( SK_U32 ) pAC - > Pnmi . Port [ NetIndex ] . TxSwQueueLen ;
SK_PNMI_STORE_U32 ( pBuf , Val32 ) ;
* pLen = sizeof ( SK_U32 ) ;
break ;
default :
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR034 ,
SK_PNMI_ERR034MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
if ( Id = = OID_SKGE_RX_HW_ERROR_CTS | |
Id = = OID_SKGE_TX_HW_ERROR_CTS | |
Id = = OID_SKGE_IN_ERRORS_CTS | |
Id = = OID_SKGE_OUT_ERROR_CTS | |
Id = = OID_GEN_XMIT_ERROR | |
Id = = OID_GEN_RCV_ERROR ) {
pAC - > Pnmi . MacUpdatedFlag - - ;
}
return ( SK_PNMI_ERR_OK ) ;
}
/*****************************************************************************
*
* Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance .
*
* Description :
* Get / Presets / Sets the RLMT OIDs .
*
* Returns :
* SK_PNMI_ERR_OK The request was successfully performed .
* SK_PNMI_ERR_GENERAL A general severe internal error occured .
* SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
* the correct data ( e . g . a 32 bit value is
* needed , but a 16 bit value was passed ) .
* SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
* value range .
* SK_PNMI_ERR_READ_ONLY The OID is read - only and cannot be set .
* SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn ' t
* exist ( e . g . port instance 3 on a two port
* adapter .
*/
PNMI_STATIC int Rlmt (
SK_AC * pAC , /* Pointer to adapter context */
SK_IOC IoC , /* IO context handle */
int Action , /* GET/PRESET/SET action */
SK_U32 Id , /* Object ID that is to be processed */
char * pBuf , /* Buffer used for the management data transfer */
unsigned int * pLen , /* On call: pBuf 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 always zero */
{
int Ret ;
unsigned int PhysPortIndex ;
unsigned int PhysPortMax ;
SK_EVPARA EventParam ;
SK_U32 Val32 ;
SK_U64 Val64 ;
/*
* Check instance . Only single instance OIDs are allowed here .
*/
if ( Instance ! = ( SK_U32 ) ( - 1 ) & & Instance ! = 1 ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_UNKNOWN_INST ) ;
}
/*
* Perform the requested action .
*/
if ( Action = = SK_PNMI_GET ) {
/*
* Check if the buffer length is large enough .
*/
switch ( Id ) {
case OID_SKGE_RLMT_MODE :
case OID_SKGE_RLMT_PORT_ACTIVE :
case OID_SKGE_RLMT_PORT_PREFERRED :
if ( * pLen < sizeof ( SK_U8 ) ) {
* pLen = sizeof ( SK_U8 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
break ;
case OID_SKGE_RLMT_PORT_NUMBER :
if ( * pLen < sizeof ( SK_U32 ) ) {
* pLen = sizeof ( SK_U32 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
break ;
case OID_SKGE_RLMT_CHANGE_CTS :
case OID_SKGE_RLMT_CHANGE_TIME :
case OID_SKGE_RLMT_CHANGE_ESTIM :
case OID_SKGE_RLMT_CHANGE_THRES :
if ( * pLen < sizeof ( SK_U64 ) ) {
* pLen = sizeof ( SK_U64 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
break ;
default :
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR035 ,
SK_PNMI_ERR035MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
/*
* Update RLMT statistic and increment semaphores to indicate
* that an update was already done . Maybe RLMT will hold its
* statistic always up to date some time . Then we can
* remove this type of call .
*/
if ( ( Ret = RlmtUpdate ( pAC , IoC , NetIndex ) ) ! = SK_PNMI_ERR_OK ) {
* pLen = 0 ;
return ( Ret ) ;
}
pAC - > Pnmi . RlmtUpdatedFlag + + ;
/*
* Retrieve Value
*/
switch ( Id ) {
case OID_SKGE_RLMT_MODE :
* pBuf = ( char ) pAC - > Rlmt . Net [ 0 ] . RlmtMode ;
* pLen = sizeof ( char ) ;
break ;
case OID_SKGE_RLMT_PORT_NUMBER :
Val32 = ( SK_U32 ) pAC - > GIni . GIMacsFound ;
SK_PNMI_STORE_U32 ( pBuf , Val32 ) ;
* pLen = sizeof ( SK_U32 ) ;
break ;
case OID_SKGE_RLMT_PORT_ACTIVE :
* pBuf = 0 ;
/*
* If multiple ports may become active this OID
* doesn ' t make sense any more . A new variable in
* the port structure should be created . However ,
* for this variable the first active port is
* returned .
*/
PhysPortMax = pAC - > GIni . GIMacsFound ;
for ( PhysPortIndex = 0 ; PhysPortIndex < PhysPortMax ;
PhysPortIndex + + ) {
if ( pAC - > Pnmi . Port [ PhysPortIndex ] . ActiveFlag ) {
* pBuf = ( char ) SK_PNMI_PORT_PHYS2LOG ( PhysPortIndex ) ;
break ;
}
}
* pLen = sizeof ( char ) ;
break ;
case OID_SKGE_RLMT_PORT_PREFERRED :
* pBuf = ( char ) SK_PNMI_PORT_PHYS2LOG ( pAC - > Rlmt . Net [ NetIndex ] . Preference ) ;
* pLen = sizeof ( char ) ;
break ;
case OID_SKGE_RLMT_CHANGE_CTS :
Val64 = pAC - > Pnmi . RlmtChangeCts ;
SK_PNMI_STORE_U64 ( pBuf , Val64 ) ;
* pLen = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_RLMT_CHANGE_TIME :
Val64 = pAC - > Pnmi . RlmtChangeTime ;
SK_PNMI_STORE_U64 ( pBuf , Val64 ) ;
* pLen = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_RLMT_CHANGE_ESTIM :
Val64 = pAC - > Pnmi . RlmtChangeEstimate . Estimate ;
SK_PNMI_STORE_U64 ( pBuf , Val64 ) ;
* pLen = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_RLMT_CHANGE_THRES :
Val64 = pAC - > Pnmi . RlmtChangeThreshold ;
SK_PNMI_STORE_U64 ( pBuf , Val64 ) ;
* pLen = sizeof ( SK_U64 ) ;
break ;
default :
SK_DBG_MSG ( pAC , SK_DBGMOD_PNMI , SK_DBGCAT_ERR ,
( " Rlmt: Unknown OID should be handled before " ) ) ;
pAC - > Pnmi . RlmtUpdatedFlag - - ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
pAC - > Pnmi . RlmtUpdatedFlag - - ;
}
else {
/* Perform a preset or set */
switch ( Id ) {
case OID_SKGE_RLMT_MODE :
/* Check if the buffer length is plausible */
if ( * pLen < sizeof ( char ) ) {
* pLen = sizeof ( char ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
/* Check if the value range is correct */
if ( * pLen ! = sizeof ( char ) | |
( * pBuf & SK_PNMI_RLMT_MODE_CHK_LINK ) = = 0 | |
* ( SK_U8 * ) pBuf > 15 ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_BAD_VALUE ) ;
}
/* The preset ends here */
if ( Action = = SK_PNMI_PRESET ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_OK ) ;
}
/* Send an event to RLMT to change the mode */
SK_MEMSET ( ( char * ) & EventParam , 0 , sizeof ( EventParam ) ) ;
EventParam . Para32 [ 0 ] | = ( SK_U32 ) ( * pBuf ) ;
EventParam . Para32 [ 1 ] = 0 ;
if ( SkRlmtEvent ( pAC , IoC , SK_RLMT_MODE_CHANGE ,
EventParam ) > 0 ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR037 ,
SK_PNMI_ERR037MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
break ;
case OID_SKGE_RLMT_PORT_PREFERRED :
/* Check if the buffer length is plausible */
if ( * pLen < sizeof ( char ) ) {
* pLen = sizeof ( char ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
/* Check if the value range is correct */
if ( * pLen ! = sizeof ( char ) | | * ( SK_U8 * ) pBuf >
( SK_U8 ) pAC - > GIni . GIMacsFound ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_BAD_VALUE ) ;
}
/* The preset ends here */
if ( Action = = SK_PNMI_PRESET ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_OK ) ;
}
/*
* Send an event to RLMT change the preferred port .
* A param of - 1 means automatic mode . RLMT will
* make the decision which is the preferred port .
*/
SK_MEMSET ( ( char * ) & EventParam , 0 , sizeof ( EventParam ) ) ;
EventParam . Para32 [ 0 ] = ( SK_U32 ) ( * pBuf ) - 1 ;
EventParam . Para32 [ 1 ] = NetIndex ;
if ( SkRlmtEvent ( pAC , IoC , SK_RLMT_PREFPORT_CHANGE ,
EventParam ) > 0 ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR038 ,
SK_PNMI_ERR038MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
break ;
case OID_SKGE_RLMT_CHANGE_THRES :
/* Check if the buffer length is plausible */
if ( * pLen < sizeof ( SK_U64 ) ) {
* pLen = sizeof ( SK_U64 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
/*
* There are not many restrictions to the
* value range .
*/
if ( * pLen ! = sizeof ( SK_U64 ) ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_BAD_VALUE ) ;
}
/* A preset ends here */
if ( Action = = SK_PNMI_PRESET ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_OK ) ;
}
/*
* Store the new threshold , which will be taken
* on the next timer event .
*/
SK_PNMI_READ_U64 ( pBuf , Val64 ) ;
pAC - > Pnmi . RlmtChangeThreshold = Val64 ;
break ;
default :
/* The other OIDs are not be able for set */
* pLen = 0 ;
return ( SK_PNMI_ERR_READ_ONLY ) ;
}
}
return ( SK_PNMI_ERR_OK ) ;
}
/*****************************************************************************
*
* RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance .
*
* Description :
* Performs get requests on multiple instance variables .
*
* Returns :
* SK_PNMI_ERR_OK The request was successfully performed .
* SK_PNMI_ERR_GENERAL A general severe internal error occured .
* SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
* the correct data ( e . g . a 32 bit value is
* needed , but a 16 bit value was passed ) .
* SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn ' t
* exist ( e . g . port instance 3 on a two port
* adapter .
*/
PNMI_STATIC int RlmtStat (
SK_AC * pAC , /* Pointer to adapter context */
SK_IOC IoC , /* IO context handle */
int Action , /* GET/PRESET/SET action */
SK_U32 Id , /* Object ID that is to be processed */
char * pBuf , /* Buffer used for the management data transfer */
unsigned int * pLen , /* On call: pBuf 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 always zero */
{
unsigned int PhysPortMax ;
unsigned int PhysPortIndex ;
unsigned int Limit ;
unsigned int Offset ;
int Ret ;
SK_U32 Val32 ;
SK_U64 Val64 ;
/*
* Calculate the port indexes from the instance .
*/
PhysPortMax = pAC - > GIni . GIMacsFound ;
if ( ( Instance ! = ( SK_U32 ) ( - 1 ) ) ) {
/* Check instance range */
if ( ( Instance < 1 ) | | ( Instance > PhysPortMax ) ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_UNKNOWN_INST ) ;
}
/* Single net mode */
PhysPortIndex = Instance - 1 ;
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
PhysPortIndex = NetIndex ;
}
/* Both net modes */
Limit = PhysPortIndex + 1 ;
}
else {
/* Single net mode */
PhysPortIndex = 0 ;
Limit = PhysPortMax ;
/* Dual net mode */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
PhysPortIndex = NetIndex ;
Limit = PhysPortIndex + 1 ;
}
}
/*
* Currently only get requests are allowed .
*/
if ( Action ! = SK_PNMI_GET ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_READ_ONLY ) ;
}
/*
* Check if the buffer length is large enough .
*/
switch ( Id ) {
case OID_SKGE_RLMT_PORT_INDEX :
case OID_SKGE_RLMT_STATUS :
if ( * pLen < ( Limit - PhysPortIndex ) * sizeof ( SK_U32 ) ) {
* pLen = ( Limit - PhysPortIndex ) * sizeof ( SK_U32 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
break ;
case OID_SKGE_RLMT_TX_HELLO_CTS :
case OID_SKGE_RLMT_RX_HELLO_CTS :
case OID_SKGE_RLMT_TX_SP_REQ_CTS :
case OID_SKGE_RLMT_RX_SP_CTS :
if ( * pLen < ( Limit - PhysPortIndex ) * sizeof ( SK_U64 ) ) {
* pLen = ( Limit - PhysPortIndex ) * sizeof ( SK_U64 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
break ;
default :
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR039 ,
SK_PNMI_ERR039MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
/*
* Update statistic and increment semaphores to indicate that
* an update was already done .
*/
if ( ( Ret = RlmtUpdate ( pAC , IoC , NetIndex ) ) ! = SK_PNMI_ERR_OK ) {
* pLen = 0 ;
return ( Ret ) ;
}
pAC - > Pnmi . RlmtUpdatedFlag + + ;
/*
* Get value
*/
Offset = 0 ;
for ( ; PhysPortIndex < Limit ; PhysPortIndex + + ) {
switch ( Id ) {
case OID_SKGE_RLMT_PORT_INDEX :
Val32 = PhysPortIndex ;
SK_PNMI_STORE_U32 ( pBuf + Offset , Val32 ) ;
Offset + = sizeof ( SK_U32 ) ;
break ;
case OID_SKGE_RLMT_STATUS :
if ( pAC - > Rlmt . Port [ PhysPortIndex ] . PortState = =
SK_RLMT_PS_INIT | |
pAC - > Rlmt . Port [ PhysPortIndex ] . PortState = =
SK_RLMT_PS_DOWN ) {
Val32 = SK_PNMI_RLMT_STATUS_ERROR ;
}
else if ( pAC - > Pnmi . Port [ PhysPortIndex ] . ActiveFlag ) {
Val32 = SK_PNMI_RLMT_STATUS_ACTIVE ;
}
else {
Val32 = SK_PNMI_RLMT_STATUS_STANDBY ;
}
SK_PNMI_STORE_U32 ( pBuf + Offset , Val32 ) ;
Offset + = sizeof ( SK_U32 ) ;
break ;
case OID_SKGE_RLMT_TX_HELLO_CTS :
Val64 = pAC - > Rlmt . Port [ PhysPortIndex ] . TxHelloCts ;
SK_PNMI_STORE_U64 ( pBuf + Offset , Val64 ) ;
Offset + = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_RLMT_RX_HELLO_CTS :
Val64 = pAC - > Rlmt . Port [ PhysPortIndex ] . RxHelloCts ;
SK_PNMI_STORE_U64 ( pBuf + Offset , Val64 ) ;
Offset + = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_RLMT_TX_SP_REQ_CTS :
Val64 = pAC - > Rlmt . Port [ PhysPortIndex ] . TxSpHelloReqCts ;
SK_PNMI_STORE_U64 ( pBuf + Offset , Val64 ) ;
Offset + = sizeof ( SK_U64 ) ;
break ;
case OID_SKGE_RLMT_RX_SP_CTS :
Val64 = pAC - > Rlmt . Port [ PhysPortIndex ] . RxSpHelloCts ;
SK_PNMI_STORE_U64 ( pBuf + Offset , Val64 ) ;
Offset + = sizeof ( SK_U64 ) ;
break ;
default :
SK_DBG_MSG ( pAC , SK_DBGMOD_PNMI , SK_DBGCAT_ERR ,
( " RlmtStat: Unknown OID should be errored before " ) ) ;
pAC - > Pnmi . RlmtUpdatedFlag - - ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
}
* pLen = Offset ;
pAC - > Pnmi . RlmtUpdatedFlag - - ;
return ( SK_PNMI_ERR_OK ) ;
}
/*****************************************************************************
*
* MacPrivateConf - OID handler function of OIDs concerning the configuration
*
* Description :
* Get / Presets / Sets the OIDs concerning the configuration .
*
* Returns :
* SK_PNMI_ERR_OK The request was successfully performed .
* SK_PNMI_ERR_GENERAL A general severe internal error occured .
* SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
* the correct data ( e . g . a 32 bit value is
* needed , but a 16 bit value was passed ) .
* SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
* value range .
* SK_PNMI_ERR_READ_ONLY The OID is read - only and cannot be set .
* SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn ' t
* exist ( e . g . port instance 3 on a two port
* adapter .
*/
PNMI_STATIC int MacPrivateConf (
SK_AC * pAC , /* Pointer to adapter context */
SK_IOC IoC , /* IO context handle */
int Action , /* GET/PRESET/SET action */
SK_U32 Id , /* Object ID that is to be processed */
char * pBuf , /* Buffer used for the management data transfer */
unsigned int * pLen , /* On call: pBuf 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 always zero */
{
unsigned int PhysPortMax ;
unsigned int PhysPortIndex ;
unsigned int LogPortMax ;
unsigned int LogPortIndex ;
unsigned int Limit ;
unsigned int Offset ;
char Val8 ;
char * pBufPtr ;
int Ret ;
SK_EVPARA EventParam ;
SK_U32 Val32 ;
/*
* Calculate instance if wished . MAC index 0 is the virtual MAC .
*/
PhysPortMax = pAC - > GIni . GIMacsFound ;
LogPortMax = SK_PNMI_PORT_PHYS2LOG ( PhysPortMax ) ;
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) { /* Dual net mode */
LogPortMax - - ;
}
if ( ( Instance ! = ( SK_U32 ) ( - 1 ) ) ) { /* Only one specific instance is queried */
/* Check instance range */
if ( ( Instance < 1 ) | | ( Instance > LogPortMax ) ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_UNKNOWN_INST ) ;
}
LogPortIndex = SK_PNMI_PORT_INST2LOG ( Instance ) ;
Limit = LogPortIndex + 1 ;
}
else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
LogPortIndex = 0 ;
Limit = LogPortMax ;
}
/*
* Perform action
*/
if ( Action = = SK_PNMI_GET ) {
/* Check length */
switch ( Id ) {
case OID_SKGE_PMD :
case OID_SKGE_CONNECTOR :
case OID_SKGE_LINK_CAP :
case OID_SKGE_LINK_MODE :
case OID_SKGE_LINK_MODE_STATUS :
case OID_SKGE_LINK_STATUS :
case OID_SKGE_FLOWCTRL_CAP :
case OID_SKGE_FLOWCTRL_MODE :
case OID_SKGE_FLOWCTRL_STATUS :
case OID_SKGE_PHY_OPERATION_CAP :
case OID_SKGE_PHY_OPERATION_MODE :
case OID_SKGE_PHY_OPERATION_STATUS :
case OID_SKGE_SPEED_CAP :
case OID_SKGE_SPEED_MODE :
case OID_SKGE_SPEED_STATUS :
if ( * pLen < ( Limit - LogPortIndex ) * sizeof ( SK_U8 ) ) {
* pLen = ( Limit - LogPortIndex ) * sizeof ( SK_U8 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
break ;
case OID_SKGE_MTU :
case OID_SKGE_PHY_TYPE :
if ( * pLen < ( Limit - LogPortIndex ) * sizeof ( SK_U32 ) ) {
* pLen = ( Limit - LogPortIndex ) * sizeof ( SK_U32 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
break ;
default :
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR041 ,
SK_PNMI_ERR041MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
/*
* Update statistic and increment semaphore to indicate
* that an update was already done .
*/
if ( ( Ret = SirqUpdate ( pAC , IoC ) ) ! = SK_PNMI_ERR_OK ) {
* pLen = 0 ;
return ( Ret ) ;
}
pAC - > Pnmi . SirqUpdatedFlag + + ;
/*
* Get value
*/
Offset = 0 ;
for ( ; LogPortIndex < Limit ; LogPortIndex + + ) {
pBufPtr = pBuf + Offset ;
switch ( Id ) {
case OID_SKGE_PMD :
* pBufPtr = pAC - > Pnmi . PMD ;
Offset + = sizeof ( char ) ;
break ;
case OID_SKGE_CONNECTOR :
* pBufPtr = pAC - > Pnmi . Connector ;
Offset + = sizeof ( char ) ;
break ;
case OID_SKGE_PHY_TYPE :
if ( ! pAC - > Pnmi . DualNetActiveFlag ) { /* SingleNetMode */
if ( LogPortIndex = = 0 ) {
continue ;
}
else {
/* Get value for physical ports */
PhysPortIndex = SK_PNMI_PORT_LOG2PHYS (
pAC , LogPortIndex ) ;
Val32 = pAC - > GIni . GP [ PhysPortIndex ] . PhyType ;
SK_PNMI_STORE_U32 ( pBufPtr , Val32 ) ;
}
}
else { /* DualNetMode */
Val32 = pAC - > GIni . GP [ NetIndex ] . PhyType ;
SK_PNMI_STORE_U32 ( pBufPtr , Val32 ) ;
}
Offset + = sizeof ( SK_U32 ) ;
break ;
case OID_SKGE_LINK_CAP :
if ( ! pAC - > Pnmi . DualNetActiveFlag ) { /* SingleNetMode */
if ( LogPortIndex = = 0 ) {
/* Get value for virtual port */
VirtualConf ( pAC , IoC , Id , pBufPtr ) ;
}
else {
/* Get value for physical ports */
PhysPortIndex = SK_PNMI_PORT_LOG2PHYS (
pAC , LogPortIndex ) ;
* pBufPtr = pAC - > GIni . GP [ PhysPortIndex ] . PLinkCap ;
}
}
else { /* DualNetMode */
* pBufPtr = pAC - > GIni . GP [ NetIndex ] . PLinkCap ;
}
Offset + = sizeof ( char ) ;
break ;
case OID_SKGE_LINK_MODE :
if ( ! pAC - > Pnmi . DualNetActiveFlag ) { /* SingleNetMode */
if ( LogPortIndex = = 0 ) {
/* Get value for virtual port */
VirtualConf ( pAC , IoC , Id , pBufPtr ) ;
}
else {
/* Get value for physical ports */
PhysPortIndex = SK_PNMI_PORT_LOG2PHYS (
pAC , LogPortIndex ) ;
* pBufPtr = pAC - > GIni . GP [ PhysPortIndex ] . PLinkModeConf ;
}
}
else { /* DualNetMode */
* pBufPtr = pAC - > GIni . GP [ NetIndex ] . PLinkModeConf ;
}
Offset + = sizeof ( char ) ;
break ;
case OID_SKGE_LINK_MODE_STATUS :
if ( ! pAC - > Pnmi . DualNetActiveFlag ) { /* SingleNetMode */
if ( LogPortIndex = = 0 ) {
/* Get value for virtual port */
VirtualConf ( pAC , IoC , Id , pBufPtr ) ;
}
else {
/* Get value for physical port */
PhysPortIndex = SK_PNMI_PORT_LOG2PHYS (
pAC , LogPortIndex ) ;
* pBufPtr =
CalculateLinkModeStatus ( pAC , IoC , PhysPortIndex ) ;
}
}
else { /* DualNetMode */
* pBufPtr = CalculateLinkModeStatus ( pAC , IoC , NetIndex ) ;
}
Offset + = sizeof ( char ) ;
break ;
case OID_SKGE_LINK_STATUS :
if ( ! pAC - > Pnmi . DualNetActiveFlag ) { /* SingleNetMode */
if ( LogPortIndex = = 0 ) {
/* Get value for virtual port */
VirtualConf ( pAC , IoC , Id , pBufPtr ) ;
}
else {
/* Get value for physical ports */
PhysPortIndex = SK_PNMI_PORT_LOG2PHYS (
pAC , LogPortIndex ) ;
* pBufPtr = CalculateLinkStatus ( pAC , IoC , PhysPortIndex ) ;
}
}
else { /* DualNetMode */
* pBufPtr = CalculateLinkStatus ( pAC , IoC , NetIndex ) ;
}
Offset + = sizeof ( char ) ;
break ;
case OID_SKGE_FLOWCTRL_CAP :
if ( ! pAC - > Pnmi . DualNetActiveFlag ) { /* SingleNetMode */
if ( LogPortIndex = = 0 ) {
/* Get value for virtual port */
VirtualConf ( pAC , IoC , Id , pBufPtr ) ;
}
else {
/* Get value for physical ports */
PhysPortIndex = SK_PNMI_PORT_LOG2PHYS (
pAC , LogPortIndex ) ;
* pBufPtr = pAC - > GIni . GP [ PhysPortIndex ] . PFlowCtrlCap ;
}
}
else { /* DualNetMode */
* pBufPtr = pAC - > GIni . GP [ NetIndex ] . PFlowCtrlCap ;
}
Offset + = sizeof ( char ) ;
break ;
case OID_SKGE_FLOWCTRL_MODE :
if ( ! pAC - > Pnmi . DualNetActiveFlag ) { /* SingleNetMode */
if ( LogPortIndex = = 0 ) {
/* Get value for virtual port */
VirtualConf ( pAC , IoC , Id , pBufPtr ) ;
}
else {
/* Get value for physical port */
PhysPortIndex = SK_PNMI_PORT_LOG2PHYS (
pAC , LogPortIndex ) ;
* pBufPtr = pAC - > GIni . GP [ PhysPortIndex ] . PFlowCtrlMode ;
}
}
else { /* DualNetMode */
* pBufPtr = pAC - > GIni . GP [ NetIndex ] . PFlowCtrlMode ;
}
Offset + = sizeof ( char ) ;
break ;
case OID_SKGE_FLOWCTRL_STATUS :
if ( ! pAC - > Pnmi . DualNetActiveFlag ) { /* SingleNetMode */
if ( LogPortIndex = = 0 ) {
/* Get value for virtual port */
VirtualConf ( pAC , IoC , Id , pBufPtr ) ;
}
else {
/* Get value for physical port */
PhysPortIndex = SK_PNMI_PORT_LOG2PHYS (
pAC , LogPortIndex ) ;
* pBufPtr = pAC - > GIni . GP [ PhysPortIndex ] . PFlowCtrlStatus ;
}
}
else { /* DualNetMode */
* pBufPtr = pAC - > GIni . GP [ NetIndex ] . PFlowCtrlStatus ;
}
Offset + = sizeof ( char ) ;
break ;
case OID_SKGE_PHY_OPERATION_CAP :
if ( ! pAC - > Pnmi . DualNetActiveFlag ) { /* SingleNetMode */
if ( LogPortIndex = = 0 ) {
/* Get value for virtual port */
VirtualConf ( pAC , IoC , Id , pBufPtr ) ;
}
else {
/* Get value for physical ports */
PhysPortIndex = SK_PNMI_PORT_LOG2PHYS (
pAC , LogPortIndex ) ;
* pBufPtr = pAC - > GIni . GP [ PhysPortIndex ] . PMSCap ;
}
}
else { /* DualNetMode */
* pBufPtr = pAC - > GIni . GP [ NetIndex ] . PMSCap ;
}
Offset + = sizeof ( char ) ;
break ;
case OID_SKGE_PHY_OPERATION_MODE :
if ( ! pAC - > Pnmi . DualNetActiveFlag ) { /* SingleNetMode */
if ( LogPortIndex = = 0 ) {
/* Get value for virtual port */
VirtualConf ( pAC , IoC , Id , pBufPtr ) ;
}
else {
/* Get value for physical port */
PhysPortIndex = SK_PNMI_PORT_LOG2PHYS (
pAC , LogPortIndex ) ;
* pBufPtr = pAC - > GIni . GP [ PhysPortIndex ] . PMSMode ;
}
}
else { /* DualNetMode */
* pBufPtr = pAC - > GIni . GP [ NetIndex ] . PMSMode ;
}
Offset + = sizeof ( char ) ;
break ;
case OID_SKGE_PHY_OPERATION_STATUS :
if ( ! pAC - > Pnmi . DualNetActiveFlag ) { /* SingleNetMode */
if ( LogPortIndex = = 0 ) {
/* Get value for virtual port */
VirtualConf ( pAC , IoC , Id , pBufPtr ) ;
}
else {
/* Get value for physical port */
PhysPortIndex = SK_PNMI_PORT_LOG2PHYS (
pAC , LogPortIndex ) ;
* pBufPtr = pAC - > GIni . GP [ PhysPortIndex ] . PMSStatus ;
}
}
else {
* pBufPtr = pAC - > GIni . GP [ NetIndex ] . PMSStatus ;
}
Offset + = sizeof ( char ) ;
break ;
case OID_SKGE_SPEED_CAP :
if ( ! pAC - > Pnmi . DualNetActiveFlag ) { /* SingleNetMode */
if ( LogPortIndex = = 0 ) {
/* Get value for virtual port */
VirtualConf ( pAC , IoC , Id , pBufPtr ) ;
}
else {
/* Get value for physical ports */
PhysPortIndex = SK_PNMI_PORT_LOG2PHYS (
pAC , LogPortIndex ) ;
* pBufPtr = pAC - > GIni . GP [ PhysPortIndex ] . PLinkSpeedCap ;
}
}
else { /* DualNetMode */
* pBufPtr = pAC - > GIni . GP [ NetIndex ] . PLinkSpeedCap ;
}
Offset + = sizeof ( char ) ;
break ;
case OID_SKGE_SPEED_MODE :
if ( ! pAC - > Pnmi . DualNetActiveFlag ) { /* SingleNetMode */
if ( LogPortIndex = = 0 ) {
/* Get value for virtual port */
VirtualConf ( pAC , IoC , Id , pBufPtr ) ;
}
else {
/* Get value for physical port */
PhysPortIndex = SK_PNMI_PORT_LOG2PHYS (
pAC , LogPortIndex ) ;
* pBufPtr = pAC - > GIni . GP [ PhysPortIndex ] . PLinkSpeed ;
}
}
else { /* DualNetMode */
* pBufPtr = pAC - > GIni . GP [ NetIndex ] . PLinkSpeed ;
}
Offset + = sizeof ( char ) ;
break ;
case OID_SKGE_SPEED_STATUS :
if ( ! pAC - > Pnmi . DualNetActiveFlag ) { /* SingleNetMode */
if ( LogPortIndex = = 0 ) {
/* Get value for virtual port */
VirtualConf ( pAC , IoC , Id , pBufPtr ) ;
}
else {
/* Get value for physical port */
PhysPortIndex = SK_PNMI_PORT_LOG2PHYS (
pAC , LogPortIndex ) ;
* pBufPtr = pAC - > GIni . GP [ PhysPortIndex ] . PLinkSpeedUsed ;
}
}
else { /* DualNetMode */
* pBufPtr = pAC - > GIni . GP [ NetIndex ] . PLinkSpeedUsed ;
}
Offset + = sizeof ( char ) ;
break ;
case OID_SKGE_MTU :
Val32 = SK_DRIVER_GET_MTU ( pAC , IoC , NetIndex ) ;
SK_PNMI_STORE_U32 ( pBufPtr , Val32 ) ;
Offset + = sizeof ( SK_U32 ) ;
break ;
default :
SK_DBG_MSG ( pAC , SK_DBGMOD_PNMI , SK_DBGCAT_ERR ,
( " MacPrivateConf: Unknown OID should be handled before " ) ) ;
pAC - > Pnmi . SirqUpdatedFlag - - ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
}
* pLen = Offset ;
pAC - > Pnmi . SirqUpdatedFlag - - ;
return ( SK_PNMI_ERR_OK ) ;
}
/*
* From here SET or PRESET action . Check if the passed
* buffer length is plausible .
*/
switch ( Id ) {
case OID_SKGE_LINK_MODE :
case OID_SKGE_FLOWCTRL_MODE :
case OID_SKGE_PHY_OPERATION_MODE :
case OID_SKGE_SPEED_MODE :
if ( * pLen < Limit - LogPortIndex ) {
* pLen = Limit - LogPortIndex ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
if ( * pLen ! = Limit - LogPortIndex ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_BAD_VALUE ) ;
}
break ;
case OID_SKGE_MTU :
if ( * pLen < sizeof ( SK_U32 ) ) {
* pLen = sizeof ( SK_U32 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
if ( * pLen ! = sizeof ( SK_U32 ) ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_BAD_VALUE ) ;
}
break ;
default :
* pLen = 0 ;
return ( SK_PNMI_ERR_READ_ONLY ) ;
}
/*
* Perform preset or set
*/
Offset = 0 ;
for ( ; LogPortIndex < Limit ; LogPortIndex + + ) {
switch ( Id ) {
case OID_SKGE_LINK_MODE :
/* Check the value range */
Val8 = * ( pBuf + Offset ) ;
if ( Val8 = = 0 ) {
Offset + = sizeof ( char ) ;
break ;
}
if ( Val8 < SK_LMODE_HALF | |
( LogPortIndex ! = 0 & & Val8 > SK_LMODE_AUTOSENSE ) | |
( LogPortIndex = = 0 & & Val8 > SK_LMODE_INDETERMINATED ) ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_BAD_VALUE ) ;
}
/* The preset ends here */
if ( Action = = SK_PNMI_PRESET ) {
return ( SK_PNMI_ERR_OK ) ;
}
if ( LogPortIndex = = 0 ) {
/*
* The virtual port consists of all currently
* active ports . Find them and send an event
* with the new link mode to SIRQ .
*/
for ( PhysPortIndex = 0 ;
PhysPortIndex < PhysPortMax ;
PhysPortIndex + + ) {
if ( ! pAC - > Pnmi . Port [ PhysPortIndex ] .
ActiveFlag ) {
continue ;
}
EventParam . Para32 [ 0 ] = PhysPortIndex ;
EventParam . Para32 [ 1 ] = ( SK_U32 ) Val8 ;
if ( SkGeSirqEvent ( pAC , IoC ,
SK_HWEV_SET_LMODE ,
EventParam ) > 0 ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW ,
SK_PNMI_ERR043 ,
SK_PNMI_ERR043MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
}
}
else {
/*
* Send an event with the new link mode to
* the SIRQ module .
*/
EventParam . Para32 [ 0 ] = SK_PNMI_PORT_LOG2PHYS (
pAC , LogPortIndex ) ;
EventParam . Para32 [ 1 ] = ( SK_U32 ) Val8 ;
if ( SkGeSirqEvent ( pAC , IoC , SK_HWEV_SET_LMODE ,
EventParam ) > 0 ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW ,
SK_PNMI_ERR043 ,
SK_PNMI_ERR043MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
}
Offset + = sizeof ( char ) ;
break ;
case OID_SKGE_FLOWCTRL_MODE :
/* Check the value range */
Val8 = * ( pBuf + Offset ) ;
if ( Val8 = = 0 ) {
Offset + = sizeof ( char ) ;
break ;
}
if ( Val8 < SK_FLOW_MODE_NONE | |
( LogPortIndex ! = 0 & & Val8 > SK_FLOW_MODE_SYM_OR_REM ) | |
( LogPortIndex = = 0 & & Val8 > SK_FLOW_MODE_INDETERMINATED ) ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_BAD_VALUE ) ;
}
/* The preset ends here */
if ( Action = = SK_PNMI_PRESET ) {
return ( SK_PNMI_ERR_OK ) ;
}
if ( LogPortIndex = = 0 ) {
/*
* The virtual port consists of all currently
* active ports . Find them and send an event
* with the new flow control mode to SIRQ .
*/
for ( PhysPortIndex = 0 ;
PhysPortIndex < PhysPortMax ;
PhysPortIndex + + ) {
if ( ! pAC - > Pnmi . Port [ PhysPortIndex ] .
ActiveFlag ) {
continue ;
}
EventParam . Para32 [ 0 ] = PhysPortIndex ;
EventParam . Para32 [ 1 ] = ( SK_U32 ) Val8 ;
if ( SkGeSirqEvent ( pAC , IoC ,
SK_HWEV_SET_FLOWMODE ,
EventParam ) > 0 ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW ,
SK_PNMI_ERR044 ,
SK_PNMI_ERR044MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
}
}
else {
/*
* Send an event with the new flow control
* mode to the SIRQ module .
*/
EventParam . Para32 [ 0 ] = SK_PNMI_PORT_LOG2PHYS (
pAC , LogPortIndex ) ;
EventParam . Para32 [ 1 ] = ( SK_U32 ) Val8 ;
if ( SkGeSirqEvent ( pAC , IoC ,
SK_HWEV_SET_FLOWMODE , EventParam )
> 0 ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW ,
SK_PNMI_ERR044 ,
SK_PNMI_ERR044MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
}
Offset + = sizeof ( char ) ;
break ;
case OID_SKGE_PHY_OPERATION_MODE :
/* Check the value range */
Val8 = * ( pBuf + Offset ) ;
if ( Val8 = = 0 ) {
/* mode of this port remains unchanged */
Offset + = sizeof ( char ) ;
break ;
}
if ( Val8 < SK_MS_MODE_AUTO | |
( LogPortIndex ! = 0 & & Val8 > SK_MS_MODE_SLAVE ) | |
( LogPortIndex = = 0 & & Val8 > SK_MS_MODE_INDETERMINATED ) ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_BAD_VALUE ) ;
}
/* The preset ends here */
if ( Action = = SK_PNMI_PRESET ) {
return ( SK_PNMI_ERR_OK ) ;
}
if ( LogPortIndex = = 0 ) {
/*
* The virtual port consists of all currently
* active ports . Find them and send an event
* with new master / slave ( role ) mode to SIRQ .
*/
for ( PhysPortIndex = 0 ;
PhysPortIndex < PhysPortMax ;
PhysPortIndex + + ) {
if ( ! pAC - > Pnmi . Port [ PhysPortIndex ] .
ActiveFlag ) {
continue ;
}
EventParam . Para32 [ 0 ] = PhysPortIndex ;
EventParam . Para32 [ 1 ] = ( SK_U32 ) Val8 ;
if ( SkGeSirqEvent ( pAC , IoC ,
SK_HWEV_SET_ROLE ,
EventParam ) > 0 ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW ,
SK_PNMI_ERR042 ,
SK_PNMI_ERR042MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
}
}
else {
/*
* Send an event with the new master / slave
* ( role ) mode to the SIRQ module .
*/
EventParam . Para32 [ 0 ] = SK_PNMI_PORT_LOG2PHYS (
pAC , LogPortIndex ) ;
EventParam . Para32 [ 1 ] = ( SK_U32 ) Val8 ;
if ( SkGeSirqEvent ( pAC , IoC ,
SK_HWEV_SET_ROLE , EventParam ) > 0 ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW ,
SK_PNMI_ERR042 ,
SK_PNMI_ERR042MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
}
Offset + = sizeof ( char ) ;
break ;
case OID_SKGE_SPEED_MODE :
/* Check the value range */
Val8 = * ( pBuf + Offset ) ;
if ( Val8 = = 0 ) {
Offset + = sizeof ( char ) ;
break ;
}
if ( Val8 < ( SK_LSPEED_AUTO ) | |
( LogPortIndex ! = 0 & & Val8 > ( SK_LSPEED_1000MBPS ) ) | |
( LogPortIndex = = 0 & & Val8 > ( SK_LSPEED_INDETERMINATED ) ) ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_BAD_VALUE ) ;
}
/* The preset ends here */
if ( Action = = SK_PNMI_PRESET ) {
return ( SK_PNMI_ERR_OK ) ;
}
if ( LogPortIndex = = 0 ) {
/*
* The virtual port consists of all currently
* active ports . Find them and send an event
* with the new flow control mode to SIRQ .
*/
for ( PhysPortIndex = 0 ;
PhysPortIndex < PhysPortMax ;
PhysPortIndex + + ) {
if ( ! pAC - > Pnmi . Port [ PhysPortIndex ] . ActiveFlag ) {
continue ;
}
EventParam . Para32 [ 0 ] = PhysPortIndex ;
EventParam . Para32 [ 1 ] = ( SK_U32 ) Val8 ;
if ( SkGeSirqEvent ( pAC , IoC ,
SK_HWEV_SET_SPEED ,
EventParam ) > 0 ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW ,
SK_PNMI_ERR045 ,
SK_PNMI_ERR045MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
}
}
else {
/*
* Send an event with the new flow control
* mode to the SIRQ module .
*/
EventParam . Para32 [ 0 ] = SK_PNMI_PORT_LOG2PHYS (
pAC , LogPortIndex ) ;
EventParam . Para32 [ 1 ] = ( SK_U32 ) Val8 ;
if ( SkGeSirqEvent ( pAC , IoC ,
SK_HWEV_SET_SPEED ,
EventParam ) > 0 ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW ,
SK_PNMI_ERR045 ,
SK_PNMI_ERR045MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
}
Offset + = sizeof ( char ) ;
break ;
case OID_SKGE_MTU :
/* Check the value range */
Val32 = * ( SK_U32 * ) ( pBuf + Offset ) ;
if ( Val32 = = 0 ) {
/* mtu of this port remains unchanged */
Offset + = sizeof ( SK_U32 ) ;
break ;
}
if ( SK_DRIVER_PRESET_MTU ( pAC , IoC , NetIndex , Val32 ) ! = 0 ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_BAD_VALUE ) ;
}
/* The preset ends here */
if ( Action = = SK_PNMI_PRESET ) {
return ( SK_PNMI_ERR_OK ) ;
}
if ( SK_DRIVER_SET_MTU ( pAC , IoC , NetIndex , Val32 ) ! = 0 ) {
return ( SK_PNMI_ERR_GENERAL ) ;
}
Offset + = sizeof ( SK_U32 ) ;
break ;
default :
SK_DBG_MSG ( pAC , SK_DBGMOD_PNMI , SK_DBGCAT_ERR ,
( " MacPrivateConf: Unknown OID should be handled before set " ) ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
}
return ( SK_PNMI_ERR_OK ) ;
}
/*****************************************************************************
*
* Monitor - OID handler function for RLMT_MONITOR_XXX
*
* Description :
* Because RLMT currently does not support the monitoring of
* remote adapter cards , we return always an empty table .
*
* Returns :
* SK_PNMI_ERR_OK The request was successfully performed .
* SK_PNMI_ERR_GENERAL A general severe internal error occured .
* SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
* the correct data ( e . g . a 32 bit value is
* needed , but a 16 bit value was passed ) .
* SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
* value range .
* SK_PNMI_ERR_READ_ONLY The OID is read - only and cannot be set .
* SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn ' t
* exist ( e . g . port instance 3 on a two port
* adapter .
*/
PNMI_STATIC int Monitor (
SK_AC * pAC , /* Pointer to adapter context */
SK_IOC IoC , /* IO context handle */
int Action , /* GET/PRESET/SET action */
SK_U32 Id , /* Object ID that is to be processed */
char * pBuf , /* Buffer used for the management data transfer */
unsigned int * pLen , /* On call: pBuf 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 always zero */
{
unsigned int Index ;
unsigned int Limit ;
unsigned int Offset ;
unsigned int Entries ;
/*
* Calculate instance if wished .
*/
/* XXX Not yet implemented. Return always an empty table. */
Entries = 0 ;
if ( ( Instance ! = ( SK_U32 ) ( - 1 ) ) ) {
if ( ( Instance < 1 ) | | ( Instance > Entries ) ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_UNKNOWN_INST ) ;
}
Index = ( unsigned int ) Instance - 1 ;
Limit = ( unsigned int ) Instance ;
}
else {
Index = 0 ;
Limit = Entries ;
}
/*
* Get / Set value
*/
if ( Action = = SK_PNMI_GET ) {
for ( Offset = 0 ; Index < Limit ; Index + + ) {
switch ( Id ) {
case OID_SKGE_RLMT_MONITOR_INDEX :
case OID_SKGE_RLMT_MONITOR_ADDR :
case OID_SKGE_RLMT_MONITOR_ERRS :
case OID_SKGE_RLMT_MONITOR_TIMESTAMP :
case OID_SKGE_RLMT_MONITOR_ADMIN :
break ;
default :
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR046 ,
SK_PNMI_ERR046MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
}
* pLen = Offset ;
}
else {
/* Only MONITOR_ADMIN can be set */
if ( Id ! = OID_SKGE_RLMT_MONITOR_ADMIN ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_READ_ONLY ) ;
}
/* Check if the length is plausible */
if ( * pLen < ( Limit - Index ) ) {
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
/* Okay, we have a wide value range */
if ( * pLen ! = ( Limit - Index ) ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_BAD_VALUE ) ;
}
/*
for ( Offset = 0 ; Index < Limit ; Index + + ) {
}
*/
/*
* XXX Not yet implemented . Return always BAD_VALUE , because the table
* is empty .
*/
* pLen = 0 ;
return ( SK_PNMI_ERR_BAD_VALUE ) ;
}
return ( SK_PNMI_ERR_OK ) ;
}
/*****************************************************************************
*
* VirtualConf - Calculates the values of configuration OIDs for virtual port
*
* Description :
* We handle here the get of the configuration group OIDs , which are
* a little bit complicated . The virtual port consists of all currently
* active physical ports . If multiple ports are active and configured
* differently we get in some trouble to return a single value . So we
* get the value of the first active port and compare it with that of
* the other active ports . If they are not the same , we return a value
* that indicates that the state is indeterminated .
*
* Returns :
* Nothing
*/
PNMI_STATIC void VirtualConf (
SK_AC * pAC , /* Pointer to adapter context */
SK_IOC IoC , /* IO context handle */
SK_U32 Id , /* Object ID that is to be processed */
char * pBuf ) /* Buffer used for the management data transfer */
{
unsigned int PhysPortMax ;
unsigned int PhysPortIndex ;
SK_U8 Val8 ;
SK_U32 Val32 ;
SK_BOOL PortActiveFlag ;
SK_GEPORT * pPrt ;
* pBuf = 0 ;
PortActiveFlag = SK_FALSE ;
PhysPortMax = pAC - > GIni . GIMacsFound ;
for ( PhysPortIndex = 0 ; PhysPortIndex < PhysPortMax ;
PhysPortIndex + + ) {
pPrt = & pAC - > GIni . GP [ PhysPortIndex ] ;
/* Check if the physical port is active */
if ( ! pAC - > Pnmi . Port [ PhysPortIndex ] . ActiveFlag ) {
continue ;
}
PortActiveFlag = SK_TRUE ;
switch ( Id ) {
case OID_SKGE_PHY_TYPE :
/* Check if it is the first active port */
if ( * pBuf = = 0 ) {
Val32 = pPrt - > PhyType ;
SK_PNMI_STORE_U32 ( pBuf , Val32 ) ;
continue ;
}
case OID_SKGE_LINK_CAP :
/*
* Different capabilities should not happen , but
* in the case of the cases OR them all together .
* From a curious point of view the virtual port
* is capable of all found capabilities .
*/
* pBuf | = pPrt - > PLinkCap ;
break ;
case OID_SKGE_LINK_MODE :
/* Check if it is the first active port */
if ( * pBuf = = 0 ) {
* pBuf = pPrt - > PLinkModeConf ;
continue ;
}
/*
* If we find an active port with a different link
* mode than the first one we return a value that
* indicates that the link mode is indeterminated .
*/
if ( * pBuf ! = pPrt - > PLinkModeConf ) {
* pBuf = SK_LMODE_INDETERMINATED ;
}
break ;
case OID_SKGE_LINK_MODE_STATUS :
/* Get the link mode of the physical port */
Val8 = CalculateLinkModeStatus ( pAC , IoC , PhysPortIndex ) ;
/* Check if it is the first active port */
if ( * pBuf = = 0 ) {
* pBuf = Val8 ;
continue ;
}
/*
* If we find an active port with a different link
* mode status than the first one we return a value
* that indicates that the link mode status is
* indeterminated .
*/
if ( * pBuf ! = Val8 ) {
* pBuf = SK_LMODE_STAT_INDETERMINATED ;
}
break ;
case OID_SKGE_LINK_STATUS :
/* Get the link status of the physical port */
Val8 = CalculateLinkStatus ( pAC , IoC , PhysPortIndex ) ;
/* Check if it is the first active port */
if ( * pBuf = = 0 ) {
* pBuf = Val8 ;
continue ;
}
/*
* If we find an active port with a different link
* status than the first one , we return a value
* that indicates that the link status is
* indeterminated .
*/
if ( * pBuf ! = Val8 ) {
* pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED ;
}
break ;
case OID_SKGE_FLOWCTRL_CAP :
/* Check if it is the first active port */
if ( * pBuf = = 0 ) {
* pBuf = pPrt - > PFlowCtrlCap ;
continue ;
}
/*
* From a curious point of view the virtual port
* is capable of all found capabilities .
*/
* pBuf | = pPrt - > PFlowCtrlCap ;
break ;
case OID_SKGE_FLOWCTRL_MODE :
/* Check if it is the first active port */
if ( * pBuf = = 0 ) {
* pBuf = pPrt - > PFlowCtrlMode ;
continue ;
}
/*
* If we find an active port with a different flow
* control mode than the first one , we return a value
* that indicates that the mode is indeterminated .
*/
if ( * pBuf ! = pPrt - > PFlowCtrlMode ) {
* pBuf = SK_FLOW_MODE_INDETERMINATED ;
}
break ;
case OID_SKGE_FLOWCTRL_STATUS :
/* Check if it is the first active port */
if ( * pBuf = = 0 ) {
* pBuf = pPrt - > PFlowCtrlStatus ;
continue ;
}
/*
* If we find an active port with a different flow
* control status than the first one , we return a
* value that indicates that the status is
* indeterminated .
*/
if ( * pBuf ! = pPrt - > PFlowCtrlStatus ) {
* pBuf = SK_FLOW_STAT_INDETERMINATED ;
}
break ;
case OID_SKGE_PHY_OPERATION_CAP :
/* Check if it is the first active port */
if ( * pBuf = = 0 ) {
* pBuf = pPrt - > PMSCap ;
continue ;
}
/*
* From a curious point of view the virtual port
* is capable of all found capabilities .
*/
* pBuf | = pPrt - > PMSCap ;
break ;
case OID_SKGE_PHY_OPERATION_MODE :
/* Check if it is the first active port */
if ( * pBuf = = 0 ) {
* pBuf = pPrt - > PMSMode ;
continue ;
}
/*
* If we find an active port with a different master /
* slave mode than the first one , we return a value
* that indicates that the mode is indeterminated .
*/
if ( * pBuf ! = pPrt - > PMSMode ) {
* pBuf = SK_MS_MODE_INDETERMINATED ;
}
break ;
case OID_SKGE_PHY_OPERATION_STATUS :
/* Check if it is the first active port */
if ( * pBuf = = 0 ) {
* pBuf = pPrt - > PMSStatus ;
continue ;
}
/*
* If we find an active port with a different master /
* slave status than the first one , we return a
* value that indicates that the status is
* indeterminated .
*/
if ( * pBuf ! = pPrt - > PMSStatus ) {
* pBuf = SK_MS_STAT_INDETERMINATED ;
}
break ;
case OID_SKGE_SPEED_MODE :
/* Check if it is the first active port */
if ( * pBuf = = 0 ) {
* pBuf = pPrt - > PLinkSpeed ;
continue ;
}
/*
* If we find an active port with a different flow
* control mode than the first one , we return a value
* that indicates that the mode is indeterminated .
*/
if ( * pBuf ! = pPrt - > PLinkSpeed ) {
* pBuf = SK_LSPEED_INDETERMINATED ;
}
break ;
case OID_SKGE_SPEED_STATUS :
/* Check if it is the first active port */
if ( * pBuf = = 0 ) {
* pBuf = pPrt - > PLinkSpeedUsed ;
continue ;
}
/*
* If we find an active port with a different flow
* control status than the first one , we return a
* value that indicates that the status is
* indeterminated .
*/
if ( * pBuf ! = pPrt - > PLinkSpeedUsed ) {
* pBuf = SK_LSPEED_STAT_INDETERMINATED ;
}
break ;
}
}
/*
* If no port is active return an indeterminated answer
*/
if ( ! PortActiveFlag ) {
switch ( Id ) {
case OID_SKGE_LINK_CAP :
* pBuf = SK_LMODE_CAP_INDETERMINATED ;
break ;
case OID_SKGE_LINK_MODE :
* pBuf = SK_LMODE_INDETERMINATED ;
break ;
case OID_SKGE_LINK_MODE_STATUS :
* pBuf = SK_LMODE_STAT_INDETERMINATED ;
break ;
case OID_SKGE_LINK_STATUS :
* pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED ;
break ;
case OID_SKGE_FLOWCTRL_CAP :
case OID_SKGE_FLOWCTRL_MODE :
* pBuf = SK_FLOW_MODE_INDETERMINATED ;
break ;
case OID_SKGE_FLOWCTRL_STATUS :
* pBuf = SK_FLOW_STAT_INDETERMINATED ;
break ;
case OID_SKGE_PHY_OPERATION_CAP :
* pBuf = SK_MS_CAP_INDETERMINATED ;
break ;
case OID_SKGE_PHY_OPERATION_MODE :
* pBuf = SK_MS_MODE_INDETERMINATED ;
break ;
case OID_SKGE_PHY_OPERATION_STATUS :
* pBuf = SK_MS_STAT_INDETERMINATED ;
break ;
case OID_SKGE_SPEED_CAP :
* pBuf = SK_LSPEED_CAP_INDETERMINATED ;
break ;
case OID_SKGE_SPEED_MODE :
* pBuf = SK_LSPEED_INDETERMINATED ;
break ;
case OID_SKGE_SPEED_STATUS :
* pBuf = SK_LSPEED_STAT_INDETERMINATED ;
break ;
}
}
}
/*****************************************************************************
*
* CalculateLinkStatus - Determins the link status of a physical port
*
* Description :
* Determins the link status the following way :
* LSTAT_PHY_DOWN : Link is down
* LSTAT_AUTONEG : Auto - negotiation failed
* LSTAT_LOG_DOWN : Link is up but RLMT did not yet put the port
* logically up .
* LSTAT_LOG_UP : RLMT marked the port as up
*
* Returns :
* Link status of physical port
*/
PNMI_STATIC SK_U8 CalculateLinkStatus (
SK_AC * pAC , /* Pointer to adapter context */
SK_IOC IoC , /* IO context handle */
unsigned int PhysPortIndex ) /* Physical port index */
{
SK_U8 Result ;
if ( ! pAC - > GIni . GP [ PhysPortIndex ] . PHWLinkUp ) {
Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN ;
}
else if ( pAC - > GIni . GP [ PhysPortIndex ] . PAutoNegFail > 0 ) {
Result = SK_PNMI_RLMT_LSTAT_AUTONEG ;
}
else if ( ! pAC - > Rlmt . Port [ PhysPortIndex ] . PortDown ) {
Result = SK_PNMI_RLMT_LSTAT_LOG_UP ;
}
else {
Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN ;
}
return ( Result ) ;
}
/*****************************************************************************
*
* CalculateLinkModeStatus - Determins the link mode status of a phys . port
*
* Description :
* The COMMON module only tells us if the mode is half or full duplex .
2006-01-10 00:08:17 +01:00
* But in the decade of auto sensing it is useful for the user to
2005-04-16 15:20:36 -07:00
* know if the mode was negotiated or forced . Therefore we have a
* look to the mode , which was last used by the negotiation process .
*
* Returns :
* The link mode status
*/
PNMI_STATIC SK_U8 CalculateLinkModeStatus (
SK_AC * pAC , /* Pointer to adapter context */
SK_IOC IoC , /* IO context handle */
unsigned int PhysPortIndex ) /* Physical port index */
{
SK_U8 Result ;
/* Get the current mode, which can be full or half duplex */
Result = pAC - > GIni . GP [ PhysPortIndex ] . PLinkModeStatus ;
/* Check if no valid mode could be found (link is down) */
if ( Result < SK_LMODE_STAT_HALF ) {
Result = SK_LMODE_STAT_UNKNOWN ;
}
else if ( pAC - > GIni . GP [ PhysPortIndex ] . PLinkMode > = SK_LMODE_AUTOHALF ) {
/*
* Auto - negotiation was used to bring up the link . Change
* the already found duplex status that it indicates
* auto - negotiation was involved .
*/
if ( Result = = SK_LMODE_STAT_HALF ) {
Result = SK_LMODE_STAT_AUTOHALF ;
}
else if ( Result = = SK_LMODE_STAT_FULL ) {
Result = SK_LMODE_STAT_AUTOFULL ;
}
}
return ( Result ) ;
}
/*****************************************************************************
*
* GetVpdKeyArr - Obtain an array of VPD keys
*
* Description :
* Read the VPD keys and build an array of VPD keys , which are
* easy to access .
*
* Returns :
* SK_PNMI_ERR_OK Task successfully performed .
* SK_PNMI_ERR_GENERAL Something went wrong .
*/
PNMI_STATIC int GetVpdKeyArr (
SK_AC * pAC , /* Pointer to adapter context */
SK_IOC IoC , /* IO context handle */
char * pKeyArr , /* Ptr KeyArray */
unsigned int KeyArrLen , /* Length of array in bytes */
unsigned int * pKeyNo ) /* Number of keys */
{
unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE ;
char BufKeys [ SK_PNMI_VPD_BUFSIZE ] ;
unsigned int StartOffset ;
unsigned int Offset ;
int Index ;
int Ret ;
SK_MEMSET ( pKeyArr , 0 , KeyArrLen ) ;
/*
* Get VPD key list
*/
Ret = VpdKeys ( pAC , IoC , ( char * ) & BufKeys , ( int * ) & BufKeysLen ,
( int * ) pKeyNo ) ;
if ( Ret > 0 ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR014 ,
SK_PNMI_ERR014MSG ) ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
/* If no keys are available return now */
if ( * pKeyNo = = 0 | | BufKeysLen = = 0 ) {
return ( SK_PNMI_ERR_OK ) ;
}
/*
* If the key list is too long for us trunc it and give a
* errorlog notification . This case should not happen because
* the maximum number of keys is limited due to RAM limitations
*/
if ( * pKeyNo > SK_PNMI_VPD_ENTRIES ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR015 ,
SK_PNMI_ERR015MSG ) ;
* pKeyNo = SK_PNMI_VPD_ENTRIES ;
}
/*
* Now build an array of fixed string length size and copy
* the keys together .
*/
for ( Index = 0 , StartOffset = 0 , Offset = 0 ; Offset < BufKeysLen ;
Offset + + ) {
if ( BufKeys [ Offset ] ! = 0 ) {
continue ;
}
if ( Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR016 ,
SK_PNMI_ERR016MSG ) ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
SK_STRNCPY ( pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE ,
& BufKeys [ StartOffset ] , SK_PNMI_VPD_KEY_SIZE ) ;
Index + + ;
StartOffset = Offset + 1 ;
}
/* Last key not zero terminated? Get it anyway */
if ( StartOffset < Offset ) {
SK_STRNCPY ( pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE ,
& BufKeys [ StartOffset ] , SK_PNMI_VPD_KEY_SIZE ) ;
}
return ( SK_PNMI_ERR_OK ) ;
}
/*****************************************************************************
*
* SirqUpdate - Let the SIRQ update its internal values
*
* Description :
* Just to be sure that the SIRQ module holds its internal data
* structures up to date , we send an update event before we make
* any access .
*
* Returns :
* SK_PNMI_ERR_OK Task successfully performed .
* SK_PNMI_ERR_GENERAL Something went wrong .
*/
PNMI_STATIC int SirqUpdate (
SK_AC * pAC , /* Pointer to adapter context */
SK_IOC IoC ) /* IO context handle */
{
SK_EVPARA EventParam ;
/* Was the module already updated during the current PNMI call? */
if ( pAC - > Pnmi . SirqUpdatedFlag > 0 ) {
return ( SK_PNMI_ERR_OK ) ;
}
/* Send an synchronuous update event to the module */
SK_MEMSET ( ( char * ) & EventParam , 0 , sizeof ( EventParam ) ) ;
if ( SkGeSirqEvent ( pAC , IoC , SK_HWEV_UPDATE_STAT , EventParam ) > 0 ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR047 ,
SK_PNMI_ERR047MSG ) ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
return ( SK_PNMI_ERR_OK ) ;
}
/*****************************************************************************
*
* RlmtUpdate - Let the RLMT update its internal values
*
* Description :
* Just to be sure that the RLMT module holds its internal data
* structures up to date , we send an update event before we make
* any access .
*
* Returns :
* SK_PNMI_ERR_OK Task successfully performed .
* SK_PNMI_ERR_GENERAL Something went wrong .
*/
PNMI_STATIC int RlmtUpdate (
SK_AC * pAC , /* Pointer to adapter context */
SK_IOC IoC , /* IO context handle */
SK_U32 NetIndex ) /* NetIndex (0..n), in single net mode allways zero */
{
SK_EVPARA EventParam ;
/* Was the module already updated during the current PNMI call? */
if ( pAC - > Pnmi . RlmtUpdatedFlag > 0 ) {
return ( SK_PNMI_ERR_OK ) ;
}
/* Send an synchronuous update event to the module */
SK_MEMSET ( ( char * ) & EventParam , 0 , sizeof ( EventParam ) ) ;
EventParam . Para32 [ 0 ] = NetIndex ;
EventParam . Para32 [ 1 ] = ( SK_U32 ) - 1 ;
if ( SkRlmtEvent ( pAC , IoC , SK_RLMT_STATS_UPDATE , EventParam ) > 0 ) {
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR048 ,
SK_PNMI_ERR048MSG ) ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
return ( SK_PNMI_ERR_OK ) ;
}
/*****************************************************************************
*
* MacUpdate - Force the XMAC to output the current statistic
*
* Description :
* The XMAC holds its statistic internally . To obtain the current
* values we must send a command so that the statistic data will
* be written to a predefined memory area on the adapter .
*
* Returns :
* SK_PNMI_ERR_OK Task successfully performed .
* SK_PNMI_ERR_GENERAL Something went wrong .
*/
PNMI_STATIC int MacUpdate (
SK_AC * pAC , /* Pointer to adapter context */
SK_IOC IoC , /* IO context handle */
unsigned int FirstMac , /* Index of the first Mac to be updated */
unsigned int LastMac ) /* Index of the last Mac to be updated */
{
unsigned int MacIndex ;
/*
* Were the statistics already updated during the
* current PNMI call ?
*/
if ( pAC - > Pnmi . MacUpdatedFlag > 0 ) {
return ( SK_PNMI_ERR_OK ) ;
}
/* Send an update command to all MACs specified */
for ( MacIndex = FirstMac ; MacIndex < = LastMac ; MacIndex + + ) {
/*
* 2002 - 09 - 13 pweber : Freeze the current SW counters .
* ( That should be done as close as
* possible to the update of the
* HW counters )
*/
if ( pAC - > GIni . GIMacType = = SK_MAC_XMAC ) {
pAC - > Pnmi . BufPort [ MacIndex ] = pAC - > Pnmi . Port [ MacIndex ] ;
}
/* 2002-09-13 pweber: Update the HW counter */
if ( pAC - > GIni . GIFunc . pFnMacUpdateStats ( pAC , IoC , MacIndex ) ! = 0 ) {
return ( SK_PNMI_ERR_GENERAL ) ;
}
}
return ( SK_PNMI_ERR_OK ) ;
}
/*****************************************************************************
*
* GetStatVal - Retrieve an XMAC statistic counter
*
* Description :
* Retrieves the statistic counter of a virtual or physical port . The
* virtual port is identified by the index 0. It consists of all
* currently active ports . To obtain the counter value for this port
* we must add the statistic counter of all active ports . To grant
* continuous counter values for the virtual port even when port
* switches occur we must additionally add a delta value , which was
* calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event .
*
* Returns :
* Requested statistic value
*/
PNMI_STATIC SK_U64 GetStatVal (
SK_AC * pAC , /* Pointer to adapter context */
SK_IOC IoC , /* IO context handle */
unsigned int LogPortIndex , /* Index of the logical Port to be processed */
unsigned int StatIndex , /* Index to statistic value */
SK_U32 NetIndex ) /* NetIndex (0..n), in single net mode allways zero */
{
unsigned int PhysPortIndex ;
unsigned int PhysPortMax ;
SK_U64 Val = 0 ;
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) { /* Dual net mode */
PhysPortIndex = NetIndex ;
Val = GetPhysStatVal ( pAC , IoC , PhysPortIndex , StatIndex ) ;
}
else { /* Single Net mode */
if ( LogPortIndex = = 0 ) {
PhysPortMax = pAC - > GIni . GIMacsFound ;
/* Add counter of all active ports */
for ( PhysPortIndex = 0 ; PhysPortIndex < PhysPortMax ;
PhysPortIndex + + ) {
if ( pAC - > Pnmi . Port [ PhysPortIndex ] . ActiveFlag ) {
Val + = GetPhysStatVal ( pAC , IoC , PhysPortIndex , StatIndex ) ;
}
}
/* Correct value because of port switches */
Val + = pAC - > Pnmi . VirtualCounterOffset [ StatIndex ] ;
}
else {
/* Get counter value of physical port */
PhysPortIndex = SK_PNMI_PORT_LOG2PHYS ( pAC , LogPortIndex ) ;
Val = GetPhysStatVal ( pAC , IoC , PhysPortIndex , StatIndex ) ;
}
}
return ( Val ) ;
}
/*****************************************************************************
*
* GetPhysStatVal - Get counter value for physical port
*
* Description :
* Builds a 64 bit counter value . Except for the octet counters
* the lower 32 bit are counted in hardware and the upper 32 bit
* in software by monitoring counter overflow interrupts in the
* event handler . To grant continous counter values during XMAC
* resets ( caused by a workaround ) we must add a delta value .
* The delta was calculated in the event handler when a
* SK_PNMI_EVT_XMAC_RESET was received .
*
* Returns :
* Counter value
*/
PNMI_STATIC SK_U64 GetPhysStatVal (
SK_AC * pAC , /* Pointer to adapter context */
SK_IOC IoC , /* IO context handle */
unsigned int PhysPortIndex , /* Index of the logical Port to be processed */
unsigned int StatIndex ) /* Index to statistic value */
{
SK_U64 Val = 0 ;
SK_U32 LowVal = 0 ;
SK_U32 HighVal = 0 ;
SK_U16 Word ;
int MacType ;
unsigned int HelpIndex ;
SK_GEPORT * pPrt ;
SK_PNMI_PORT * pPnmiPrt ;
SK_GEMACFUNC * pFnMac ;
pPrt = & pAC - > GIni . GP [ PhysPortIndex ] ;
MacType = pAC - > GIni . GIMacType ;
/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
if ( MacType = = SK_MAC_XMAC ) {
pPnmiPrt = & pAC - > Pnmi . BufPort [ PhysPortIndex ] ;
}
else {
pPnmiPrt = & pAC - > Pnmi . Port [ PhysPortIndex ] ;
}
pFnMac = & pAC - > GIni . GIFunc ;
switch ( StatIndex ) {
case SK_PNMI_HTX :
if ( MacType = = SK_MAC_GMAC ) {
( void ) pFnMac - > pFnMacStatistic ( pAC , IoC , PhysPortIndex ,
StatAddr [ SK_PNMI_HTX_BROADCAST ] [ MacType ] . Reg ,
& LowVal ) ;
( void ) pFnMac - > pFnMacStatistic ( pAC , IoC , PhysPortIndex ,
StatAddr [ SK_PNMI_HTX_MULTICAST ] [ MacType ] . Reg ,
& HighVal ) ;
LowVal + = HighVal ;
( void ) pFnMac - > pFnMacStatistic ( pAC , IoC , PhysPortIndex ,
StatAddr [ SK_PNMI_HTX_UNICAST ] [ MacType ] . Reg ,
& HighVal ) ;
LowVal + = HighVal ;
}
else {
( void ) pFnMac - > pFnMacStatistic ( pAC , IoC , PhysPortIndex ,
StatAddr [ StatIndex ] [ MacType ] . Reg ,
& LowVal ) ;
}
HighVal = pPnmiPrt - > CounterHigh [ StatIndex ] ;
break ;
case SK_PNMI_HRX :
if ( MacType = = SK_MAC_GMAC ) {
( void ) pFnMac - > pFnMacStatistic ( pAC , IoC , PhysPortIndex ,
StatAddr [ SK_PNMI_HRX_BROADCAST ] [ MacType ] . Reg ,
& LowVal ) ;
( void ) pFnMac - > pFnMacStatistic ( pAC , IoC , PhysPortIndex ,
StatAddr [ SK_PNMI_HRX_MULTICAST ] [ MacType ] . Reg ,
& HighVal ) ;
LowVal + = HighVal ;
( void ) pFnMac - > pFnMacStatistic ( pAC , IoC , PhysPortIndex ,
StatAddr [ SK_PNMI_HRX_UNICAST ] [ MacType ] . Reg ,
& HighVal ) ;
LowVal + = HighVal ;
}
else {
( void ) pFnMac - > pFnMacStatistic ( pAC , IoC , PhysPortIndex ,
StatAddr [ StatIndex ] [ MacType ] . Reg ,
& LowVal ) ;
}
HighVal = pPnmiPrt - > CounterHigh [ StatIndex ] ;
break ;
case SK_PNMI_HTX_OCTET :
case SK_PNMI_HRX_OCTET :
( void ) pFnMac - > pFnMacStatistic ( pAC , IoC , PhysPortIndex ,
StatAddr [ StatIndex ] [ MacType ] . Reg ,
& HighVal ) ;
( void ) pFnMac - > pFnMacStatistic ( pAC , IoC , PhysPortIndex ,
StatAddr [ StatIndex + 1 ] [ MacType ] . Reg ,
& LowVal ) ;
break ;
case SK_PNMI_HTX_BURST :
case SK_PNMI_HTX_EXCESS_DEF :
case SK_PNMI_HTX_CARRIER :
/* Not supported by GMAC */
if ( MacType = = SK_MAC_GMAC ) {
return ( Val ) ;
}
( void ) pFnMac - > pFnMacStatistic ( pAC , IoC , PhysPortIndex ,
StatAddr [ StatIndex ] [ MacType ] . Reg ,
& LowVal ) ;
HighVal = pPnmiPrt - > CounterHigh [ StatIndex ] ;
break ;
case SK_PNMI_HTX_MACC :
/* GMAC only supports PAUSE MAC control frames */
if ( MacType = = SK_MAC_GMAC ) {
HelpIndex = SK_PNMI_HTX_PMACC ;
}
else {
HelpIndex = StatIndex ;
}
( void ) pFnMac - > pFnMacStatistic ( pAC , IoC , PhysPortIndex ,
StatAddr [ HelpIndex ] [ MacType ] . Reg ,
& LowVal ) ;
HighVal = pPnmiPrt - > CounterHigh [ StatIndex ] ;
break ;
case SK_PNMI_HTX_COL :
case SK_PNMI_HRX_UNDERSIZE :
/* Not supported by XMAC */
if ( MacType = = SK_MAC_XMAC ) {
return ( Val ) ;
}
( void ) pFnMac - > pFnMacStatistic ( pAC , IoC , PhysPortIndex ,
StatAddr [ StatIndex ] [ MacType ] . Reg ,
& LowVal ) ;
HighVal = pPnmiPrt - > CounterHigh [ StatIndex ] ;
break ;
case SK_PNMI_HTX_DEFFERAL :
/* Not supported by GMAC */
if ( MacType = = SK_MAC_GMAC ) {
return ( Val ) ;
}
/*
* XMAC counts frames with deferred transmission
* even in full - duplex mode .
*
* In full - duplex mode the counter remains constant !
*/
if ( ( pPrt - > PLinkModeStatus = = SK_LMODE_STAT_AUTOFULL ) | |
( pPrt - > PLinkModeStatus = = SK_LMODE_STAT_FULL ) ) {
LowVal = 0 ;
HighVal = 0 ;
}
else {
/* Otherwise get contents of hardware register */
( void ) pFnMac - > pFnMacStatistic ( pAC , IoC , PhysPortIndex ,
StatAddr [ StatIndex ] [ MacType ] . Reg ,
& LowVal ) ;
HighVal = pPnmiPrt - > CounterHigh [ StatIndex ] ;
}
break ;
case SK_PNMI_HRX_BADOCTET :
/* Not supported by XMAC */
if ( MacType = = SK_MAC_XMAC ) {
return ( Val ) ;
}
( void ) pFnMac - > pFnMacStatistic ( pAC , IoC , PhysPortIndex ,
StatAddr [ StatIndex ] [ MacType ] . Reg ,
& HighVal ) ;
( void ) pFnMac - > pFnMacStatistic ( pAC , IoC , PhysPortIndex ,
StatAddr [ StatIndex + 1 ] [ MacType ] . Reg ,
& LowVal ) ;
break ;
case SK_PNMI_HTX_OCTETLOW :
case SK_PNMI_HRX_OCTETLOW :
case SK_PNMI_HRX_BADOCTETLOW :
return ( Val ) ;
case SK_PNMI_HRX_LONGFRAMES :
/* For XMAC the SW counter is managed by PNMI */
if ( MacType = = SK_MAC_XMAC ) {
return ( pPnmiPrt - > StatRxLongFrameCts ) ;
}
( void ) pFnMac - > pFnMacStatistic ( pAC , IoC , PhysPortIndex ,
StatAddr [ StatIndex ] [ MacType ] . Reg ,
& LowVal ) ;
HighVal = pPnmiPrt - > CounterHigh [ StatIndex ] ;
break ;
case SK_PNMI_HRX_TOO_LONG :
( void ) pFnMac - > pFnMacStatistic ( pAC , IoC , PhysPortIndex ,
StatAddr [ StatIndex ] [ MacType ] . Reg ,
& LowVal ) ;
HighVal = pPnmiPrt - > CounterHigh [ StatIndex ] ;
Val = ( ( ( SK_U64 ) HighVal < < 32 ) | ( SK_U64 ) LowVal ) ;
if ( MacType = = SK_MAC_GMAC ) {
/* For GMAC the SW counter is additionally managed by PNMI */
Val + = pPnmiPrt - > StatRxFrameTooLongCts ;
}
else {
/*
* Frames longer than IEEE 802.3 frame max size are counted
* by XMAC in frame_too_long counter even reception of long
* frames was enabled and the frame was correct .
* So correct the value by subtracting RxLongFrame counter .
*/
Val - = pPnmiPrt - > StatRxLongFrameCts ;
}
LowVal = ( SK_U32 ) Val ;
HighVal = ( SK_U32 ) ( Val > > 32 ) ;
break ;
case SK_PNMI_HRX_SHORTS :
/* Not supported by GMAC */
if ( MacType = = SK_MAC_GMAC ) {
/* GM_RXE_FRAG?? */
return ( Val ) ;
}
/*
* XMAC counts short frame errors even if link down ( # 10620 )
*
* If link - down the counter remains constant
*/
if ( pPrt - > PLinkModeStatus ! = SK_LMODE_STAT_UNKNOWN ) {
/* Otherwise get incremental difference */
( void ) pFnMac - > pFnMacStatistic ( pAC , IoC , PhysPortIndex ,
StatAddr [ StatIndex ] [ MacType ] . Reg ,
& LowVal ) ;
HighVal = pPnmiPrt - > CounterHigh [ StatIndex ] ;
Val = ( ( ( SK_U64 ) HighVal < < 32 ) | ( SK_U64 ) LowVal ) ;
Val - = pPnmiPrt - > RxShortZeroMark ;
LowVal = ( SK_U32 ) Val ;
HighVal = ( SK_U32 ) ( Val > > 32 ) ;
}
break ;
case SK_PNMI_HRX_MACC :
case SK_PNMI_HRX_MACC_UNKWN :
case SK_PNMI_HRX_BURST :
case SK_PNMI_HRX_MISSED :
case SK_PNMI_HRX_FRAMING :
case SK_PNMI_HRX_CARRIER :
case SK_PNMI_HRX_IRLENGTH :
case SK_PNMI_HRX_SYMBOL :
case SK_PNMI_HRX_CEXT :
/* Not supported by GMAC */
if ( MacType = = SK_MAC_GMAC ) {
return ( Val ) ;
}
( void ) pFnMac - > pFnMacStatistic ( pAC , IoC , PhysPortIndex ,
StatAddr [ StatIndex ] [ MacType ] . Reg ,
& LowVal ) ;
HighVal = pPnmiPrt - > CounterHigh [ StatIndex ] ;
break ;
case SK_PNMI_HRX_PMACC_ERR :
/* For GMAC the SW counter is managed by PNMI */
if ( MacType = = SK_MAC_GMAC ) {
return ( pPnmiPrt - > StatRxPMaccErr ) ;
}
( void ) pFnMac - > pFnMacStatistic ( pAC , IoC , PhysPortIndex ,
StatAddr [ StatIndex ] [ MacType ] . Reg ,
& LowVal ) ;
HighVal = pPnmiPrt - > CounterHigh [ StatIndex ] ;
break ;
/* SW counter managed by PNMI */
case SK_PNMI_HTX_SYNC :
LowVal = ( SK_U32 ) pPnmiPrt - > StatSyncCts ;
HighVal = ( SK_U32 ) ( pPnmiPrt - > StatSyncCts > > 32 ) ;
break ;
/* SW counter managed by PNMI */
case SK_PNMI_HTX_SYNC_OCTET :
LowVal = ( SK_U32 ) pPnmiPrt - > StatSyncOctetsCts ;
HighVal = ( SK_U32 ) ( pPnmiPrt - > StatSyncOctetsCts > > 32 ) ;
break ;
case SK_PNMI_HRX_FCS :
/*
* Broadcom filters FCS errors and counts it in
* Receive Error Counter register
*/
if ( pPrt - > PhyType = = SK_PHY_BCOM ) {
/* do not read while not initialized (PHY_READ hangs!)*/
if ( pPrt - > PState ! = SK_PRT_RESET ) {
SkXmPhyRead ( pAC , IoC , PhysPortIndex , PHY_BCOM_RE_CTR , & Word ) ;
LowVal = Word ;
}
HighVal = pPnmiPrt - > CounterHigh [ StatIndex ] ;
}
else {
( void ) pFnMac - > pFnMacStatistic ( pAC , IoC , PhysPortIndex ,
StatAddr [ StatIndex ] [ MacType ] . Reg ,
& LowVal ) ;
HighVal = pPnmiPrt - > CounterHigh [ StatIndex ] ;
}
break ;
default :
( void ) pFnMac - > pFnMacStatistic ( pAC , IoC , PhysPortIndex ,
StatAddr [ StatIndex ] [ MacType ] . Reg ,
& LowVal ) ;
HighVal = pPnmiPrt - > CounterHigh [ StatIndex ] ;
break ;
}
Val = ( ( ( SK_U64 ) HighVal < < 32 ) | ( SK_U64 ) LowVal ) ;
/* Correct value because of possible XMAC reset. XMAC Errata #2 */
Val + = pPnmiPrt - > CounterOffset [ StatIndex ] ;
return ( Val ) ;
}
/*****************************************************************************
*
* ResetCounter - Set all counters and timestamps to zero
*
* Description :
* Notifies other common modules which store statistic data to
* reset their counters and finally reset our own counters .
*
* Returns :
* Nothing
*/
PNMI_STATIC void ResetCounter (
SK_AC * pAC , /* Pointer to adapter context */
SK_IOC IoC , /* IO context handle */
SK_U32 NetIndex )
{
unsigned int PhysPortIndex ;
SK_EVPARA EventParam ;
SK_MEMSET ( ( char * ) & EventParam , 0 , sizeof ( EventParam ) ) ;
/* Notify sensor module */
SkEventQueue ( pAC , SKGE_I2C , SK_I2CEV_CLEAR , EventParam ) ;
/* Notify RLMT module */
EventParam . Para32 [ 0 ] = NetIndex ;
EventParam . Para32 [ 1 ] = ( SK_U32 ) - 1 ;
SkEventQueue ( pAC , SKGE_RLMT , SK_RLMT_STATS_CLEAR , EventParam ) ;
EventParam . Para32 [ 1 ] = 0 ;
/* Notify SIRQ module */
SkEventQueue ( pAC , SKGE_HWAC , SK_HWEV_CLEAR_STAT , EventParam ) ;
/* Notify CSUM module */
# ifdef SK_USE_CSUM
EventParam . Para32 [ 0 ] = NetIndex ;
EventParam . Para32 [ 1 ] = ( SK_U32 ) - 1 ;
SkEventQueue ( pAC , SKGE_CSUM , SK_CSUM_EVENT_CLEAR_PROTO_STATS ,
EventParam ) ;
# endif /* SK_USE_CSUM */
/* Clear XMAC statistic */
for ( PhysPortIndex = 0 ; PhysPortIndex <
( unsigned int ) pAC - > GIni . GIMacsFound ; PhysPortIndex + + ) {
( void ) pAC - > GIni . GIFunc . pFnMacResetCounter ( pAC , IoC , PhysPortIndex ) ;
SK_MEMSET ( ( char * ) & pAC - > Pnmi . Port [ PhysPortIndex ] . CounterHigh ,
0 , sizeof ( pAC - > Pnmi . Port [ PhysPortIndex ] . CounterHigh ) ) ;
SK_MEMSET ( ( char * ) & pAC - > Pnmi . Port [ PhysPortIndex ] .
CounterOffset , 0 , sizeof ( pAC - > Pnmi . Port [
PhysPortIndex ] . CounterOffset ) ) ;
SK_MEMSET ( ( char * ) & pAC - > Pnmi . Port [ PhysPortIndex ] . StatSyncCts ,
0 , sizeof ( pAC - > Pnmi . Port [ PhysPortIndex ] . StatSyncCts ) ) ;
SK_MEMSET ( ( char * ) & pAC - > Pnmi . Port [ PhysPortIndex ] .
StatSyncOctetsCts , 0 , sizeof ( pAC - > Pnmi . Port [
PhysPortIndex ] . StatSyncOctetsCts ) ) ;
SK_MEMSET ( ( char * ) & pAC - > Pnmi . Port [ PhysPortIndex ] .
StatRxLongFrameCts , 0 , sizeof ( pAC - > Pnmi . Port [
PhysPortIndex ] . StatRxLongFrameCts ) ) ;
SK_MEMSET ( ( char * ) & pAC - > Pnmi . Port [ PhysPortIndex ] .
StatRxFrameTooLongCts , 0 , sizeof ( pAC - > Pnmi . Port [
PhysPortIndex ] . StatRxFrameTooLongCts ) ) ;
SK_MEMSET ( ( char * ) & pAC - > Pnmi . Port [ PhysPortIndex ] .
StatRxPMaccErr , 0 , sizeof ( pAC - > Pnmi . Port [
PhysPortIndex ] . StatRxPMaccErr ) ) ;
}
/*
* Clear local statistics
*/
SK_MEMSET ( ( char * ) & pAC - > Pnmi . VirtualCounterOffset , 0 ,
sizeof ( pAC - > Pnmi . VirtualCounterOffset ) ) ;
pAC - > Pnmi . RlmtChangeCts = 0 ;
pAC - > Pnmi . RlmtChangeTime = 0 ;
SK_MEMSET ( ( char * ) & pAC - > Pnmi . RlmtChangeEstimate . EstValue [ 0 ] , 0 ,
sizeof ( pAC - > Pnmi . RlmtChangeEstimate . EstValue ) ) ;
pAC - > Pnmi . RlmtChangeEstimate . EstValueIndex = 0 ;
pAC - > Pnmi . RlmtChangeEstimate . Estimate = 0 ;
pAC - > Pnmi . Port [ NetIndex ] . TxSwQueueMax = 0 ;
pAC - > Pnmi . Port [ NetIndex ] . TxRetryCts = 0 ;
pAC - > Pnmi . Port [ NetIndex ] . RxIntrCts = 0 ;
pAC - > Pnmi . Port [ NetIndex ] . TxIntrCts = 0 ;
pAC - > Pnmi . Port [ NetIndex ] . RxNoBufCts = 0 ;
pAC - > Pnmi . Port [ NetIndex ] . TxNoBufCts = 0 ;
pAC - > Pnmi . Port [ NetIndex ] . TxUsedDescrNo = 0 ;
pAC - > Pnmi . Port [ NetIndex ] . RxDeliveredCts = 0 ;
pAC - > Pnmi . Port [ NetIndex ] . RxOctetsDeliveredCts = 0 ;
pAC - > Pnmi . Port [ NetIndex ] . ErrRecoveryCts = 0 ;
}
/*****************************************************************************
*
* GetTrapEntry - Get an entry in the trap buffer
*
* Description :
* The trap buffer stores various events . A user application somehow
* gets notified that an event occured and retrieves the trap buffer
* contens ( or simply polls the buffer ) . The buffer is organized as
* a ring which stores the newest traps at the beginning . The oldest
* traps are overwritten by the newest ones . Each trap entry has a
* unique number , so that applications may detect new trap entries .
*
* Returns :
* A pointer to the trap entry
*/
PNMI_STATIC char * GetTrapEntry (
SK_AC * pAC , /* Pointer to adapter context */
SK_U32 TrapId , /* SNMP ID of the trap */
unsigned int Size ) /* Space needed for trap entry */
{
unsigned int BufPad = pAC - > Pnmi . TrapBufPad ;
unsigned int BufFree = pAC - > Pnmi . TrapBufFree ;
unsigned int Beg = pAC - > Pnmi . TrapQueueBeg ;
unsigned int End = pAC - > Pnmi . TrapQueueEnd ;
char * pBuf = & pAC - > Pnmi . TrapBuf [ 0 ] ;
int Wrap ;
unsigned int NeededSpace ;
unsigned int EntrySize ;
SK_U32 Val32 ;
SK_U64 Val64 ;
/* Last byte of entry will get a copy of the entry length */
Size + + ;
/*
* Calculate needed buffer space */
if ( Beg > = Size ) {
NeededSpace = Size ;
Wrap = SK_FALSE ;
}
else {
NeededSpace = Beg + Size ;
Wrap = SK_TRUE ;
}
/*
* Check if enough buffer space is provided . Otherwise
* free some entries . Leave one byte space between begin
* and end of buffer to make it possible to detect whether
* the buffer is full or empty
*/
while ( BufFree < NeededSpace + 1 ) {
if ( End = = 0 ) {
End = SK_PNMI_TRAP_QUEUE_LEN ;
}
EntrySize = ( unsigned int ) * ( ( unsigned char * ) pBuf + End - 1 ) ;
BufFree + = EntrySize ;
End - = EntrySize ;
# ifdef DEBUG
SK_MEMSET ( pBuf + End , ( char ) ( - 1 ) , EntrySize ) ;
# endif /* DEBUG */
if ( End = = BufPad ) {
# ifdef DEBUG
SK_MEMSET ( pBuf , ( char ) ( - 1 ) , End ) ;
# endif /* DEBUG */
BufFree + = End ;
End = 0 ;
BufPad = 0 ;
}
}
/*
* Insert new entry as first entry . Newest entries are
* stored at the beginning of the queue .
*/
if ( Wrap ) {
BufPad = Beg ;
Beg = SK_PNMI_TRAP_QUEUE_LEN - Size ;
}
else {
Beg = Beg - Size ;
}
BufFree - = NeededSpace ;
/* Save the current offsets */
pAC - > Pnmi . TrapQueueBeg = Beg ;
pAC - > Pnmi . TrapQueueEnd = End ;
pAC - > Pnmi . TrapBufPad = BufPad ;
pAC - > Pnmi . TrapBufFree = BufFree ;
/* Initialize the trap entry */
* ( pBuf + Beg + Size - 1 ) = ( char ) Size ;
* ( pBuf + Beg ) = ( char ) Size ;
Val32 = ( pAC - > Pnmi . TrapUnique ) + + ;
SK_PNMI_STORE_U32 ( pBuf + Beg + 1 , Val32 ) ;
SK_PNMI_STORE_U32 ( pBuf + Beg + 1 + sizeof ( SK_U32 ) , TrapId ) ;
Val64 = SK_PNMI_HUNDREDS_SEC ( SkOsGetTime ( pAC ) ) ;
SK_PNMI_STORE_U64 ( pBuf + Beg + 1 + 2 * sizeof ( SK_U32 ) , Val64 ) ;
return ( pBuf + Beg ) ;
}
/*****************************************************************************
*
* CopyTrapQueue - Copies the trap buffer for the TRAP OID
*
* Description :
* On a query of the TRAP OID the trap buffer contents will be
* copied continuously to the request buffer , which must be large
* enough . No length check is performed .
*
* Returns :
* Nothing
*/
PNMI_STATIC void CopyTrapQueue (
SK_AC * pAC , /* Pointer to adapter context */
char * pDstBuf ) /* Buffer to which the queued traps will be copied */
{
unsigned int BufPad = pAC - > Pnmi . TrapBufPad ;
unsigned int Trap = pAC - > Pnmi . TrapQueueBeg ;
unsigned int End = pAC - > Pnmi . TrapQueueEnd ;
char * pBuf = & pAC - > Pnmi . TrapBuf [ 0 ] ;
unsigned int Len ;
unsigned int DstOff = 0 ;
while ( Trap ! = End ) {
Len = ( unsigned int ) * ( pBuf + Trap ) ;
/*
* Last byte containing a copy of the length will
* not be copied .
*/
* ( pDstBuf + DstOff ) = ( char ) ( Len - 1 ) ;
SK_MEMCPY ( pDstBuf + DstOff + 1 , pBuf + Trap + 1 , Len - 2 ) ;
DstOff + = Len - 1 ;
Trap + = Len ;
if ( Trap = = SK_PNMI_TRAP_QUEUE_LEN ) {
Trap = BufPad ;
}
}
}
/*****************************************************************************
*
* GetTrapQueueLen - Get the length of the trap buffer
*
* Description :
* Evaluates the number of currently stored traps and the needed
* buffer size to retrieve them .
*
* Returns :
* Nothing
*/
PNMI_STATIC void GetTrapQueueLen (
SK_AC * pAC , /* Pointer to adapter context */
unsigned int * pLen , /* Length in Bytes of all queued traps */
unsigned int * pEntries ) /* Returns number of trapes stored in queue */
{
unsigned int BufPad = pAC - > Pnmi . TrapBufPad ;
unsigned int Trap = pAC - > Pnmi . TrapQueueBeg ;
unsigned int End = pAC - > Pnmi . TrapQueueEnd ;
char * pBuf = & pAC - > Pnmi . TrapBuf [ 0 ] ;
unsigned int Len ;
unsigned int Entries = 0 ;
unsigned int TotalLen = 0 ;
while ( Trap ! = End ) {
Len = ( unsigned int ) * ( pBuf + Trap ) ;
TotalLen + = Len - 1 ;
Entries + + ;
Trap + = Len ;
if ( Trap = = SK_PNMI_TRAP_QUEUE_LEN ) {
Trap = BufPad ;
}
}
* pEntries = Entries ;
* pLen = TotalLen ;
}
/*****************************************************************************
*
* QueueSimpleTrap - Store a simple trap to the trap buffer
*
* Description :
* A simple trap is a trap with now additional data . It consists
* simply of a trap code .
*
* Returns :
* Nothing
*/
PNMI_STATIC void QueueSimpleTrap (
SK_AC * pAC , /* Pointer to adapter context */
SK_U32 TrapId ) /* Type of sensor trap */
{
GetTrapEntry ( pAC , TrapId , SK_PNMI_TRAP_SIMPLE_LEN ) ;
}
/*****************************************************************************
*
* QueueSensorTrap - Stores a sensor trap in the trap buffer
*
* Description :
* Gets an entry in the trap buffer and fills it with sensor related
* data .
*
* Returns :
* Nothing
*/
PNMI_STATIC void QueueSensorTrap (
SK_AC * pAC , /* Pointer to adapter context */
SK_U32 TrapId , /* Type of sensor trap */
unsigned int SensorIndex ) /* Index of sensor which caused the trap */
{
char * pBuf ;
unsigned int Offset ;
unsigned int DescrLen ;
SK_U32 Val32 ;
/* Get trap buffer entry */
DescrLen = SK_STRLEN ( pAC - > I2c . SenTable [ SensorIndex ] . SenDesc ) ;
pBuf = GetTrapEntry ( pAC , TrapId ,
SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen ) ;
Offset = SK_PNMI_TRAP_SIMPLE_LEN ;
/* Store additionally sensor trap related data */
Val32 = OID_SKGE_SENSOR_INDEX ;
SK_PNMI_STORE_U32 ( pBuf + Offset , Val32 ) ;
* ( pBuf + Offset + 4 ) = 4 ;
Val32 = ( SK_U32 ) SensorIndex ;
SK_PNMI_STORE_U32 ( pBuf + Offset + 5 , Val32 ) ;
Offset + = 9 ;
Val32 = ( SK_U32 ) OID_SKGE_SENSOR_DESCR ;
SK_PNMI_STORE_U32 ( pBuf + Offset , Val32 ) ;
* ( pBuf + Offset + 4 ) = ( char ) DescrLen ;
SK_MEMCPY ( pBuf + Offset + 5 , pAC - > I2c . SenTable [ SensorIndex ] . SenDesc ,
DescrLen ) ;
Offset + = DescrLen + 5 ;
Val32 = OID_SKGE_SENSOR_TYPE ;
SK_PNMI_STORE_U32 ( pBuf + Offset , Val32 ) ;
* ( pBuf + Offset + 4 ) = 1 ;
* ( pBuf + Offset + 5 ) = ( char ) pAC - > I2c . SenTable [ SensorIndex ] . SenType ;
Offset + = 6 ;
Val32 = OID_SKGE_SENSOR_VALUE ;
SK_PNMI_STORE_U32 ( pBuf + Offset , Val32 ) ;
* ( pBuf + Offset + 4 ) = 4 ;
Val32 = ( SK_U32 ) pAC - > I2c . SenTable [ SensorIndex ] . SenValue ;
SK_PNMI_STORE_U32 ( pBuf + Offset + 5 , Val32 ) ;
}
/*****************************************************************************
*
* QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
*
* Description :
* Nothing further to explain .
*
* Returns :
* Nothing
*/
PNMI_STATIC void QueueRlmtNewMacTrap (
SK_AC * pAC , /* Pointer to adapter context */
unsigned int ActiveMac ) /* Index (0..n) of the currently active port */
{
char * pBuf ;
SK_U32 Val32 ;
pBuf = GetTrapEntry ( pAC , OID_SKGE_TRAP_RLMT_CHANGE_PORT ,
SK_PNMI_TRAP_RLMT_CHANGE_LEN ) ;
Val32 = OID_SKGE_RLMT_PORT_ACTIVE ;
SK_PNMI_STORE_U32 ( pBuf + SK_PNMI_TRAP_SIMPLE_LEN , Val32 ) ;
* ( pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4 ) = 1 ;
* ( pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5 ) = ( char ) ActiveMac ;
}
/*****************************************************************************
*
* QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
*
* Description :
* Nothing further to explain .
*
* Returns :
* Nothing
*/
PNMI_STATIC void QueueRlmtPortTrap (
SK_AC * pAC , /* Pointer to adapter context */
SK_U32 TrapId , /* Type of RLMT port trap */
unsigned int PortIndex ) /* Index of the port, which changed its state */
{
char * pBuf ;
SK_U32 Val32 ;
pBuf = GetTrapEntry ( pAC , TrapId , SK_PNMI_TRAP_RLMT_PORT_LEN ) ;
Val32 = OID_SKGE_RLMT_PORT_INDEX ;
SK_PNMI_STORE_U32 ( pBuf + SK_PNMI_TRAP_SIMPLE_LEN , Val32 ) ;
* ( pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4 ) = 1 ;
* ( pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5 ) = ( char ) PortIndex ;
}
/*****************************************************************************
*
* CopyMac - Copies a MAC address
*
* Description :
* Nothing further to explain .
*
* Returns :
* Nothing
*/
PNMI_STATIC void CopyMac (
char * pDst , /* Pointer to destination buffer */
SK_MAC_ADDR * pMac ) /* Pointer of Source */
{
int i ;
for ( i = 0 ; i < sizeof ( SK_MAC_ADDR ) ; i + + ) {
* ( pDst + i ) = pMac - > a [ i ] ;
}
}
# ifdef SK_POWER_MGMT
/*****************************************************************************
*
* PowerManagement - OID handler function of PowerManagement OIDs
*
* Description :
* The code is simple . No description necessary .
*
* Returns :
* SK_PNMI_ERR_OK The request was successfully performed .
* SK_PNMI_ERR_GENERAL A general severe internal error occured .
* SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
* the correct data ( e . g . a 32 bit value is
* needed , but a 16 bit value was passed ) .
* SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn ' t
* exist ( e . g . port instance 3 on a two port
* adapter .
*/
PNMI_STATIC int PowerManagement (
SK_AC * pAC , /* Pointer to adapter context */
SK_IOC IoC , /* IO context handle */
int Action , /* Get/PreSet/Set action */
SK_U32 Id , /* Object ID that is to be processed */
char * pBuf , /* Buffer to which to mgmt data will be retrieved */
unsigned int * pLen , /* On call: buffer length. On return: used buffer */
SK_U32 Instance , /* Instance (1..n) that is to be queried or -1 */
unsigned int TableIndex , /* Index to the Id table */
SK_U32 NetIndex ) /* NetIndex (0..n), in single net mode allways zero */
{
SK_U32 RetCode = SK_PNMI_ERR_GENERAL ;
/*
* Check instance . We only handle single instance variables
*/
if ( Instance ! = ( SK_U32 ) ( - 1 ) & & Instance ! = 1 ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_UNKNOWN_INST ) ;
}
/* Check length */
switch ( Id ) {
case OID_PNP_CAPABILITIES :
if ( * pLen < sizeof ( SK_PNP_CAPABILITIES ) ) {
* pLen = sizeof ( SK_PNP_CAPABILITIES ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
break ;
case OID_PNP_SET_POWER :
case OID_PNP_QUERY_POWER :
if ( * pLen < sizeof ( SK_DEVICE_POWER_STATE ) )
{
* pLen = sizeof ( SK_DEVICE_POWER_STATE ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
break ;
case OID_PNP_ADD_WAKE_UP_PATTERN :
case OID_PNP_REMOVE_WAKE_UP_PATTERN :
if ( * pLen < sizeof ( SK_PM_PACKET_PATTERN ) ) {
* pLen = sizeof ( SK_PM_PACKET_PATTERN ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
break ;
case OID_PNP_ENABLE_WAKE_UP :
if ( * pLen < sizeof ( SK_U32 ) ) {
* pLen = sizeof ( SK_U32 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
break ;
}
/*
* Perform action
*/
if ( Action = = SK_PNMI_GET ) {
/*
* Get value
*/
switch ( Id ) {
case OID_PNP_CAPABILITIES :
RetCode = SkPowerQueryPnPCapabilities ( pAC , IoC , pBuf , pLen ) ;
break ;
case OID_PNP_QUERY_POWER :
/* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
the miniport to indicate whether it can transition its NIC
to the low - power state .
A miniport driver must always return NDIS_STATUS_SUCCESS
to a query of OID_PNP_QUERY_POWER . */
* pLen = sizeof ( SK_DEVICE_POWER_STATE ) ;
RetCode = SK_PNMI_ERR_OK ;
break ;
/* NDIS handles these OIDs as write-only.
* So in case of get action the buffer with written length = 0
* is returned
*/
case OID_PNP_SET_POWER :
case OID_PNP_ADD_WAKE_UP_PATTERN :
case OID_PNP_REMOVE_WAKE_UP_PATTERN :
* pLen = 0 ;
RetCode = SK_PNMI_ERR_NOT_SUPPORTED ;
break ;
case OID_PNP_ENABLE_WAKE_UP :
RetCode = SkPowerGetEnableWakeUp ( pAC , IoC , pBuf , pLen ) ;
break ;
default :
RetCode = SK_PNMI_ERR_GENERAL ;
break ;
}
return ( RetCode ) ;
}
/*
* Perform preset or set
*/
/* POWER module does not support PRESET action */
if ( Action = = SK_PNMI_PRESET ) {
return ( SK_PNMI_ERR_OK ) ;
}
switch ( Id ) {
case OID_PNP_SET_POWER :
RetCode = SkPowerSetPower ( pAC , IoC , pBuf , pLen ) ;
break ;
case OID_PNP_ADD_WAKE_UP_PATTERN :
RetCode = SkPowerAddWakeUpPattern ( pAC , IoC , pBuf , pLen ) ;
break ;
case OID_PNP_REMOVE_WAKE_UP_PATTERN :
RetCode = SkPowerRemoveWakeUpPattern ( pAC , IoC , pBuf , pLen ) ;
break ;
case OID_PNP_ENABLE_WAKE_UP :
RetCode = SkPowerSetEnableWakeUp ( pAC , IoC , pBuf , pLen ) ;
break ;
default :
RetCode = SK_PNMI_ERR_READ_ONLY ;
}
return ( RetCode ) ;
}
# endif /* SK_POWER_MGMT */
# ifdef SK_DIAG_SUPPORT
/*****************************************************************************
*
* DiagActions - OID handler function of Diagnostic driver
*
* Description :
* The code is simple . No description necessary .
*
* Returns :
* SK_PNMI_ERR_OK The request was successfully performed .
* SK_PNMI_ERR_GENERAL A general severe internal error occured .
* SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
* the correct data ( e . g . a 32 bit 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 DiagActions (
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 used for the management data transfer */
unsigned int * pLen , /* On call: pBuf 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 always zero */
{
SK_U32 DiagStatus ;
SK_U32 RetCode = SK_PNMI_ERR_GENERAL ;
/*
* Check instance . We only handle single instance variables .
*/
if ( Instance ! = ( SK_U32 ) ( - 1 ) & & Instance ! = 1 ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_UNKNOWN_INST ) ;
}
/*
* Check length .
*/
switch ( Id ) {
case OID_SKGE_DIAG_MODE :
if ( * pLen < sizeof ( SK_U32 ) ) {
* pLen = sizeof ( SK_U32 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
break ;
default :
SK_ERR_LOG ( pAC , SK_ERRCL_SW , SK_PNMI_ERR040 , SK_PNMI_ERR040MSG ) ;
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
/* Perform action. */
/* GET value. */
if ( Action = = SK_PNMI_GET ) {
switch ( Id ) {
case OID_SKGE_DIAG_MODE :
DiagStatus = pAC - > Pnmi . DiagAttached ;
SK_PNMI_STORE_U32 ( pBuf , DiagStatus ) ;
* pLen = sizeof ( SK_U32 ) ;
RetCode = SK_PNMI_ERR_OK ;
break ;
default :
* pLen = 0 ;
RetCode = SK_PNMI_ERR_GENERAL ;
break ;
}
return ( RetCode ) ;
}
/* From here SET or PRESET value. */
/* PRESET value is not supported. */
if ( Action = = SK_PNMI_PRESET ) {
return ( SK_PNMI_ERR_OK ) ;
}
/* SET value. */
switch ( Id ) {
case OID_SKGE_DIAG_MODE :
/* Handle the SET. */
switch ( * pBuf ) {
/* Attach the DIAG to this adapter. */
case SK_DIAG_ATTACHED :
/* Check if we come from running */
if ( pAC - > Pnmi . DiagAttached = = SK_DIAG_RUNNING ) {
RetCode = SkDrvLeaveDiagMode ( pAC ) ;
}
else if ( pAC - > Pnmi . DiagAttached = = SK_DIAG_IDLE ) {
RetCode = SK_PNMI_ERR_OK ;
}
else {
RetCode = SK_PNMI_ERR_GENERAL ;
}
if ( RetCode = = SK_PNMI_ERR_OK ) {
pAC - > Pnmi . DiagAttached = SK_DIAG_ATTACHED ;
}
break ;
/* Enter the DIAG mode in the driver. */
case SK_DIAG_RUNNING :
RetCode = SK_PNMI_ERR_OK ;
/*
* If DiagAttached is set , we can tell the driver
* to enter the DIAG mode .
*/
if ( pAC - > Pnmi . DiagAttached = = SK_DIAG_ATTACHED ) {
/* If DiagMode is not active, we can enter it. */
if ( ! pAC - > DiagModeActive ) {
RetCode = SkDrvEnterDiagMode ( pAC ) ;
}
else {
RetCode = SK_PNMI_ERR_GENERAL ;
}
}
else {
RetCode = SK_PNMI_ERR_GENERAL ;
}
if ( RetCode = = SK_PNMI_ERR_OK ) {
pAC - > Pnmi . DiagAttached = SK_DIAG_RUNNING ;
}
break ;
case SK_DIAG_IDLE :
/* Check if we come from running */
if ( pAC - > Pnmi . DiagAttached = = SK_DIAG_RUNNING ) {
RetCode = SkDrvLeaveDiagMode ( pAC ) ;
}
else if ( pAC - > Pnmi . DiagAttached = = SK_DIAG_ATTACHED ) {
RetCode = SK_PNMI_ERR_OK ;
}
else {
RetCode = SK_PNMI_ERR_GENERAL ;
}
if ( RetCode = = SK_PNMI_ERR_OK ) {
pAC - > Pnmi . DiagAttached = SK_DIAG_IDLE ;
}
break ;
default :
RetCode = SK_PNMI_ERR_BAD_VALUE ;
break ;
}
break ;
default :
RetCode = SK_PNMI_ERR_GENERAL ;
}
if ( RetCode = = SK_PNMI_ERR_OK ) {
* pLen = sizeof ( SK_U32 ) ;
}
else {
* pLen = 0 ;
}
return ( RetCode ) ;
}
# endif /* SK_DIAG_SUPPORT */
/*****************************************************************************
*
* Vct - OID handler function of OIDs
*
* Description :
* The code is simple . No description necessary .
*
* Returns :
* SK_PNMI_ERR_OK The request was performed successfully .
* SK_PNMI_ERR_GENERAL A general severe internal error occured .
* SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
* the correct data ( e . g . a 32 bit value is
* needed , but a 16 bit value was passed ) .
* SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn ' t
* exist ( e . g . port instance 3 on a two port
* adapter ) .
* SK_PNMI_ERR_READ_ONLY Only the Get action is allowed .
*
*/
PNMI_STATIC int Vct (
SK_AC * pAC , /* Pointer to adapter context */
SK_IOC IoC , /* IO context handle */
int Action , /* GET/PRESET/SET action */
SK_U32 Id , /* Object ID that is to be processed */
char * pBuf , /* Buffer used for the management data transfer */
unsigned int * pLen , /* On call: pBuf buffer length. On return: used buffer */
SK_U32 Instance , /* Instance (-1,2..n) that is to be queried */
unsigned int TableIndex , /* Index to the Id table */
SK_U32 NetIndex ) /* NetIndex (0..n), in single net mode always zero */
{
SK_GEPORT * pPrt ;
SK_PNMI_VCT * pVctBackupData ;
SK_U32 LogPortMax ;
SK_U32 PhysPortMax ;
SK_U32 PhysPortIndex ;
SK_U32 Limit ;
SK_U32 Offset ;
SK_BOOL Link ;
SK_U32 RetCode = SK_PNMI_ERR_GENERAL ;
int i ;
SK_EVPARA Para ;
SK_U32 CableLength ;
/*
* Calculate the port indexes from the instance .
*/
PhysPortMax = pAC - > GIni . GIMacsFound ;
LogPortMax = SK_PNMI_PORT_PHYS2LOG ( PhysPortMax ) ;
/* Dual net mode? */
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
LogPortMax - - ;
}
if ( ( Instance ! = ( SK_U32 ) ( - 1 ) ) ) {
/* Check instance range. */
if ( ( Instance < 2 ) | | ( Instance > LogPortMax ) ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_UNKNOWN_INST ) ;
}
if ( pAC - > Pnmi . DualNetActiveFlag = = SK_TRUE ) {
PhysPortIndex = NetIndex ;
}
else {
PhysPortIndex = Instance - 2 ;
}
Limit = PhysPortIndex + 1 ;
}
else {
/*
* Instance = = ( SK_U32 ) ( - 1 ) , get all Instances of that OID .
*
* Not implemented yet . May be used in future releases .
*/
PhysPortIndex = 0 ;
Limit = PhysPortMax ;
}
pPrt = & pAC - > GIni . GP [ PhysPortIndex ] ;
if ( pPrt - > PHWLinkUp ) {
Link = SK_TRUE ;
}
else {
Link = SK_FALSE ;
}
/* Check MAC type */
if ( pPrt - > PhyType ! = SK_PHY_MARV_COPPER ) {
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
/* Initialize backup data pointer. */
pVctBackupData = & pAC - > Pnmi . VctBackup [ PhysPortIndex ] ;
/* Check action type */
if ( Action = = SK_PNMI_GET ) {
/* Check length */
switch ( Id ) {
case OID_SKGE_VCT_GET :
if ( * pLen < ( Limit - PhysPortIndex ) * sizeof ( SK_PNMI_VCT ) ) {
* pLen = ( Limit - PhysPortIndex ) * sizeof ( SK_PNMI_VCT ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
break ;
case OID_SKGE_VCT_STATUS :
if ( * pLen < ( Limit - PhysPortIndex ) * sizeof ( SK_U8 ) ) {
* pLen = ( Limit - PhysPortIndex ) * sizeof ( SK_U8 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
break ;
default :
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
/* Get value */
Offset = 0 ;
for ( ; PhysPortIndex < Limit ; PhysPortIndex + + ) {
switch ( Id ) {
case OID_SKGE_VCT_GET :
if ( ( Link = = SK_FALSE ) & &
( pAC - > Pnmi . VctStatus [ PhysPortIndex ] & SK_PNMI_VCT_PENDING ) ) {
RetCode = SkGmCableDiagStatus ( pAC , IoC , PhysPortIndex , SK_FALSE ) ;
if ( RetCode = = 0 ) {
pAC - > Pnmi . VctStatus [ PhysPortIndex ] & = ~ SK_PNMI_VCT_PENDING ;
pAC - > Pnmi . VctStatus [ PhysPortIndex ] | =
( SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE ) ;
/* Copy results for later use to PNMI struct. */
for ( i = 0 ; i < 4 ; i + + ) {
if ( pPrt - > PMdiPairSts [ i ] = = SK_PNMI_VCT_NORMAL_CABLE ) {
if ( ( pPrt - > PMdiPairLen [ i ] > 35 ) & & ( pPrt - > PMdiPairLen [ i ] < 0xff ) ) {
pPrt - > PMdiPairSts [ i ] = SK_PNMI_VCT_IMPEDANCE_MISMATCH ;
}
}
if ( ( pPrt - > PMdiPairLen [ i ] > 35 ) & & ( pPrt - > PMdiPairLen [ i ] ! = 0xff ) ) {
CableLength = 1000 * ( ( ( 175 * pPrt - > PMdiPairLen [ i ] ) / 210 ) - 28 ) ;
}
else {
CableLength = 0 ;
}
pVctBackupData - > PMdiPairLen [ i ] = CableLength ;
pVctBackupData - > PMdiPairSts [ i ] = pPrt - > PMdiPairSts [ i ] ;
}
Para . Para32 [ 0 ] = PhysPortIndex ;
Para . Para32 [ 1 ] = - 1 ;
SkEventQueue ( pAC , SKGE_DRV , SK_DRV_PORT_RESET , Para ) ;
SkEventDispatcher ( pAC , IoC ) ;
}
else {
; /* VCT test is running. */
}
}
/* Get all results. */
CheckVctStatus ( pAC , IoC , pBuf , Offset , PhysPortIndex ) ;
Offset + = sizeof ( SK_U8 ) ;
* ( pBuf + Offset ) = pPrt - > PCableLen ;
Offset + = sizeof ( SK_U8 ) ;
for ( i = 0 ; i < 4 ; i + + ) {
SK_PNMI_STORE_U32 ( ( pBuf + Offset ) , pVctBackupData - > PMdiPairLen [ i ] ) ;
Offset + = sizeof ( SK_U32 ) ;
}
for ( i = 0 ; i < 4 ; i + + ) {
* ( pBuf + Offset ) = pVctBackupData - > PMdiPairSts [ i ] ;
Offset + = sizeof ( SK_U8 ) ;
}
RetCode = SK_PNMI_ERR_OK ;
break ;
case OID_SKGE_VCT_STATUS :
CheckVctStatus ( pAC , IoC , pBuf , Offset , PhysPortIndex ) ;
Offset + = sizeof ( SK_U8 ) ;
RetCode = SK_PNMI_ERR_OK ;
break ;
default :
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
} /* for */
* pLen = Offset ;
return ( RetCode ) ;
} /* if SK_PNMI_GET */
/*
* From here SET or PRESET action . Check if the passed
* buffer length is plausible .
*/
/* Check length */
switch ( Id ) {
case OID_SKGE_VCT_SET :
if ( * pLen < ( Limit - PhysPortIndex ) * sizeof ( SK_U32 ) ) {
* pLen = ( Limit - PhysPortIndex ) * sizeof ( SK_U32 ) ;
return ( SK_PNMI_ERR_TOO_SHORT ) ;
}
break ;
default :
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
/*
* Perform preset or set .
*/
/* VCT does not support PRESET action. */
if ( Action = = SK_PNMI_PRESET ) {
return ( SK_PNMI_ERR_OK ) ;
}
Offset = 0 ;
for ( ; PhysPortIndex < Limit ; PhysPortIndex + + ) {
switch ( Id ) {
case OID_SKGE_VCT_SET : /* Start VCT test. */
if ( Link = = SK_FALSE ) {
SkGeStopPort ( pAC , IoC , PhysPortIndex , SK_STOP_ALL , SK_SOFT_RST ) ;
RetCode = SkGmCableDiagStatus ( pAC , IoC , PhysPortIndex , SK_TRUE ) ;
if ( RetCode = = 0 ) { /* RetCode: 0 => Start! */
pAC - > Pnmi . VctStatus [ PhysPortIndex ] | = SK_PNMI_VCT_PENDING ;
pAC - > Pnmi . VctStatus [ PhysPortIndex ] & = ~ SK_PNMI_VCT_NEW_VCT_DATA ;
pAC - > Pnmi . VctStatus [ PhysPortIndex ] & = ~ SK_PNMI_VCT_LINK ;
/*
* Start VCT timer counter .
*/
SK_MEMSET ( ( char * ) & Para , 0 , sizeof ( Para ) ) ;
Para . Para32 [ 0 ] = PhysPortIndex ;
Para . Para32 [ 1 ] = - 1 ;
SkTimerStart ( pAC , IoC , & pAC - > Pnmi . VctTimeout [ PhysPortIndex ] . VctTimer ,
4000000 , SKGE_PNMI , SK_PNMI_EVT_VCT_RESET , Para ) ;
SK_PNMI_STORE_U32 ( ( pBuf + Offset ) , RetCode ) ;
RetCode = SK_PNMI_ERR_OK ;
}
else { /* RetCode: 2 => Running! */
SK_PNMI_STORE_U32 ( ( pBuf + Offset ) , RetCode ) ;
RetCode = SK_PNMI_ERR_OK ;
}
}
else { /* RetCode: 4 => Link! */
RetCode = 4 ;
SK_PNMI_STORE_U32 ( ( pBuf + Offset ) , RetCode ) ;
RetCode = SK_PNMI_ERR_OK ;
}
Offset + = sizeof ( SK_U32 ) ;
break ;
default :
* pLen = 0 ;
return ( SK_PNMI_ERR_GENERAL ) ;
}
} /* for */
* pLen = Offset ;
return ( RetCode ) ;
} /* Vct */
PNMI_STATIC void CheckVctStatus (
SK_AC * pAC ,
SK_IOC IoC ,
char * pBuf ,
SK_U32 Offset ,
SK_U32 PhysPortIndex )
{
SK_GEPORT * pPrt ;
SK_PNMI_VCT * pVctData ;
SK_U32 RetCode ;
pPrt = & pAC - > GIni . GP [ PhysPortIndex ] ;
pVctData = ( SK_PNMI_VCT * ) ( pBuf + Offset ) ;
pVctData - > VctStatus = SK_PNMI_VCT_NONE ;
if ( ! pPrt - > PHWLinkUp ) {
/* Was a VCT test ever made before? */
if ( pAC - > Pnmi . VctStatus [ PhysPortIndex ] & SK_PNMI_VCT_TEST_DONE ) {
if ( ( pAC - > Pnmi . VctStatus [ PhysPortIndex ] & SK_PNMI_VCT_LINK ) ) {
pVctData - > VctStatus | = SK_PNMI_VCT_OLD_VCT_DATA ;
}
else {
pVctData - > VctStatus | = SK_PNMI_VCT_NEW_VCT_DATA ;
}
}
/* Check VCT test status. */
RetCode = SkGmCableDiagStatus ( pAC , IoC , PhysPortIndex , SK_FALSE ) ;
if ( RetCode = = 2 ) { /* VCT test is running. */
pVctData - > VctStatus | = SK_PNMI_VCT_RUNNING ;
}
else { /* VCT data was copied to pAC here. Check PENDING state. */
if ( pAC - > Pnmi . VctStatus [ PhysPortIndex ] & SK_PNMI_VCT_PENDING ) {
pVctData - > VctStatus | = SK_PNMI_VCT_NEW_VCT_DATA ;
}
}
if ( pPrt - > PCableLen ! = 0xff ) { /* Old DSP value. */
pVctData - > VctStatus | = SK_PNMI_VCT_OLD_DSP_DATA ;
}
}
else {
/* Was a VCT test ever made before? */
if ( pAC - > Pnmi . VctStatus [ PhysPortIndex ] & SK_PNMI_VCT_TEST_DONE ) {
pVctData - > VctStatus & = ~ SK_PNMI_VCT_NEW_VCT_DATA ;
pVctData - > VctStatus | = SK_PNMI_VCT_OLD_VCT_DATA ;
}
/* DSP only valid in 100/1000 modes. */
if ( pAC - > GIni . GP [ PhysPortIndex ] . PLinkSpeedUsed ! =
SK_LSPEED_STAT_10MBPS ) {
pVctData - > VctStatus | = SK_PNMI_VCT_NEW_DSP_DATA ;
}
}
} /* CheckVctStatus */
/*****************************************************************************
*
* SkPnmiGenIoctl - Handles new generic PNMI IOCTL , calls the needed
* PNMI function depending on the subcommand and
* returns all data belonging to the complete database
* or OID request .
*
* Description :
* Looks up the requested subcommand , calls the corresponding handler
* function and passes all required parameters to it .
* The function is called by the driver . It is needed to handle the new
* generic PNMI IOCTL . This IOCTL is given to the driver and contains both
* the OID and a subcommand to decide what kind of request has to be done .
*
* 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 SkPnmiGenIoctl (
SK_AC * pAC , /* Pointer to adapter context struct */
SK_IOC IoC , /* I/O context */
void * pBuf , /* Buffer used for the management data transfer */
unsigned int * pLen , /* Length of buffer */
SK_U32 NetIndex ) /* NetIndex (0..n), in single net mode always zero */
{
SK_I32 Mode ; /* Store value of subcommand. */
SK_U32 Oid ; /* Store value of OID. */
int ReturnCode ; /* Store return value to show status of PNMI action. */
int HeaderLength ; /* Length of desired action plus OID. */
ReturnCode = SK_PNMI_ERR_GENERAL ;
SK_MEMCPY ( & Mode , pBuf , sizeof ( SK_I32 ) ) ;
SK_MEMCPY ( & Oid , ( char * ) pBuf + sizeof ( SK_I32 ) , sizeof ( SK_U32 ) ) ;
HeaderLength = sizeof ( SK_I32 ) + sizeof ( SK_U32 ) ;
* pLen = * pLen - HeaderLength ;
SK_MEMCPY ( ( char * ) pBuf + sizeof ( SK_I32 ) , ( char * ) pBuf + HeaderLength , * pLen ) ;
switch ( Mode ) {
case SK_GET_SINGLE_VAR :
ReturnCode = SkPnmiGetVar ( pAC , IoC , Oid ,
( char * ) pBuf + sizeof ( SK_I32 ) , pLen ,
( ( SK_U32 ) ( - 1 ) ) , NetIndex ) ;
SK_PNMI_STORE_U32 ( pBuf , ReturnCode ) ;
* pLen = * pLen + sizeof ( SK_I32 ) ;
break ;
case SK_PRESET_SINGLE_VAR :
ReturnCode = SkPnmiPreSetVar ( pAC , IoC , Oid ,
( char * ) pBuf + sizeof ( SK_I32 ) , pLen ,
( ( SK_U32 ) ( - 1 ) ) , NetIndex ) ;
SK_PNMI_STORE_U32 ( pBuf , ReturnCode ) ;
* pLen = * pLen + sizeof ( SK_I32 ) ;
break ;
case SK_SET_SINGLE_VAR :
ReturnCode = SkPnmiSetVar ( pAC , IoC , Oid ,
( char * ) pBuf + sizeof ( SK_I32 ) , pLen ,
( ( SK_U32 ) ( - 1 ) ) , NetIndex ) ;
SK_PNMI_STORE_U32 ( pBuf , ReturnCode ) ;
* pLen = * pLen + sizeof ( SK_I32 ) ;
break ;
case SK_GET_FULL_MIB :
ReturnCode = SkPnmiGetStruct ( pAC , IoC , pBuf , pLen , NetIndex ) ;
break ;
case SK_PRESET_FULL_MIB :
ReturnCode = SkPnmiPreSetStruct ( pAC , IoC , pBuf , pLen , NetIndex ) ;
break ;
case SK_SET_FULL_MIB :
ReturnCode = SkPnmiSetStruct ( pAC , IoC , pBuf , pLen , NetIndex ) ;
break ;
default :
break ;
}
return ( ReturnCode ) ;
} /* SkGeIocGen */