/*****************************************************************************
 *
 * Name:	skgepnmi.c
 * Project:	Gigabit Ethernet Adapters, PNMI-Module
 * Version:	$Revision: 2.26 $
 * Date:	$Date: 2005/12/21 09:53:21 $
 * Purpose:	Private Network Management Interface
 *
 ****************************************************************************/

/******************************************************************************
 *
 *	LICENSE:
 *	(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.
 *	/LICENSE
 *
 ******************************************************************************/
#include <config.h>

#ifdef CONFIG_SK98

#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
static const char SysKonnectFileId[] =
	"@(#) $Id: skgepnmi.c,v 2.26 2005/12/21 09:53:21 tschilli Exp $ (C) Marvell.";
#endif

#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/sky2le.h"
#include "h/skgeinit.h"
#include "h/skdrv2nd.h"
#include "h/skgepnm2.h"
#ifdef SK_POWER_MGMT
#include "h/skgepmgt.h"
#endif /* SK_POWER_MGMT */

/* defines *******************************************************************/

#ifndef DEBUG
#define PNMI_STATIC	static
#else	/* DEBUG */
#define PNMI_STATIC
#endif /* DEBUG */

/*
 * 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 void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
PNMI_STATIC void VctGetResults(SK_AC *, SK_IOC, 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_EVPARA		EventParam;	/* Event struct for timer event */

	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;

			/* Initialize DSP variables for Vct() to 0xff => Never written! */
			pAC->GIni.GP[PortIndex].PCableLen = 0xff;
			pAC->Pnmi.VctBackup[PortIndex].CableLen = 0xff;
		}

#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);
		}

		/* Get PCI bus speed. */
		if (pAC->GIni.GIPciClock66) {

			pAC->Pnmi.PciBusSpeed = 66;
		}
		else {
			pAC->Pnmi.PciBusSpeed = 33;
		}

		/* Get PCI bus width. */
		if (pAC->GIni.GIPciSlot64) {

			pAC->Pnmi.PciBusWidth = 64;
		}
		else {
			pAC->Pnmi.PciBusWidth = 32;
		}

		/* 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;

		case CHIP_ID_YUKON_LITE:
			pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON_LITE;
			break;

		case CHIP_ID_YUKON_LP:
			pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON_LP;
			break;

		case CHIP_ID_YUKON_XL:
			pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON_XL;
			break;

		case CHIP_ID_YUKON_EC:
			pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON_EC;
			break;

		case CHIP_ID_YUKON_FE:
			pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON_FE;
			break;

		default:
			break;
		}

		/* Get PMD and Device Type. */
		switch (pAC->GIni.GIPmdTyp) {

		case 'S':
			pAC->Pnmi.PMD = 3;
			pAC->Pnmi.DeviceType = 0x00020001;
			break;

		case 'L':
			pAC->Pnmi.PMD = 2;
			pAC->Pnmi.DeviceType = 0x00020003;
			break;

		case 'C':
			pAC->Pnmi.PMD = 4;
			pAC->Pnmi.DeviceType = 0x00020005;
			break;

		case 'T':
			pAC->Pnmi.PMD = 5;
			pAC->Pnmi.DeviceType = 0x00020007;
			break;

		default :
			pAC->Pnmi.PMD = 1;
			pAC->Pnmi.DeviceType = 0;
			break;
		}

		if (pAC->GIni.GIMacsFound > 1) {

			pAC->Pnmi.DeviceType++;
		}

		/* Get connector type. */
		switch (pAC->GIni.GIConTyp) {

		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,
			SK_PNMI_EVT_TIMER_CHECK, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
			EventParam);
		break;

	default:
		break; /* Nothing to do. */
	}

	return (0);
}

/*****************************************************************************
 *
 * SkPnmiGetVar - Retrieves the value of a single OID
 *
 * Description:
 *	Calls a general sub-function for all this stuff. If the instance
 *	-1 is passed, the values of all instances are returned in an
 *	array of values.
 *
 * Returns:
 *	SK_PNMI_ERR_OK           The request was successfully performed
 *	SK_PNMI_ERR_GENERAL      A general severe internal error occured
 *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to take
 *	                         the data.
 *	SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown
 *	SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 *                           exist (e.g. port instance 3 on a two port
 *	                         adapter.
 */
int SkPnmiGetVar(
SK_AC *pAC,		/* Pointer to adapter context */
SK_IOC IoC,		/* IO context handle */
SK_U32 Id,		/* Object ID that is to be processed */
void *pBuf,		/* Buffer to which 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
 *	new value. This is usefull to check if a set might be successfull.
 *	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 32bit value is
 *	                         needed, but a 16 bit value was passed).
 *	SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 *	                         value range.
 *	SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 *	SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown.
 *	SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 *                           exist (e.g. port instance 3 on a two port
 *	                         adapter.
 */
int SkPnmiPreSetVar(
SK_AC *pAC,		/* Pointer to adapter context */
SK_IOC IoC,		/* IO context handle */
SK_U32 Id,		/* Object ID that is to be processed */
void *pBuf,		/* Buffer 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
 *	new value. This is usefull to check if a set might be successfull.
 *	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 32bit value is
 *	                         needed, but a 16 bit value was passed).
 *	SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 *	                         value range.
 *	SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 *	SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown.
 *	SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 *                           exist (e.g. port instance 3 on a two port
 *	                         adapter.
 */
int SkPnmiSetVar(
SK_AC *pAC,		/* Pointer to adapter context */
SK_IOC IoC,		/* IO context handle */
SK_U32 Id,		/* Object ID that is to be processed */
void *pBuf,		/* Buffer 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 statistics. */
	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.
	 * Please read comment in Vpd().
	 */
	if (pAC->Pnmi.VpdKeyReadError == SK_FALSE) {
		Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
		if (Ret != SK_PNMI_ERR_OK) {

			pAC->Pnmi.MacUpdatedFlag --;
			pAC->Pnmi.RlmtUpdatedFlag --;
			pAC->Pnmi.SirqUpdatedFlag --;

			SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
			SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
			*pLen = SK_PNMI_MIN_STRUCT_SIZE;
			return (SK_PNMI_ERR_GENERAL);
		}
	}

	/* Retrieve values. */
	SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);

	for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {

		InstanceNo = IdTable[TableIndex].InstanceNo;
		for (InstanceCnt = 1; InstanceCnt <= InstanceNo; InstanceCnt ++) {

			DstOffset = IdTable[TableIndex].Offset +
				(InstanceCnt - 1) *
				IdTable[TableIndex].StructSize;

			/*
			 * For the VPD the instance is not an index number
			 * but the key itself. Determin with the instance
			 * counter the VPD key to be used.
			 */
			if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
				IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
				IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
				IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {

				SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
			}
			else {
				Instance = (SK_U32)InstanceCnt;
			}

			TmpLen = *pLen - DstOffset;
			Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
				IdTable[TableIndex].Id, (char *)pBuf +
				DstOffset, &TmpLen, Instance, TableIndex, NetIndex);

			/*
			 * An unknown instance error means that we reached
			 * the last instance of that variable. Proceed with
			 * the next OID in the table and ignore the return
			 * code.
			 */
			if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {

                break;
			}

			if (Ret != SK_PNMI_ERR_OK) {

				pAC->Pnmi.MacUpdatedFlag --;
				pAC->Pnmi.RlmtUpdatedFlag --;
				pAC->Pnmi.SirqUpdatedFlag --;

				SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
				SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
				*pLen = SK_PNMI_MIN_STRUCT_SIZE;
				return (Ret);
			}
		}
	}

	pAC->Pnmi.MacUpdatedFlag --;
	pAC->Pnmi.RlmtUpdatedFlag --;
	pAC->Pnmi.SirqUpdatedFlag --;

	*pLen = SK_PNMI_STRUCT_SIZE;
	SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
	SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
	return (SK_PNMI_ERR_OK);
}

/*****************************************************************************
 *
 * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
 *
 * Description:
 *	Calls a general sub-function for all this set stuff. The preset does
 *	the same as a set, but returns just before finally setting the
 *	new value. This is usefull to check if a set might be successfull.
 *	The sub-function runs through the IdTable, checks which OIDs are able
 *	to set, and calls the handler function of the OID to perform the
 *	preset. The return value of the function will also be stored in
 *	SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
 *	SK_PNMI_MIN_STRUCT_SIZE.
 *
 * Returns:
 *	SK_PNMI_ERR_OK           The request was successfully performed.
 *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 *	                         the correct data (e.g. a 32bit value is
 *	                         needed, but a 16 bit value was passed).
 *	SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 *	                         value range.
 */
int SkPnmiPreSetStruct(
SK_AC *pAC,		/* Pointer to adapter context */
SK_IOC IoC,		/* IO context handle */
void *pBuf,		/* Buffer which contains the data to be set */
unsigned int *pLen,	/* Length of buffer */
SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode 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 32bit value is
 *	                         needed, but a 16 bit value was passed).
 *	SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 *	                         value range.
 */
int SkPnmiSetStruct(
SK_AC *pAC,		/* Pointer to adapter context */
SK_IOC IoC,		/* IO context handle */
void *pBuf,		/* Buffer which contains the data to be set */
unsigned int *pLen,	/* Length of buffer */
SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode 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;
	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_U32		RetCode;

#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: 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 (SK_PNMI_EVT_TIMER_CHECK)
		 *   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,
			SK_PNMI_EVT_TIMER_CHECK, 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 /* DEBUG */

		PhysPortIndex = (unsigned int)Param.Para64;

		/* Update XMAC statistic to get fresh values. */
		if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
			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 inactive. */
		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) { /* SingleNet mode. */
		pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
        }
        else { /* DualNet mode. */
		pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
        }
        break;

    case SK_PNMI_EVT_VCT_RESET:
		PhysPortIndex = Param.Para32[0];

		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],
					SK_PNMI_VCT_TIMER_CHECK, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);

				break;
			}

			VctGetResults(pAC, IoC, PhysPortIndex);

			EventParam.Para32[0] = PhysPortIndex;
			EventParam.Para32[1] = -1;
			SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, EventParam);

			/* 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 32bit value is
 *	                         needed, but a 16 bit value was passed).
 *	SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 *	                         value range.
 *	SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 *	SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 *                           exist (e.g. port instance 3 on a two port
 *	                         adapter.
 */
PNMI_STATIC int OidStruct(
SK_AC *pAC,		/* Pointer to adapter context */
SK_IOC IoC,		/* IO context handle */
int Action,		/* GET/PRESET/SET action */
SK_U32 Id,		/* Object ID that is to be processed */
char *pBuf,		/* Buffer 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 32bit value is
 *	                         needed, but a 16 bit value was passed).
 *	SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 *	                         value range.
 *	SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 *	SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 *                           exist (e.g. port instance 3 on a two port
 *	                         adapter.
 */
PNMI_STATIC int Perform(
SK_AC *pAC,		/* Pointer to adapter context */
SK_IOC IoC,		/* IO context handle */
int Action,		/* GET/PRESET/SET action */
SK_U32 Id,		/* Object ID that is to be processed */
char *pBuf,		/* Buffer 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 32bit value is
 *	                         needed, but a 16 bit value was passed).
 *	SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 *                           exist (e.g. port instance 3 on a two port
 *	                         adapter.
 */
PNMI_STATIC int Mac8023Stat(
SK_AC *pAC,		/* Pointer to adapter context */
SK_IOC IoC,		/* IO context handle */
int Action,		/* GET/PRESET/SET action */
SK_U32 Id,		/* Object ID that is to be processed */
char *pBuf,		/* Buffer 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 32 bits are required for OID. */
		if (*pLen < sizeof(SK_U32)) {
			/*
			 * 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 32 bit 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 32bit value is
 *	                         needed, but a 16 bit value was passed).
 *	SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 *                           exist (e.g. port instance 3 on a two port
 *	                         adapter.
 */
PNMI_STATIC int MacPrivateStat(
SK_AC *pAC,		/* Pointer to adapter context */
SK_IOC IoC,		/* IO context handle */
int Action,		/* GET/PRESET/SET action */
SK_U32 Id,		/* Object ID that is to be processed */
char *pBuf,		/* Buffer 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) { /* DualNet 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 32bit value is
 *	                         needed, but a 16 bit value was passed).
 *	SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 *	                         value range.
 *	SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 *	SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 *                           exist (e.g. port instance 3 on a two port
 *	                         adapter.
 */
PNMI_STATIC int Addr(
SK_AC *pAC,		/* Pointer to adapter context */
SK_IOC IoC,		/* IO context handle */
int Action,		/* GET/PRESET/SET action */
SK_U32 Id,		/* Object ID that is to be processed */
char *pBuf,		/* Buffer 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) { /* DualNet mode. */
		LogPortMax--;
	}

	if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried. */
		/* Check instance range. */
		if ((Instance < 1) || (Instance > LogPortMax)) {

			*pLen = 0;
			return (SK_PNMI_ERR_UNKNOWN_INST);
		}
		LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
		Limit = LogPortIndex + 1;
	}
	else { /* Instance == (SK_U32)(-1), get all Instances of that OID. */

		LogPortIndex = 0;
		Limit = LogPortMax;
	}

	/* Perform action. */
	if (Action == SK_PNMI_GET) {

		/* Check length. */
		if (*pLen < (Limit - LogPortIndex) * 6) {

			*pLen = (Limit - LogPortIndex) * 6;
			return (SK_PNMI_ERR_TOO_SHORT);
		}

		/* Get value. */
		for (; LogPortIndex < Limit; LogPortIndex ++) {

			switch (Id) {

			case OID_SKGE_PHYS_CUR_ADDR:
				if (LogPortIndex == 0) {
					CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
				}
				else {
					PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);

					CopyMac(pBuf + Offset,
						&pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
				}
				Offset += 6;
				break;

			case OID_SKGE_PHYS_FAC_ADDR:
				if (LogPortIndex == 0) {
					CopyMac(pBuf + Offset,
						&pAC->Addr.Net[NetIndex].PermanentMacAddress);
				}
				else {
					PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);

					CopyMac(pBuf + Offset,
						&pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
				}
				Offset += 6;
				break;

			default:
				SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008, SK_PNMI_ERR008MSG);

				*pLen = 0;
				return (SK_PNMI_ERR_GENERAL);
			}
		}

		*pLen = Offset;
	}
	else {
		/*
		 * The logical MAC address may not be changed,
		 * only the physical ones.
		 */
		if (Id == OID_SKGE_PHYS_FAC_ADDR) {

			*pLen = 0;
			return (SK_PNMI_ERR_READ_ONLY);
		}

		/* Only the current address may be changed. */
		if (Id != OID_SKGE_PHYS_CUR_ADDR) {

			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009, SK_PNMI_ERR009MSG);

			*pLen = 0;
			return (SK_PNMI_ERR_GENERAL);
		}

		/* Check length. */
		if (*pLen < (Limit - LogPortIndex) * 6) {

			*pLen = (Limit - LogPortIndex) * 6;
			return (SK_PNMI_ERR_TOO_SHORT);
		}
		if (*pLen > (Limit - LogPortIndex) * 6) {

			*pLen = 0;
			return (SK_PNMI_ERR_BAD_VALUE);
		}

		/* Check action. */
		if (Action == SK_PNMI_PRESET) {

			*pLen = 0;
			return (SK_PNMI_ERR_OK);
		}

		/* Set OID_SKGE_MAC_CUR_ADDR.  */
		for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {

			/*
			 * A set to virtual port and set of broadcast
			 * address will be ignored.
			 */
			if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
				"\xff\xff\xff\xff\xff\xff", 6) == 0) {
				continue;
			}

			PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);

			Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
				(SK_MAC_ADDR *)(pBuf + Offset),
				(LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
				SK_ADDR_PHYSICAL_ADDRESS));
			if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {

				return (SK_PNMI_ERR_GENERAL);
			}
		}
		*pLen = Offset;
	}

	return (SK_PNMI_ERR_OK);
}

/*****************************************************************************
 *
 * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
 *
 * Description:
 *	Retrieves the statistic values of the CSUM module. The CSUM data
 *	structure must be available in the SK_AC even if the CSUM module
 *	is not included, because PNMI reads the statistic data from the
 *	CSUM part of SK_AC directly.
 *
 * Returns:
 *	SK_PNMI_ERR_OK           The request was successfully performed.
 *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 *	                         the correct data (e.g. a 32bit value is
 *	                         needed, but a 16 bit value was passed).
 *	SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 *                           exist (e.g. port instance 3 on a two port
 *	                         adapter.
 */
PNMI_STATIC int CsumStat(
SK_AC *pAC,		/* Pointer to adapter context */
SK_IOC IoC,		/* IO context handle */
int Action,		/* GET/PRESET/SET action */
SK_U32 Id,		/* Object ID that is to be processed */
char *pBuf,		/* Buffer 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 32bit value is
 *	                         needed, but a 16 bit value was passed).
 *	SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 *                           exist (e.g. port instance 3 on a two port
 *	                         adapter.
 */
PNMI_STATIC int SensorStat(
SK_AC *pAC,		/* Pointer to adapter context */
SK_IOC IoC,		/* IO context handle */
int Action,		/* GET/PRESET/SET action */
SK_U32 Id,		/* Object ID that is to be processed */
char *pBuf,		/* Buffer 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 ++;
			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 ++;
			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 ++;
			break;

		case OID_SKGE_SENSOR_WAR_CTS:
			Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
			SK_PNMI_STORE_U64(pBuf + Offset, Val64);
			Offset += sizeof(SK_U64);
			break;

		case OID_SKGE_SENSOR_ERR_CTS:
			Val64 = pAC->I2c.SenTable[Index].SenErrCts;
			SK_PNMI_STORE_U64(pBuf + Offset, Val64);
			Offset += sizeof(SK_U64);
			break;

		case OID_SKGE_SENSOR_WAR_TIME:
			Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
				SenBegWarnTS);
			SK_PNMI_STORE_U64(pBuf + Offset, Val64);
			Offset += sizeof(SK_U64);
			break;

		case OID_SKGE_SENSOR_ERR_TIME:
			Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
				SenBegErrTS);
			SK_PNMI_STORE_U64(pBuf + Offset, Val64);
			Offset += sizeof(SK_U64);
			break;

		default:
			SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
				("SensorStat: Unknown OID should be handled before"));

			return (SK_PNMI_ERR_GENERAL);
		}
	}

	/* Store used buffer space. */
	*pLen = Offset;

	return (SK_PNMI_ERR_OK);
}

/*****************************************************************************
 *
 * Vpd - OID handler function of OID_SKGE_VPD_XXX
 *
 * Description:
 *	Get/preset/set of VPD data. As instance the name of a VPD key
 *	can be passed. The Instance parameter is a SK_U32 and can be
 *	used as a string buffer for the VPD key, because their maximum
 *	length is 4 byte.
 *
 * Returns:
 *	SK_PNMI_ERR_OK           The request was successfully performed.
 *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 *	                         the correct data (e.g. a 32bit value is
 *	                         needed, but a 16 bit value was passed).
 *	SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 *	                         value range.
 *	SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 *	SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 *                           exist (e.g. port instance 3 on a two port
 *	                         adapter.
 */
PNMI_STATIC int Vpd(
SK_AC *pAC,		/* Pointer to adapter context */
SK_IOC IoC,		/* IO context handle */
int Action,		/* GET/PRESET/SET action */
SK_U32 Id,		/* Object ID that is to be processed */
char *pBuf,		/* Buffer 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;

	/*
	 * VpdKeyReadError will be set in GetVpdKeyArr() if an error occurs.
	 * Due to the fact that some drivers use SkPnmiGetStruct() to retrieve
	 * all statistical data, an error in GetVpdKeyArr() will generate a PNMI
	 * error and terminate SkPnmiGetStruct() without filling in statistical
	 * data into the PNMI struct. In this case the driver will get no values
	 * for statistical purposes (netstat, ifconfig etc.). GetVpdKeyArr() is
	 * the first function to be called in SkPnmiGetStruct(), so any error
	 * will terminate SkPnmiGetStruct() immediately. Hence, VpdKeyReadError will
	 * be set during the first call to GetVpdKeyArr() to make successful calls
	 * to SkPnmiGetStruct() possible. But there is another point to consider:
	 * When filling in the statistical data into the PNMI struct, the VPD
	 * handler Vpd() will also be called. If GetVpdKeyArr() in Vpd() would
	 * return with SK_PNMI_ERR_GENERAL, SkPnmiGetStruct() would fail again.
	 * For this reason VpdKeyReadError is checked here and, if set, Vpd()
	 * will return without doing anything and the return value SK_PNMI_ERR_OK.
	 * Therefore SkPnmiGetStruct() is able to continue and fill in all other
	 * statistical data.
	 */
	if (pAC->Pnmi.VpdKeyReadError == SK_TRUE) {
		return (SK_PNMI_ERR_OK);
	}

	/* 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_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
					(SK_PNMI_ERR017MSG));

				*pLen = 0;
				return (SK_PNMI_ERR_GENERAL);
			}
			if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {

				SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
					(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_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
						(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_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
						(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_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
				(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_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
				(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_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
					(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_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
					(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_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
					(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_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
					(SK_PNMI_ERR028MSG));

				*pLen = 0;
				return (SK_PNMI_ERR_GENERAL);
			}
			break;

		default:
			*pLen = 0;
			return (SK_PNMI_ERR_BAD_VALUE);
		}
	}

	return (SK_PNMI_ERR_OK);
}

/*****************************************************************************
 *
 * General - OID handler function of various single instance OIDs
 *
 * Description:
 *	The code is simple. No description necessary.
 *
 * Returns:
 *	SK_PNMI_ERR_OK           The request was successfully performed.
 *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 *	                         the correct data (e.g. a 32bit value is
 *	                         needed, but a 16 bit value was passed).
 *	SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 *                           exist (e.g. port instance 3 on a two port
 *	                         adapter.
 */
PNMI_STATIC int General(
SK_AC *pAC,		/* Pointer to adapter context */
SK_IOC IoC,		/* IO context handle */
int Action,		/* GET/PRESET/SET action */
SK_U32 Id,		/* Object ID that is to be processed */
char *pBuf,		/* Buffer 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		Val64RxRunt = 0;
	SK_U64		Val64RxFcs = 0;
	SK_U64		Val64TxHwErrs = 0;
	SK_BOOL		Is64BitReq = SK_FALSE;
	char		Buf[256];
	int			MacType;

	/* Check instance. We only handle single instance variables. */
	if (Instance != (SK_U32)(-1) && Instance != 1) {

		*pLen = 0;
		return (SK_PNMI_ERR_UNKNOWN_INST);
	}

	/* Check action. We only allow get requests. */
	if (Action != SK_PNMI_GET) {

		*pLen = 0;
		return (SK_PNMI_ERR_READ_ONLY);
	}

	MacType = pAC->GIni.GIMacType;

	/* Check length for the various supported OIDs. */
	switch (Id) {

	case OID_GEN_XMIT_ERROR:
	case OID_GEN_RCV_ERROR:
	case OID_GEN_RCV_NO_BUFFER:
#ifndef SK_NDIS_64BIT_CTR
		if (*pLen < sizeof(SK_U32)) {
			*pLen = sizeof(SK_U32);
			return (SK_PNMI_ERR_TOO_SHORT);
		}

#else /* SK_NDIS_64BIT_CTR */

		/* For compatibility, at least 32bit are required for OID. */
		if (*pLen < sizeof(SK_U32)) {
			/*
			 * Indicate handling for 64bit values,
			 * if insufficient space is provided.
			 */
			*pLen = sizeof(SK_U64);
			return (SK_PNMI_ERR_TOO_SHORT);
		}

		Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
#endif /* SK_NDIS_64BIT_CTR */
		break;

	case OID_SKGE_PORT_NUMBER:
	case OID_SKGE_DEVICE_TYPE:
	case OID_SKGE_RESULT:
	case OID_SKGE_RLMT_MONITOR_NUMBER:
	case OID_GEN_TRANSMIT_QUEUE_LENGTH:
	case OID_SKGE_TRAP_NUMBER:
	case OID_SKGE_MDB_VERSION:
	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 statistics. */
	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_TOO_LONG, NetIndex) +
				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);


			/*
			* In some cases the runt and fcs counters are incremented when collisions
			* occur. We have to correct those counters here.
			*/
			Val64RxRunt = GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex);
			Val64RxFcs = GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex);

			if (Val64RxRunt > Val64RxFcs) {
				Val64RxRunt -= Val64RxFcs;
				Val64RxHwErrs += Val64RxRunt;
			}
			else {
				Val64RxFcs -= Val64RxRunt;
				Val64RxHwErrs += Val64RxFcs;
			}
			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; Index ++) {

			Val32 = (SK_U32)IdTable[Index].Id;
			SK_PNMI_STORE_U32(pBuf + Offset, Val32);
			Offset += sizeof(SK_U32);
		}
		*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_ERR053, 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_ERR054, 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_ERR055, 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_ERR056, 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.
		 * Please read comment in Vpd().
		 */
		if (pAC->Pnmi.VpdKeyReadError == SK_TRUE) {
			return (SK_PNMI_ERR_OK);
		}

		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:
		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)('0' | ((Val8 >> 4) & 0x0f));
		pBuf[3] = '.';
		pBuf[4] = (char)('0' | (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:
		/* 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) {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
			}
			/* SingleNet mode. */
			else {
				Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
					pAC->Pnmi.BufPort[1].TxSwQueueLen;
			}
		}
		else {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
			}
			/* SingleNet 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) {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
			}
			/* SingleNet mode. */
			else {
				Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
					pAC->Pnmi.BufPort[1].TxSwQueueMax;
			}
		}
		else {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
			}
			/* SingleNet 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) {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
			}
			/* SingleNet mode. */
			else {
				Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
					pAC->Pnmi.BufPort[1].TxRetryCts;
			}
		}
		else {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
			}
			/* SingleNet 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) {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
			}
			/* SingleNet mode. */
			else {
				Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
					pAC->Pnmi.BufPort[1].RxIntrCts;
			}
		}
		else {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
			}
			/* SingleNet 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) {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
			}
			/* SingleNet mode. */
			else {
				Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
					pAC->Pnmi.BufPort[1].TxIntrCts;
			}
		}
		else {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
			}
			/* SingleNet 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) {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
			}
			/* SingleNet mode. */
			else {
				Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
					pAC->Pnmi.BufPort[1].RxNoBufCts;
			}
		}
		else {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
			}
			/* SingleNet 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) {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
			}
			/* SingleNet mode. */
			else {
				Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
					pAC->Pnmi.BufPort[1].TxNoBufCts;
			}
		}
		else {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
			}
			/* SingleNet 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) {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
			}
			/* SingleNet mode. */
			else {
				Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
					pAC->Pnmi.BufPort[1].TxUsedDescrNo;
			}
		}
		else {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
			}
			/* SingleNet 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) {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
			}
			/* SingleNet mode. */
			else {
				Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
					pAC->Pnmi.BufPort[1].RxDeliveredCts;
			}
		}
		else {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
			}
			/* SingleNet 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) {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
			}
			/* SingleNet mode. */
			else {
				Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
					pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
			}
		}
		else {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
			}
			/* SingleNet 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) {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
			}
			/* SingleNet mode. */
			else {
				Val64 = Val64RxHwErrs +
					pAC->Pnmi.BufPort[0].RxNoBufCts +
					pAC->Pnmi.BufPort[1].RxNoBufCts;
			}
		}
		else {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
			}
			/* SingleNet 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) {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
			}
			/* SingleNet mode. */
			else {
				Val64 = Val64TxHwErrs +
					pAC->Pnmi.BufPort[0].TxNoBufCts +
					pAC->Pnmi.BufPort[1].TxNoBufCts;
			}
		}
		else {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
			}
			/* SingleNet 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) {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
			}
			/* SingleNet mode. */
			else {
				Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
					pAC->Pnmi.BufPort[1].ErrRecoveryCts;
			}
		}
		else {
			/* DualNet mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
			}
			/* SingleNet mode. */
			else {
				Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
					pAC->Pnmi.Port[1].ErrRecoveryCts;
			}
		}
		SK_PNMI_STORE_U64(pBuf, Val64);
		*pLen = sizeof(SK_U64);
		break;

	case OID_SKGE_SYSUPTIME:
		Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
		Val64 -= pAC->Pnmi.StartUpTime;
		SK_PNMI_STORE_U64(pBuf, Val64);
		*pLen = sizeof(SK_U64);
		break;

	case OID_SKGE_MDB_VERSION:
		Val32 = SK_PNMI_MDB_VERSION;
		SK_PNMI_STORE_U32(pBuf, Val32);
		*pLen = sizeof(SK_U32);
		break;

	case OID_GEN_RCV_ERROR:
		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
		if (MacType == SK_MAC_XMAC) {
			Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
		}
		else {
			Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
		}

		/*
		 * By default 32bit values are evaluated.
		 */
		if (!Is64BitReq) {
			Val32 = (SK_U32)Val64;
			SK_PNMI_STORE_U32(pBuf, Val32);
			*pLen = sizeof(SK_U32);
		}
		else {
			SK_PNMI_STORE_U64(pBuf, Val64);
			*pLen = sizeof(SK_U64);
		}
		break;

	case OID_GEN_XMIT_ERROR:
		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
		if (MacType == SK_MAC_XMAC) {
			Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
		}
		else {
			Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
		}

		/*
		 * By default 32bit values are evaluated.
		 */
		if (!Is64BitReq) {
			Val32 = (SK_U32)Val64;
			SK_PNMI_STORE_U32(pBuf, Val32);
			*pLen = sizeof(SK_U32);
		}
		else {
			SK_PNMI_STORE_U64(pBuf, Val64);
			*pLen = sizeof(SK_U64);
		}
		break;

	case OID_GEN_RCV_NO_BUFFER:
		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
		if (MacType == SK_MAC_XMAC) {
			Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts +
				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex);

		}
		else {
			Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts +
				GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex);
		}

		/*
		 * By default 32bit values are evaluated.
		 */
		if (!Is64BitReq) {
			Val32 = (SK_U32)Val64;
			SK_PNMI_STORE_U32(pBuf, Val32);
			*pLen = sizeof(SK_U32);
		}
		else {
			SK_PNMI_STORE_U64(pBuf, Val64);
			*pLen = sizeof(SK_U64);
		}
		break;

	case OID_GEN_TRANSMIT_QUEUE_LENGTH:
		Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
		SK_PNMI_STORE_U32(pBuf, Val32);
		*pLen = sizeof(SK_U32);
		break;

	default:
		SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034, SK_PNMI_ERR034MSG);

		*pLen = 0;
		return (SK_PNMI_ERR_GENERAL);
	}

	if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
		Id == OID_SKGE_TX_HW_ERROR_CTS ||
		Id == OID_SKGE_IN_ERRORS_CTS ||
		Id == OID_SKGE_OUT_ERROR_CTS ||
		Id == OID_GEN_XMIT_ERROR ||
		Id == OID_GEN_RCV_ERROR) {

		pAC->Pnmi.MacUpdatedFlag --;
	}

	return (SK_PNMI_ERR_OK);
}

/*****************************************************************************
 *
 * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
 *
 * Description:
 *	Get/Presets/Sets the RLMT OIDs.
 *
 * Returns:
 *	SK_PNMI_ERR_OK           The request was successfully performed.
 *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 *	                         the correct data (e.g. a 32bit value is
 *	                         needed, but a 16 bit value was passed).
 *	SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 *	                         value range.
 *	SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 *	SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 *                           exist (e.g. port instance 3 on a two port
 *	                         adapter.
 */
PNMI_STATIC int Rlmt(
SK_AC *pAC,		/* Pointer to adapter context */
SK_IOC IoC,		/* IO context handle */
int Action,		/* GET/PRESET/SET action */
SK_U32 Id,		/* Object ID that is to be processed */
char *pBuf,		/* Buffer 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:
			/* PRESET/SET action makes no sense in Dual Net mode. */
			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
				break;
			}

			/* 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);
			}
			/* The PRESET ends here. */
			if (Action == SK_PNMI_PRESET) {

				*pLen = 0;
				return (SK_PNMI_ERR_OK);
			}
			/*
			 * Store the new threshold, which will be taken
			 * on the next timer event.
			 */
			SK_PNMI_READ_U64(pBuf, Val64);
			pAC->Pnmi.RlmtChangeThreshold = Val64;
			break;

		default:
			/* The other OIDs are not be able for set. */
			*pLen = 0;
			return (SK_PNMI_ERR_READ_ONLY);
		}
	}

	return (SK_PNMI_ERR_OK);
}

/*****************************************************************************
 *
 * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
 *
 * Description:
 *	Performs get requests on multiple instance variables.
 *
 * Returns:
 *	SK_PNMI_ERR_OK           The request was successfully performed.
 *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 *	                         the correct data (e.g. a 32bit value is
 *	                         needed, but a 16 bit value was passed).
 *	SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 *                           exist (e.g. port instance 3 on a two port
 *	                         adapter.
 */
PNMI_STATIC int RlmtStat(
SK_AC *pAC,		/* Pointer to adapter context */
SK_IOC IoC,		/* IO context handle */
int Action,		/* GET/PRESET/SET action */
SK_U32 Id,		/* Object ID that is to be processed */
char *pBuf,		/* Buffer 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);
		}

		/* SingleNet mode. */
		PhysPortIndex = Instance - 1;

		/* DualNet mode. */
		if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
			PhysPortIndex = NetIndex;
		}

		/* Both net modes. */
		Limit = PhysPortIndex + 1;
	}
	else {
		/* SingleNet mode. */
		PhysPortIndex = 0;
		Limit = PhysPortMax;

		/* DualNet mode. */
		if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
			PhysPortIndex = NetIndex;
			Limit = PhysPortIndex + 1;
		}
	}

	/* Currently only GET requests are allowed. */
	if (Action != SK_PNMI_GET) {

		*pLen = 0;
		return (SK_PNMI_ERR_READ_ONLY);
	}

	/* Check if the buffer length is large enough. */
	switch (Id) {

	case OID_SKGE_RLMT_PORT_INDEX:
	case OID_SKGE_RLMT_STATUS:
		if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {

			*pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
			return (SK_PNMI_ERR_TOO_SHORT);
		}
		break;

	case OID_SKGE_RLMT_TX_HELLO_CTS:
	case OID_SKGE_RLMT_RX_HELLO_CTS:
	case OID_SKGE_RLMT_TX_SP_REQ_CTS:
	case OID_SKGE_RLMT_RX_SP_CTS:
		if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {

			*pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
			return (SK_PNMI_ERR_TOO_SHORT);
		}
		break;

	default:
		SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039, SK_PNMI_ERR039MSG);

		*pLen = 0;
		return (SK_PNMI_ERR_GENERAL);

	}

	/*
	 * Update statistic and increment semaphores to indicate that
	 * an update was already done.
	 */
	if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {

		*pLen = 0;
		return (Ret);
	}
	pAC->Pnmi.RlmtUpdatedFlag ++;

	/* Get value. */
	Offset = 0;
	for (; PhysPortIndex < Limit; PhysPortIndex ++) {

		switch (Id) {

		case OID_SKGE_RLMT_PORT_INDEX:
			Val32 = PhysPortIndex;
			SK_PNMI_STORE_U32(pBuf + Offset, Val32);
			Offset += sizeof(SK_U32);
			break;

		case OID_SKGE_RLMT_STATUS:
			if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
				SK_RLMT_PS_INIT ||
				pAC->Rlmt.Port[PhysPortIndex].PortState ==
				SK_RLMT_PS_DOWN) {

				Val32 = SK_PNMI_RLMT_STATUS_ERROR;
			}
			else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {

				Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
			}
			else {
				Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
			}
			SK_PNMI_STORE_U32(pBuf + Offset, Val32);
			Offset += sizeof(SK_U32);
			break;

		case OID_SKGE_RLMT_TX_HELLO_CTS:
			Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
			SK_PNMI_STORE_U64(pBuf + Offset, Val64);
			Offset += sizeof(SK_U64);
			break;

		case OID_SKGE_RLMT_RX_HELLO_CTS:
			Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
			SK_PNMI_STORE_U64(pBuf + Offset, Val64);
			Offset += sizeof(SK_U64);
			break;

		case OID_SKGE_RLMT_TX_SP_REQ_CTS:
			Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
			SK_PNMI_STORE_U64(pBuf + Offset, Val64);
			Offset += sizeof(SK_U64);
			break;

		case OID_SKGE_RLMT_RX_SP_CTS:
			Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
			SK_PNMI_STORE_U64(pBuf + Offset, Val64);
			Offset += sizeof(SK_U64);
			break;

		default:
			SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
				("RlmtStat: Unknown OID should be errored before"));

			pAC->Pnmi.RlmtUpdatedFlag --;
			*pLen = 0;
			return (SK_PNMI_ERR_GENERAL);
		}
	}
	*pLen = Offset;

	pAC->Pnmi.RlmtUpdatedFlag --;

	return (SK_PNMI_ERR_OK);
}

/*****************************************************************************
 *
 * MacPrivateConf - OID handler function of OIDs concerning the configuration
 *
 * Description:
 *	Get/Presets/Sets the OIDs concerning the configuration.
 *
 * Returns:
 *	SK_PNMI_ERR_OK           The request was successfully performed.
 *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 *	                         the correct data (e.g. a 32bit value is
 *	                         needed, but a 16 bit value was passed).
 *	SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 *	                         value range.
 *	SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 *	SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 *                           exist (e.g. port instance 3 on a two port
 *	                         adapter.
 */
PNMI_STATIC int MacPrivateConf(
SK_AC *pAC,		/* Pointer to adapter context */
SK_IOC IoC,		/* IO context handle */
int Action,		/* GET/PRESET/SET action */
SK_U32 Id,		/* Object ID that is to be processed */
char *pBuf,		/* Buffer 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;
#ifdef SK_PHY_LP_MODE
	SK_U8	CurrentPhyPowerState;
#endif /* SK_PHY_LP_MODE */


	/* 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) { /* DualNet 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:
#ifdef SK_PHY_LP_MODE
		case OID_SKGE_PHY_LP_MODE:
#endif
			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 ++;
				break;

			case OID_SKGE_CONNECTOR:
				*pBufPtr = pAC->Pnmi.Connector;
				Offset ++;
				break;

			case OID_SKGE_PHY_TYPE:
				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
					if (LogPortIndex == 0) {
						continue;
					}
					/* Get value for physical port. */
					PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
					Val32 = pAC->GIni.GP[PhysPortIndex].PhyType;
				}
				else { /* DualNet mode. */

					Val32 = pAC->GIni.GP[NetIndex].PhyType;
				}
				SK_PNMI_STORE_U32(pBufPtr, Val32);
				Offset += sizeof(SK_U32);
				break;

#ifdef SK_PHY_LP_MODE
			case OID_SKGE_PHY_LP_MODE:
				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
					if (LogPortIndex == 0) {
						continue;
					}
					/* Get value for physical port. */
					PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
					*pBufPtr = (SK_U8)pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
				}
				else { /* DualNet mode. */

					*pBufPtr = (SK_U8)pAC->GIni.GP[NetIndex].PPhyPowerState;
				}
				Offset += sizeof(SK_U8);
				break;
#endif

			case OID_SKGE_LINK_CAP:
				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
					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].PLinkCap;
					}
				}
				else { /* DualNet mode. */

					*pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap;
				}
				Offset ++;
				break;

			case OID_SKGE_LINK_MODE:
				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
					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].PLinkModeConf;
					}
				}
				else { /* DualNet mode. */

					*pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf;
				}
				Offset ++;
				break;

			case OID_SKGE_LINK_MODE_STATUS:
				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
					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 { /* DualNet mode. */

					*pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex);
				}
				Offset ++;
				break;

			case OID_SKGE_LINK_STATUS:
				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
					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 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
					}
				}
				else { /* DualNet mode. */

					*pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex);
				}
				Offset ++;
				break;

			case OID_SKGE_FLOWCTRL_CAP:
				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
					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].PFlowCtrlCap;
					}
				}
				else { /* DualNet mode. */

					*pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
				}
				Offset ++;
				break;

			case OID_SKGE_FLOWCTRL_MODE:
				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
					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 { /* DualNet mode. */

					*pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
				}
				Offset ++;
				break;

			case OID_SKGE_FLOWCTRL_STATUS:
				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
					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 { /* DualNet mode. */

					*pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
				}
				Offset ++;
				break;

			case OID_SKGE_PHY_OPERATION_CAP:
				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet Mode. */
					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].PMSCap;
					}
				}
				else { /* DualNet mode. */

					*pBufPtr = pAC->GIni.GP[NetIndex].PMSCap;
				}
				Offset ++;
				break;

			case OID_SKGE_PHY_OPERATION_MODE:
				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
					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 { /* DualNet mode. */

					*pBufPtr = pAC->GIni.GP[NetIndex].PMSMode;
				}
				Offset ++;
				break;

			case OID_SKGE_PHY_OPERATION_STATUS:
				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
					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 ++;
				break;

			case OID_SKGE_SPEED_CAP:
				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
					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].PLinkSpeedCap;
					}
				}
				else { /* DualNet mode. */

					*pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
				}
				Offset ++;
				break;

			case OID_SKGE_SPEED_MODE:
				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
					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 { /* DualNet mode. */

					*pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed;
				}
				Offset ++;
				break;

			case OID_SKGE_SPEED_STATUS:
				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
					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 { /* DualNet mode. */

					*pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
				}
				Offset ++;
				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;

#ifdef SK_PHY_LP_MODE
	case OID_SKGE_PHY_LP_MODE:
		if (*pLen < Limit - LogPortIndex) {

			*pLen = Limit - LogPortIndex;
			return (SK_PNMI_ERR_TOO_SHORT);
		}
		break;
#endif /* SK_PHY_LP_MODE */

	case OID_SKGE_MTU:
		if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) {

			*pLen = (Limit - LogPortIndex) * sizeof(SK_U32);
			return (SK_PNMI_ERR_TOO_SHORT);
		}
		break;

    default:
		*pLen = 0;
		return (SK_PNMI_ERR_READ_ONLY);
	}

	/* Perform PRESET or SET. */
	Offset = 0;
	for (; LogPortIndex < Limit; LogPortIndex ++) {

		Val8 = *(pBuf + Offset);

		switch (Id) {

		case OID_SKGE_LINK_MODE:
			/* Check the value range. */
			if (Val8 == 0) {
				Offset++;
				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 (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
				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);
						}
					} /* for */
				}
				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);
					}
				}
			}
			else { /* DualNet mode. */

				/*
				 * Send an event with the new link mode to
				 * the SIRQ module.
				 */
				EventParam.Para32[0] = NetIndex;
				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++;
			break;

		case OID_SKGE_FLOWCTRL_MODE:
			/* Check the value range. */
			if (Val8 == 0) {
				Offset++;
				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 (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
				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);
					}
				}
			}
			else { /* DualNet mode. */

				/*
				 * Send an event with the new link mode to
				 * the SIRQ module.
				 */
				EventParam.Para32[0] = NetIndex;
				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++;
			break;

		case OID_SKGE_PHY_OPERATION_MODE :
			/* Check the value range. */
			if (Val8 == 0) {
				/* Mode of this port remains unchanged. */
				Offset++;
				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 (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
				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);
					}
				}
			}
			else { /* DualNet mode. */

				/*
				 * Send an event with the new link mode to
				 * the SIRQ module.
				 */
				EventParam.Para32[0] = NetIndex;
				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++;
			break;

		case OID_SKGE_SPEED_MODE:
			/* Check the value range. */
			if (Val8 == 0) {
				Offset++;
				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 (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
				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);
					}
				}
			}
			else { /* DualNet mode. */

				/*
				 * Send an event with the new link mode to
				 * the SIRQ module.
				 */
				EventParam.Para32[0] = NetIndex;
				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++;
			break;

		case OID_SKGE_MTU:
			/* Check the value range. */
			SK_PNMI_READ_U32((pBuf + Offset), Val32);

			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;

#ifdef SK_PHY_LP_MODE
		case OID_SKGE_PHY_LP_MODE:
			/* The PRESET ends here. */
			if (Action == SK_PNMI_PRESET) {

				return (SK_PNMI_ERR_OK);
			}

			if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
				if (LogPortIndex == 0) {
					Offset = 0;
					continue;
				}
			}
			/* Set value for physical port. */
			PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
			CurrentPhyPowerState = pAC->GIni.GP[PhysPortIndex].PPhyPowerState;

			switch (Val8) {
				case PHY_PM_OPERATIONAL_MODE:
					/* If LowPowerMode is active, we can leave it. */
					if (CurrentPhyPowerState) {

						Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex);

						if ((CurrentPhyPowerState == PHY_PM_DEEP_SLEEP) ||
							(CurrentPhyPowerState == PHY_PM_IEEE_POWER_DOWN)) {

							SkDrvInitAdapter(pAC);
						}
						break;
					}
					else {
						*pLen = 0;
						return (SK_PNMI_ERR_GENERAL);
					}
				case PHY_PM_DEEP_SLEEP:
				case PHY_PM_IEEE_POWER_DOWN:
					/* If no LowPowerMode is active, we can enter it. */
					if (!CurrentPhyPowerState) {
						SkDrvDeInitAdapter(pAC);
					}

				case PHY_PM_ENERGY_DETECT:
				case PHY_PM_ENERGY_DETECT_PLUS:
					/* If no LowPowerMode is active, we can enter it. */
					if (!CurrentPhyPowerState) {

						Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf);
						break;
					}
					else {
						*pLen = 0;
						return (SK_PNMI_ERR_GENERAL);
					}
				default:
					*pLen = 0;
					return (SK_PNMI_ERR_BAD_VALUE);
			}
			Offset++;
			break;
#endif /* SK_PHY_LP_MODE */

		default:
            SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
                ("MacPrivateConf: Unknown OID should be handled before set"));

			*pLen = 0;
			return (SK_PNMI_ERR_GENERAL);
		}
	}

	return (SK_PNMI_ERR_OK);
}

/*****************************************************************************
 *
 * Monitor - OID handler function for RLMT_MONITOR_XXX
 *
 * Description:
 *	Because RLMT currently does not support the monitoring of
 *	remote adapter cards, we return always an empty table.
 *
 * Returns:
 *	SK_PNMI_ERR_OK           The request was successfully performed.
 *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 *	                         the correct data (e.g. a 32bit value is
 *	                         needed, but a 16 bit value was passed).
 *	SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 *	                         value range.
 *	SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 *	SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 *                           exist (e.g. port instance 3 on a two port
 *	                         adapter.
 */
PNMI_STATIC int Monitor(
SK_AC *pAC,		/* Pointer to adapter context */
SK_IOC IoC,		/* IO context handle */
int Action,		/* GET/PRESET/SET action */
SK_U32 Id,		/* Object ID that is to be processed */
char *pBuf,		/* Buffer 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;

	/* Not implemented yet. Return always an empty table. */
	Entries = 0;

	/* Calculate instance if wished. */
	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);
		}

		/*
		 * 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;
			}
			break;

		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 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 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 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 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 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 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 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 link speed
			 * than the first one we return 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 link speed used
			 * than the first one we return 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.
 *	But in the decade of auto sensing it is usefull for the user to
 *	know if the mode was negotiated or forced. Therefore we have a
 *	look to the mode, which was last used by the negotiation process.
 *
 * Returns:
 *	The link mode status
 */
PNMI_STATIC SK_U8 CalculateLinkModeStatus(
SK_AC *pAC,			/* Pointer to adapter context */
SK_IOC IoC,			/* IO context handle */
unsigned int PhysPortIndex)	/* Physical port index */
{
	SK_U8	Result;

	/* Get the current mode, which can be full or half duplex. */
	Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;

	/* Check if no valid mode could be found (link is down). */
	if (Result < SK_LMODE_STAT_HALF) {

		Result = SK_LMODE_STAT_UNKNOWN;
	}
	else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
		/*
		 * Auto-negotiation was used to bring up the link. Change
		 * the already found duplex status that it indicates
		 * auto-negotiation was involved.
		 */
		if (Result == SK_LMODE_STAT_HALF) {

			Result = SK_LMODE_STAT_AUTOHALF;
		}
		else if (Result == SK_LMODE_STAT_FULL) {

			Result = SK_LMODE_STAT_AUTOFULL;
		}
	}

	return (Result);
}

/*****************************************************************************
 *
 * GetVpdKeyArr - Obtain an array of VPD keys
 *
 * Description:
 *	Read the VPD keys and build an array of VPD keys, which are
 *	easy to access.
 *
 * Returns:
 *	SK_PNMI_ERR_OK	     Task successfully performed.
 *	SK_PNMI_ERR_GENERAL  Something went wrong.
 */
PNMI_STATIC int GetVpdKeyArr(
SK_AC *pAC,		/* Pointer to adapter context */
SK_IOC IoC,		/* IO context handle */
char *pKeyArr,		/* Ptr KeyArray */
unsigned int KeyArrLen,	/* Length of array in bytes */
unsigned int *pKeyNo)	/* Number of keys */
{
	unsigned int		BufKeysLen = SK_PNMI_VPD_BUFSIZE;
	char			BufKeys[SK_PNMI_VPD_BUFSIZE];
	unsigned int		StartOffset;
	unsigned int		Offset;
	int			Index;
	int			Ret;

	SK_MEMSET(pKeyArr, 0, KeyArrLen);

	/* Get VPD key list. */
	Ret = VpdKeys(pAC, IoC, BufKeys, (int *)&BufKeysLen,
		(int *)pKeyNo);

	if (Ret > 0) {

		SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
			(SK_PNMI_ERR014MSG));

		/* Please read comment in Vpd(). */
		pAC->Pnmi.VpdKeyReadError = SK_TRUE;
		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_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
			(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_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
					   (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)) {

		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) {	/* DualNet mode. */

		PhysPortIndex = NetIndex;

		Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
	}
	else {	/* SingleNet mode. */

		if (LogPortIndex == 0) {

			PhysPortMax = pAC->GIni.GIMacsFound;

			/* Add counter of all active ports. */
			for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
				PhysPortIndex ++) {

				if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {

					Val += GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
				}
			}

			/* Correct value because of port switches. */
			Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
		}
		else {
			/* Get counter value of physical port. */
			PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);

			Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
		}
	}
	return (Val);
}

/*****************************************************************************
 *
 * GetPhysStatVal - Get counter value for physical port
 *
 * Description:
 *	Builds a 64bit counter value. Except for the octet counters
 *	the lower 32bit are counted in hardware and the upper 32bit
 *	in software by monitoring counter overflow interrupts in the
 *	event handler. To grant continous counter values during XMAC
 *	resets (caused by a workaround) we must add a delta value.
 *	The delta was calculated in the event handler when a
 *	SK_PNMI_EVT_XMAC_RESET was received.
 *
 * Returns:
 *	Counter value
 */
PNMI_STATIC SK_U64 GetPhysStatVal(
SK_AC *pAC,					/* Pointer to adapter context */
SK_IOC IoC,					/* IO context handle */
unsigned int PhysPortIndex,	/* Index of the logical Port to be processed */
unsigned int StatIndex)		/* Index to statistic value */
{
	SK_U64	Val = 0;
	SK_U32	LowVal = 0;
	SK_U32	HighVal = 0;
	SK_U16	Word;
	int		MacType;
	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 the link is 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 them in
		 * Receive Error Counter register.
		 */
		if (pPrt->PhyType == SK_PHY_BCOM) {
#ifdef GENESIS
			/* 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];
#endif /* GENESIS */
		}
		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 statistics. */
	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 32bit value is
 *	                         needed, but a 16 bit value was passed).
 *	SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 *                               exist (e.g. port instance 3 on a two port
 *	                         adapter.
 */

PNMI_STATIC int PowerManagement(
SK_AC *pAC,		/* Pointer to adapter context */
SK_IOC IoC,		/* IO context handle */
int Action,		/* Get/PreSet/Set action */
SK_U32 Id,		/* Object ID that is to be processed */
char *pBuf,		/* Buffer to which to mgmt data will be retrieved */
unsigned int *pLen,	/* On call: buffer length. On return: used buffer */
SK_U32 Instance,	/* Instance (1..n) that is to be queried or -1 */
unsigned int TableIndex, /* Index to the Id table */
SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode allways zero */
{

	int i;
	unsigned int HwPortIndex;

	SK_U32	RetCode = SK_PNMI_ERR_GENERAL;

	/* Check instance. We only handle single instance variables. */
	if ((Instance != (SK_U32)(-1))) {

		*pLen = 0;
		return (SK_PNMI_ERR_UNKNOWN_INST);
	}

	/* Get hardware port index */
	HwPortIndex = NetIndex;

    /* 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, HwPortIndex, pBuf, pLen);
			break;

		default:
			RetCode = SK_PNMI_ERR_GENERAL;
			break;
		}

		return (RetCode);
	}

	/* Perform PRESET or SET. */

	/* The POWER module does not support PRESET action. */
	if (Action == SK_PNMI_PRESET) {

		return (SK_PNMI_ERR_OK);
	}

	/* */
	i= HwPortIndex;

	switch (Id) {
	case OID_PNP_SET_POWER:
		/* Dual net mode? */
		for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
			if (RetCode = SkPowerSetPower(pAC, IoC, i, pBuf, pLen)) {
				break;
			}
		}
		break;

	case OID_PNP_ADD_WAKE_UP_PATTERN:
		for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
			if (RetCode = SkPowerAddWakeUpPattern(pAC, IoC, i, pBuf, pLen)) {
				break;
			}
		}
		break;

	case OID_PNP_REMOVE_WAKE_UP_PATTERN:
		for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
			if (RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, i, pBuf, pLen)) {
				break;
			}
		}
		break;

	case OID_PNP_ENABLE_WAKE_UP:
		for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
			if (RetCode = SkPowerSetEnableWakeUp(pAC, IoC, i, pBuf, pLen)) {
				break;
			}
		}
		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 32bit value is
 *	                         needed, but a 16 bit value was passed).
 *	SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 *                           exist (e.g. port instance 3 on a two port
 *	                         adapter.
 */

PNMI_STATIC int 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. */
	if (Action == SK_PNMI_GET) {

		/* Get value. */
		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 for Virtual Cable Tester (VCT)
 *
 * Description:
 *	The code is simple. No description necessary.
 *
 * Returns:
 *	SK_PNMI_ERR_OK           The request was performed successfully.
 *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 *	                         the correct data (e.g. a 32bit value is
 *	                         needed, but a 16 bit value was passed).
 *	SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 *                           exist (e.g. port instance 3 on a two port
 *	                         adapter).
 *	SK_PNMI_ERR_READ_ONLY	 Only the Get action is allowed.
 *
 */

PNMI_STATIC int Vct(
SK_AC *pAC,		/* Pointer to adapter context */
SK_IOC IoC,		/* IO context handle */
int Action,		/* GET/PRESET/SET action */
SK_U32 Id,		/* Object ID that is to be processed */
char *pBuf,		/* Buffer 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_U32		RetCode;
	int			i;
	SK_EVPARA	Para;

	RetCode = SK_PNMI_ERR_GENERAL;

	/* 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))) {
		/*
		 * Get one instance of that OID, so check the instance range:
		 * There is no virtual port with an Instance == 1, so we get
		 * the values from one physical port only.
		 */
		if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
			PhysPortIndex = NetIndex;
		}
		else {
			if ((Instance < 2) || (Instance > LogPortMax)) {
				*pLen = 0;
				return (SK_PNMI_ERR_UNKNOWN_INST);
			}
			PhysPortIndex = Instance - 2;
		}
		Limit = PhysPortIndex + 1;
	}
	else {
		/*
		 * Instance == (SK_U32) (-1), so get all instances of that OID.
		 * There is no virtual port with an Instance == 1, so we get
		 * the values from all physical ports.
		 */
		PhysPortIndex = 0;
		Limit = PhysPortMax;
	}

	/* Check MAC type. */
	if ((Id != OID_SKGE_VCT_CAPABILITIES) &&
		(pAC->GIni.GP[PhysPortIndex].PhyType != SK_PHY_MARV_COPPER)) {
		*pLen = 0;
		return (SK_PNMI_ERR_NOT_SUPPORTED);
	}

	/* 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:
		case OID_SKGE_VCT_CAPABILITIES:
			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++) {

			pPrt = &pAC->GIni.GP[PhysPortIndex];

			switch (Id) {

			case OID_SKGE_VCT_GET:
				if (!pPrt->PHWLinkUp &&
					(pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {

					RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);

					if (RetCode == 0) {

						/* VCT test is finished, so save the data. */
						VctGetResults(pAC, IoC, PhysPortIndex);

						Para.Para32[0] = PhysPortIndex;
						Para.Para32[1] = -1;
						SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);

						/* SkEventDispatcher(pAC, IoC); */
					}
				}

				/* Initialize backup data pointer. */
				pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];

				/* Get all results. */
				CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);

				Offset++;
				*(pBuf + Offset) = pPrt->PCableLen;
				Offset++;
				for (i = 0; i < 4; i++)  {

					SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->MdiPairLen[i]);
					Offset += sizeof(SK_U32);
				}
				for (i = 0; i < 4; i++)  {

					*(pBuf + Offset) = pVctBackupData->MdiPairSts[i];
					Offset++;
				}

				RetCode = SK_PNMI_ERR_OK;
				break;

			case OID_SKGE_VCT_STATUS:
				CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);

				Offset++;
				RetCode = SK_PNMI_ERR_OK;
				break;

			case OID_SKGE_VCT_CAPABILITIES:
				if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
					*(pBuf + Offset) = SK_PNMI_VCT_NOT_SUPPORTED;
				}
				else {
					*(pBuf + Offset) = SK_PNMI_VCT_SUPPORTED;
				}
				Offset++;

				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++) {

		pPrt = &pAC->GIni.GP[PhysPortIndex];

		switch (Id) {
		case OID_SKGE_VCT_SET: /* Start VCT test. */
			if (!pPrt->PHWLinkUp) {
				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 | 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],
						SK_PNMI_VCT_TIMER_CHECK, 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 VctGetResults(
SK_AC		*pAC,
SK_IOC		IoC,
SK_U32		Port)
{
	SK_GEPORT	*pPrt;
	int			i;
	SK_U8		PairLen;
	SK_U8		PairSts;
	SK_U32		MinLength;
	SK_U32		CableLength;

	pPrt = &pAC->GIni.GP[Port];

	if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
		MinLength = 25;
	}
	else {
		MinLength = 35;
	}

	/* Copy results for later use to PNMI struct. */
	for (i = 0; i < 4; i++)  {

		PairLen = pPrt->PMdiPairLen[i];

		if (((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) == 0) && (i > 1)) {
			PairSts = SK_PNMI_VCT_NOT_PRESENT;
		}
		else {
			PairSts = pPrt->PMdiPairSts[i];
		}

		if ((PairSts == SK_PNMI_VCT_NORMAL_CABLE) &&
			(PairLen > 28) && (PairLen < 0xff)) {

			PairSts = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
		}

		/* Ignore values <= MinLength, the linear factor is 4/5. */
		if ((PairLen > MinLength) && (PairLen < 0xff)) {

			CableLength = 1000UL * (PairLen - MinLength) * 4 / 5;
		}
		else {
			/* No cable or short cable. */
			CableLength = 0;
		}

		pAC->Pnmi.VctBackup[Port].MdiPairLen[i] = CableLength;
		pAC->Pnmi.VctBackup[Port].MdiPairSts[i] = PairSts;
	}

	pAC->Pnmi.VctStatus[Port] &= ~SK_PNMI_VCT_PENDING;
	pAC->Pnmi.VctStatus[Port] |= (SK_PNMI_VCT_NEW_VCT_DATA |
		SK_PNMI_VCT_TEST_DONE);

} /* GetVctResults */

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_U8		VctStatus;
	SK_U32		RetCode;

	pPrt = &pAC->GIni.GP[PhysPortIndex];

	pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
	pVctData->VctStatus = SK_PNMI_VCT_NONE;

	VctStatus = pAC->Pnmi.VctStatus[PhysPortIndex];

	if (!pPrt->PHWLinkUp) {

		/* Was a VCT test ever made before? */
		if (VctStatus & SK_PNMI_VCT_TEST_DONE) {
			if (VctStatus & 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 (VctStatus & 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 (VctStatus & 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 (pPrt->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 */

#ifdef SK_ASF
/*****************************************************************************
 *
 * Asf
 *
 * Description:
 *  The code is simple. No description necessary.
 *
 * Returns:
 *  SK_PNMI_ERR_OK           The request was successfully performed.
 *  SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 *  SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 *                           the correct data (e.g. a 32bit value is
 *                           needed, but a 16 bit value was passed).
 *  SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 *                           exist (e.g. port instance 3 on a two port
 *                           adapter.
 */

PNMI_STATIC int Asf(
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  RetCode = SK_PNMI_ERR_GENERAL;

    /*
     * Check instance. We only handle single instance variables.
     */
    if (Instance != (SK_U32)(-1) && Instance != 1) {

        *pLen = 0;
        return (SK_PNMI_ERR_UNKNOWN_INST);
    }

    /* Perform action. */
    /* GET value. */
    if (Action == SK_PNMI_GET) {
        switch (Id) {
            case OID_SKGE_ASF:
                RetCode = SkAsfGet(pAC, IoC, (SK_U8 *) pBuf, pLen);
                break;
            default:
                RetCode = SkAsfGetOid( pAC, IoC, Id, Instance, (SK_U8 *) pBuf, pLen );
                break;
        }

        return (RetCode);
    }

    /* PRESET value. */
    if (Action == SK_PNMI_PRESET) {
        switch (Id) {
            case OID_SKGE_ASF:
                RetCode = SkAsfPreSet(pAC, IoC, (SK_U8 *) pBuf, pLen);
                break;
            default:
                RetCode = SkAsfPreSetOid( pAC, IoC, Id, Instance, (SK_U8 *) pBuf, pLen );
                break;
        }
    }

    /* SET value. */
    if (Action == SK_PNMI_SET) {
        switch (Id) {
            case OID_SKGE_ASF:
                RetCode = SkAsfSet(pAC, IoC, (SK_U8 *) pBuf, pLen);
                break;
            default:
                RetCode = SkAsfSetOid( pAC, IoC, Id, Instance, (SK_U8 *) pBuf, pLen );
                break;
        }
    }
    return (RetCode);
}
#endif /* SK_ASF */

#endif
