1 /*****************************************************************************
 
   4  * Project:     GEnesis, PCI Gigabit Ethernet Adapter
 
   5  * Version:     $Revision: 1.111 $
 
   6  * Date:        $Date: 2003/09/15 13:35:35 $
 
   7  * Purpose:     Private Network Management Interface
 
   9  ****************************************************************************/
 
  11 /******************************************************************************
 
  13  *      (C)Copyright 1998-2002 SysKonnect GmbH.
 
  14  *      (C)Copyright 2002-2003 Marvell.
 
  16  *      This program is free software; you can redistribute it and/or modify
 
  17  *      it under the terms of the GNU General Public License as published by
 
  18  *      the Free Software Foundation; either version 2 of the License, or
 
  19  *      (at your option) any later version.
 
  21  *      The information in this file is provided "AS IS" without warranty.
 
  23  ******************************************************************************/
 
  27 static const char SysKonnectFileId[] =
 
  28         "@(#) $Id: skgepnmi.c,v 1.111 2003/09/15 13:35:35 tschilli Exp $ (C) Marvell.";
 
  31 #include "h/skdrv1st.h"
 
  32 #include "h/sktypes.h"
 
  33 #include "h/xmac_ii.h"
 
  34 #include "h/skdebug.h"
 
  35 #include "h/skqueue.h"
 
  36 #include "h/skgepnmi.h"
 
  37 #include "h/skgesirq.h"
 
  41 #include "h/skgeinit.h"
 
  42 #include "h/skdrv2nd.h"
 
  43 #include "h/skgepnm2.h"
 
  45 #include "h/skgepmgt.h"
 
  47 /* defines *******************************************************************/
 
  50 #define PNMI_STATIC     static
 
  56  * Public Function prototypes
 
  58 int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level);
 
  59 int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
 
  60         unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
 
  61 int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
 
  62         unsigned int *pLen, SK_U32 NetIndex);
 
  63 int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
 
  64         unsigned int *pLen, SK_U32 NetIndex);
 
  65 int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
 
  66         unsigned int *pLen, SK_U32 NetIndex);
 
  67 int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
 
  68 int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf,
 
  69         unsigned int * pLen, SK_U32 NetIndex);
 
  73  * Private Function prototypes
 
  76 PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
 
  78 PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
 
  80 PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac);
 
  81 PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
 
  82 PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
 
  83         unsigned int PhysPortIndex, unsigned int StatIndex);
 
  84 PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
 
  85         unsigned int StatIndex, SK_U32 NetIndex);
 
  86 PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
 
  87 PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
 
  88         unsigned int *pEntries);
 
  89 PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr,
 
  90         unsigned int KeyArrLen, unsigned int *pKeyNo);
 
  91 PNMI_STATIC int LookupId(SK_U32 Id);
 
  92 PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
 
  93         unsigned int LastMac);
 
  94 PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
 
  95         unsigned int *pLen, SK_U32 NetIndex);
 
  96 PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id,
 
  97         char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
 
  98 PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
 
  99 PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
 
 100         unsigned int PortIndex);
 
 101 PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
 
 102         unsigned int SensorIndex);
 
 103 PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
 
 104 PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
 
 105 PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
 
 106 PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
 
 107 PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
 
 108 PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
 
 109         unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
 
 110 PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
 
 113  * Table to correlate OID with handler function and index to
 
 114  * hardware register stored in StatAddress if applicable.
 
 118 /* global variables **********************************************************/
 
 121  * Overflow status register bit table and corresponding counter
 
 122  * dependent on MAC type - the number relates to the size of overflow
 
 123  * mask returned by the pFnMacOverflow function
 
 125 PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = {
 
 126 /* Bit0  */     { SK_PNMI_HTX,                          SK_PNMI_HTX_UNICAST},
 
 127 /* Bit1  */     { SK_PNMI_HTX_OCTETHIGH,        SK_PNMI_HTX_BROADCAST},
 
 128 /* Bit2  */     { SK_PNMI_HTX_OCTETLOW,         SK_PNMI_HTX_PMACC},
 
 129 /* Bit3  */     { SK_PNMI_HTX_BROADCAST,        SK_PNMI_HTX_MULTICAST},
 
 130 /* Bit4  */     { SK_PNMI_HTX_MULTICAST,        SK_PNMI_HTX_OCTETLOW},
 
 131 /* Bit5  */     { SK_PNMI_HTX_UNICAST,          SK_PNMI_HTX_OCTETHIGH},
 
 132 /* Bit6  */     { SK_PNMI_HTX_LONGFRAMES,       SK_PNMI_HTX_64},
 
 133 /* Bit7  */     { SK_PNMI_HTX_BURST,            SK_PNMI_HTX_127},
 
 134 /* Bit8  */     { SK_PNMI_HTX_PMACC,            SK_PNMI_HTX_255},
 
 135 /* Bit9  */     { SK_PNMI_HTX_MACC,             SK_PNMI_HTX_511},
 
 136 /* Bit10 */     { SK_PNMI_HTX_SINGLE_COL,       SK_PNMI_HTX_1023},
 
 137 /* Bit11 */     { SK_PNMI_HTX_MULTI_COL,        SK_PNMI_HTX_MAX},
 
 138 /* Bit12 */     { SK_PNMI_HTX_EXCESS_COL,       SK_PNMI_HTX_LONGFRAMES},
 
 139 /* Bit13 */     { SK_PNMI_HTX_LATE_COL,         SK_PNMI_HTX_RESERVED},
 
 140 /* Bit14 */     { SK_PNMI_HTX_DEFFERAL,         SK_PNMI_HTX_COL},
 
 141 /* Bit15 */     { SK_PNMI_HTX_EXCESS_DEF,       SK_PNMI_HTX_LATE_COL},
 
 142 /* Bit16 */     { SK_PNMI_HTX_UNDERRUN,         SK_PNMI_HTX_EXCESS_COL},
 
 143 /* Bit17 */     { SK_PNMI_HTX_CARRIER,          SK_PNMI_HTX_MULTI_COL},
 
 144 /* Bit18 */     { SK_PNMI_HTX_UTILUNDER,        SK_PNMI_HTX_SINGLE_COL},
 
 145 /* Bit19 */     { SK_PNMI_HTX_UTILOVER,         SK_PNMI_HTX_UNDERRUN},
 
 146 /* Bit20 */     { SK_PNMI_HTX_64,                       SK_PNMI_HTX_RESERVED},
 
 147 /* Bit21 */     { SK_PNMI_HTX_127,                      SK_PNMI_HTX_RESERVED},
 
 148 /* Bit22 */     { SK_PNMI_HTX_255,                      SK_PNMI_HTX_RESERVED},
 
 149 /* Bit23 */     { SK_PNMI_HTX_511,                      SK_PNMI_HTX_RESERVED},
 
 150 /* Bit24 */     { SK_PNMI_HTX_1023,             SK_PNMI_HTX_RESERVED},
 
 151 /* Bit25 */     { SK_PNMI_HTX_MAX,                      SK_PNMI_HTX_RESERVED},
 
 152 /* Bit26 */     { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
 
 153 /* Bit27 */     { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
 
 154 /* Bit28 */     { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
 
 155 /* Bit29 */     { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
 
 156 /* Bit30 */     { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
 
 157 /* Bit31 */     { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
 
 158 /* Bit32 */     { SK_PNMI_HRX,                          SK_PNMI_HRX_UNICAST},
 
 159 /* Bit33 */     { SK_PNMI_HRX_OCTETHIGH,        SK_PNMI_HRX_BROADCAST},
 
 160 /* Bit34 */     { SK_PNMI_HRX_OCTETLOW,         SK_PNMI_HRX_PMACC},
 
 161 /* Bit35 */     { SK_PNMI_HRX_BROADCAST,        SK_PNMI_HRX_MULTICAST},
 
 162 /* Bit36 */     { SK_PNMI_HRX_MULTICAST,        SK_PNMI_HRX_FCS},
 
 163 /* Bit37 */     { SK_PNMI_HRX_UNICAST,          SK_PNMI_HRX_RESERVED},
 
 164 /* Bit38 */     { SK_PNMI_HRX_PMACC,            SK_PNMI_HRX_OCTETLOW},
 
 165 /* Bit39 */     { SK_PNMI_HRX_MACC,             SK_PNMI_HRX_OCTETHIGH},
 
 166 /* Bit40 */     { SK_PNMI_HRX_PMACC_ERR,        SK_PNMI_HRX_BADOCTETLOW},
 
 167 /* Bit41 */     { SK_PNMI_HRX_MACC_UNKWN,       SK_PNMI_HRX_BADOCTETHIGH},
 
 168 /* Bit42 */     { SK_PNMI_HRX_BURST,            SK_PNMI_HRX_UNDERSIZE},
 
 169 /* Bit43 */     { SK_PNMI_HRX_MISSED,           SK_PNMI_HRX_RUNT},
 
 170 /* Bit44 */     { SK_PNMI_HRX_FRAMING,          SK_PNMI_HRX_64},
 
 171 /* Bit45 */     { SK_PNMI_HRX_OVERFLOW,         SK_PNMI_HRX_127},
 
 172 /* Bit46 */     { SK_PNMI_HRX_JABBER,           SK_PNMI_HRX_255},
 
 173 /* Bit47 */     { SK_PNMI_HRX_CARRIER,          SK_PNMI_HRX_511},
 
 174 /* Bit48 */     { SK_PNMI_HRX_IRLENGTH,         SK_PNMI_HRX_1023},
 
 175 /* Bit49 */     { SK_PNMI_HRX_SYMBOL,           SK_PNMI_HRX_MAX},
 
 176 /* Bit50 */     { SK_PNMI_HRX_SHORTS,           SK_PNMI_HRX_LONGFRAMES},
 
 177 /* Bit51 */     { SK_PNMI_HRX_RUNT,             SK_PNMI_HRX_TOO_LONG},
 
 178 /* Bit52 */     { SK_PNMI_HRX_TOO_LONG,         SK_PNMI_HRX_JABBER},
 
 179 /* Bit53 */     { SK_PNMI_HRX_FCS,                      SK_PNMI_HRX_RESERVED},
 
 180 /* Bit54 */     { SK_PNMI_HRX_RESERVED,         SK_PNMI_HRX_OVERFLOW},
 
 181 /* Bit55 */     { SK_PNMI_HRX_CEXT,             SK_PNMI_HRX_RESERVED},
 
 182 /* Bit56 */     { SK_PNMI_HRX_UTILUNDER,        SK_PNMI_HRX_RESERVED},
 
 183 /* Bit57 */     { SK_PNMI_HRX_UTILOVER,         SK_PNMI_HRX_RESERVED},
 
 184 /* Bit58 */     { SK_PNMI_HRX_64,                       SK_PNMI_HRX_RESERVED},
 
 185 /* Bit59 */     { SK_PNMI_HRX_127,                      SK_PNMI_HRX_RESERVED},
 
 186 /* Bit60 */     { SK_PNMI_HRX_255,                      SK_PNMI_HRX_RESERVED},
 
 187 /* Bit61 */     { SK_PNMI_HRX_511,                      SK_PNMI_HRX_RESERVED},
 
 188 /* Bit62 */     { SK_PNMI_HRX_1023,             SK_PNMI_HRX_RESERVED},
 
 189 /* Bit63 */     { SK_PNMI_HRX_MAX,                      SK_PNMI_HRX_RESERVED}
 
 193  * Table for hardware register saving on resets and port switches
 
 195 PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = {
 
 197         {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}},
 
 198         /* SK_PNMI_HTX_OCTETHIGH */
 
 199         {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}},
 
 200         /* SK_PNMI_HTX_OCTETLOW */
 
 201         {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}},
 
 202         /* SK_PNMI_HTX_BROADCAST */
 
 203         {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}},
 
 204         /* SK_PNMI_HTX_MULTICAST */
 
 205         {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}},
 
 206         /* SK_PNMI_HTX_UNICAST */
 
 207         {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}},
 
 208         /* SK_PNMI_HTX_BURST */
 
 209         {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}},
 
 210         /* SK_PNMI_HTX_PMACC */
 
 211         {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}},
 
 212         /* SK_PNMI_HTX_MACC */
 
 213         {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
 
 214         /* SK_PNMI_HTX_COL */
 
 215         {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}},
 
 216         /* SK_PNMI_HTX_SINGLE_COL */
 
 217         {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}},
 
 218         /* SK_PNMI_HTX_MULTI_COL */
 
 219         {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}},
 
 220         /* SK_PNMI_HTX_EXCESS_COL */
 
 221         {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}},
 
 222         /* SK_PNMI_HTX_LATE_COL */
 
 223         {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}},
 
 224         /* SK_PNMI_HTX_DEFFERAL */
 
 225         {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}},
 
 226         /* SK_PNMI_HTX_EXCESS_DEF */
 
 227         {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}},
 
 228         /* SK_PNMI_HTX_UNDERRUN */
 
 229         {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}},
 
 230         /* SK_PNMI_HTX_CARRIER */
 
 231         {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}},
 
 232         /* SK_PNMI_HTX_UTILUNDER */
 
 233         {{0, SK_FALSE}, {0, SK_FALSE}},
 
 234         /* SK_PNMI_HTX_UTILOVER */
 
 235         {{0, SK_FALSE}, {0, SK_FALSE}},
 
 237         {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}},
 
 238         /* SK_PNMI_HTX_127 */
 
 239         {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}},
 
 240         /* SK_PNMI_HTX_255 */
 
 241         {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}},
 
 242         /* SK_PNMI_HTX_511 */
 
 243         {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}},
 
 244         /* SK_PNMI_HTX_1023 */
 
 245         {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}},
 
 246         /* SK_PNMI_HTX_MAX */
 
 247         {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}},
 
 248         /* SK_PNMI_HTX_LONGFRAMES  */
 
 249         {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}},
 
 250         /* SK_PNMI_HTX_SYNC */
 
 251         {{0, SK_FALSE}, {0, SK_FALSE}},
 
 252         /* SK_PNMI_HTX_SYNC_OCTET */
 
 253         {{0, SK_FALSE}, {0, SK_FALSE}},
 
 254         /* SK_PNMI_HTX_RESERVED */
 
 255         {{0, SK_FALSE}, {0, SK_FALSE}},
 
 257         {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}},
 
 258         /* SK_PNMI_HRX_OCTETHIGH */
 
 259         {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}},
 
 260         /* SK_PNMI_HRX_OCTETLOW */
 
 261         {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}},
 
 262         /* SK_PNMI_HRX_BADOCTETHIGH */
 
 263         {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}},
 
 264         /* SK_PNMI_HRX_BADOCTETLOW */
 
 265         {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}},
 
 266         /* SK_PNMI_HRX_BROADCAST */
 
 267         {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}},
 
 268         /* SK_PNMI_HRX_MULTICAST */
 
 269         {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}},
 
 270         /* SK_PNMI_HRX_UNICAST */
 
 271         {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}},
 
 272         /* SK_PNMI_HRX_PMACC */
 
 273         {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}},
 
 274         /* SK_PNMI_HRX_MACC */
 
 275         {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
 
 276         /* SK_PNMI_HRX_PMACC_ERR */
 
 277         {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}},
 
 278         /* SK_PNMI_HRX_MACC_UNKWN */
 
 279         {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}},
 
 280         /* SK_PNMI_HRX_BURST */
 
 281         {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}},
 
 282         /* SK_PNMI_HRX_MISSED */
 
 283         {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}},
 
 284         /* SK_PNMI_HRX_FRAMING */
 
 285         {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}},
 
 286         /* SK_PNMI_HRX_UNDERSIZE */
 
 287         {{0, SK_FALSE}, {GM_RXF_SHT, SK_TRUE}},
 
 288         /* SK_PNMI_HRX_OVERFLOW */
 
 289         {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}},
 
 290         /* SK_PNMI_HRX_JABBER */
 
 291         {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}},
 
 292         /* SK_PNMI_HRX_CARRIER */
 
 293         {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}},
 
 294         /* SK_PNMI_HRX_IRLENGTH */
 
 295         {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}},
 
 296         /* SK_PNMI_HRX_SYMBOL */
 
 297         {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}},
 
 298         /* SK_PNMI_HRX_SHORTS */
 
 299         {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}},
 
 300         /* SK_PNMI_HRX_RUNT */
 
 301         {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}},
 
 302         /* SK_PNMI_HRX_TOO_LONG */
 
 303         {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}},
 
 304         /* SK_PNMI_HRX_FCS */
 
 305         {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}},
 
 306         /* SK_PNMI_HRX_CEXT */
 
 307         {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}},
 
 308         /* SK_PNMI_HRX_UTILUNDER */
 
 309         {{0, SK_FALSE}, {0, SK_FALSE}},
 
 310         /* SK_PNMI_HRX_UTILOVER */
 
 311         {{0, SK_FALSE}, {0, SK_FALSE}},
 
 313         {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}},
 
 314         /* SK_PNMI_HRX_127 */
 
 315         {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}},
 
 316         /* SK_PNMI_HRX_255 */
 
 317         {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}},
 
 318         /* SK_PNMI_HRX_511 */
 
 319         {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}},
 
 320         /* SK_PNMI_HRX_1023 */
 
 321         {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}},
 
 322         /* SK_PNMI_HRX_MAX */
 
 323         {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}},
 
 324         /* SK_PNMI_HRX_LONGFRAMES */
 
 325         {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}},
 
 326         /* SK_PNMI_HRX_RESERVED */
 
 327         {{0, SK_FALSE}, {0, SK_FALSE}}
 
 331 /*****************************************************************************
 
 337 /*****************************************************************************
 
 339  * SkPnmiInit - Init function of PNMI
 
 342  *      SK_INIT_DATA: Initialises the data structures
 
 343  *      SK_INIT_IO:   Resets the XMAC statistics, determines the device and
 
 345  *      SK_INIT_RUN:  Starts a timer event for port switch per hour
 
 352 SK_AC *pAC,             /* Pointer to adapter context */
 
 353 SK_IOC IoC,             /* IO context handle */
 
 354 int Level)              /* Initialization level */
 
 356         unsigned int    PortMax;        /* Number of ports */
 
 357         unsigned int    PortIndex;      /* Current port index in loop */
 
 358         SK_U16          Val16;          /* Multiple purpose 16 bit variable */
 
 359         SK_U8           Val8;           /* Mulitple purpose 8 bit variable */
 
 360         SK_EVPARA       EventParam;     /* Event struct for timer event */
 
 361         SK_PNMI_VCT     *pVctBackupData;
 
 364         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
 365                 ("PNMI: SkPnmiInit: Called, level=%d\n", Level));
 
 370                 SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
 
 371                 pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
 
 372                 pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
 
 373                 pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
 
 374                 for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
 
 376                         pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
 
 377                         pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
 
 381                 if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) {
 
 383                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG);
 
 385                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
 
 386                                            ("CounterOffset struct size (%d) differs from"
 
 387                                                 "SK_PNMI_MAX_IDX (%d)\n",
 
 388                                                 SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
 
 391                 if (SK_PNMI_MAX_IDX !=
 
 392                         (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) {
 
 394                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG);
 
 396                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
 
 397                                            ("StatAddr table size (%d) differs from "
 
 398                                                 "SK_PNMI_MAX_IDX (%d)\n",
 
 400                                                  (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)),
 
 403 #endif /* SK_PNMI_CHECK */
 
 410                 PortMax = pAC->GIni.GIMacsFound;
 
 412                 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
 
 414                         pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
 
 417                 /* Initialize DSP variables for Vct() to 0xff => Never written! */              
 
 418                 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
 
 419                         pAC->GIni.GP[PortIndex].PCableLen = 0xff;
 
 420                         pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
 
 421                         pVctBackupData->PCableLen = 0xff;
 
 427                 SK_IN16(IoC, B0_CTST, &Val16);
 
 428                 if ((Val16 & CS_BUS_CLOCK) == 0) {
 
 430                         pAC->Pnmi.PciBusSpeed = 33;
 
 433                         pAC->Pnmi.PciBusSpeed = 66;
 
 439                 SK_IN16(IoC, B0_CTST, &Val16);
 
 440                 if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
 
 442                         pAC->Pnmi.PciBusWidth = 32;
 
 445                         pAC->Pnmi.PciBusWidth = 64;
 
 451                 switch (pAC->GIni.GIChipId) {
 
 452                 case CHIP_ID_GENESIS:
 
 453                         pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
 
 457                         pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
 
 465                  * Get PMD and DeviceType
 
 467                 SK_IN8(IoC, B2_PMD_TYP, &Val8);
 
 471                         if (pAC->GIni.GIMacsFound > 1) {
 
 473                                 pAC->Pnmi.DeviceType = 0x00020002;
 
 476                                 pAC->Pnmi.DeviceType = 0x00020001;
 
 482                         if (pAC->GIni.GIMacsFound > 1) {
 
 484                                 pAC->Pnmi.DeviceType = 0x00020004;
 
 487                                 pAC->Pnmi.DeviceType = 0x00020003;
 
 493                         if (pAC->GIni.GIMacsFound > 1) {
 
 495                                 pAC->Pnmi.DeviceType = 0x00020006;
 
 498                                 pAC->Pnmi.DeviceType = 0x00020005;
 
 504                         if (pAC->GIni.GIMacsFound > 1) {
 
 506                                 pAC->Pnmi.DeviceType = 0x00020008;
 
 509                                 pAC->Pnmi.DeviceType = 0x00020007;
 
 515                         pAC->Pnmi.DeviceType = 0;
 
 522                 SK_IN8(IoC, B2_CONN_TYP, &Val8);
 
 525                         pAC->Pnmi.Connector = 2;
 
 529                         pAC->Pnmi.Connector = 3;
 
 533                         pAC->Pnmi.Connector = 4;
 
 537                         pAC->Pnmi.Connector = 5;
 
 541                         pAC->Pnmi.Connector = 6;
 
 545                         pAC->Pnmi.Connector = 1;
 
 552                  * Start timer for RLMT change counter
 
 554                 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
 
 555                 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
 
 556                         28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
 
 561                 break; /* Nothing todo */
 
 567 /*****************************************************************************
 
 569  * SkPnmiGetVar - Retrieves the value of a single OID
 
 572  *      Calls a general sub-function for all this stuff. If the instance
 
 573  *      -1 is passed, the values of all instances are returned in an
 
 577  *      SK_PNMI_ERR_OK           The request was successfully performed
 
 578  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured
 
 579  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to take
 
 581  *      SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown
 
 582  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
 583  *                           exist (e.g. port instance 3 on a two port
 
 586 static int SkPnmiGetVar(
 
 587 SK_AC *pAC,             /* Pointer to adapter context */
 
 588 SK_IOC IoC,             /* IO context handle */
 
 589 SK_U32 Id,              /* Object ID that is to be processed */
 
 590 void *pBuf,             /* Buffer to which the management data will be copied */
 
 591 unsigned int *pLen,     /* On call: buffer length. On return: used buffer */
 
 592 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
 593 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
 595         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
 596                 ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
 
 597                         Id, *pLen, Instance, NetIndex));
 
 599         return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
 
 600                 Instance, NetIndex));
 
 603 /*****************************************************************************
 
 605  * SkPnmiPreSetVar - Presets the value of a single OID
 
 608  *      Calls a general sub-function for all this stuff. The preset does
 
 609  *      the same as a set, but returns just before finally setting the
 
 610  *      new value. This is useful to check if a set might be successfull.
 
 611  *      If the instance -1 is passed, an array of values is supposed and
 
 612  *      all instances of the OID will be set.
 
 615  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
 616  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
 617  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
 618  *                               the correct data (e.g. a 32bit value is
 
 619  *                               needed, but a 16 bit value was passed).
 
 620  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 
 622  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 
 623  *      SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown.
 
 624  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
 625  *                           exist (e.g. port instance 3 on a two port
 
 628 static int SkPnmiPreSetVar(
 
 629 SK_AC *pAC,             /* Pointer to adapter context */
 
 630 SK_IOC IoC,             /* IO context handle */
 
 631 SK_U32 Id,              /* Object ID that is to be processed */
 
 632 void *pBuf,             /* Buffer to which the management data will be copied */
 
 633 unsigned int *pLen,     /* Total length of management data */
 
 634 SK_U32 Instance,        /* Instance (1..n) that is to be set or -1 */
 
 635 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
 637         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
 638                 ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
 
 639                         Id, *pLen, Instance, NetIndex));
 
 642         return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
 
 643                 Instance, NetIndex));
 
 646 /*****************************************************************************
 
 648  * SkPnmiSetVar - Sets the value of a single OID
 
 651  *      Calls a general sub-function for all this stuff. The preset does
 
 652  *      the same as a set, but returns just before finally setting the
 
 653  *      new value. This is useful to check if a set might be successfull.
 
 654  *      If the instance -1 is passed, an array of values is supposed and
 
 655  *      all instances of the OID will be set.
 
 658  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
 659  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
 660  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
 661  *                               the correct data (e.g. a 32bit value is
 
 662  *                               needed, but a 16 bit value was passed).
 
 663  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 
 665  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 
 666  *      SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown.
 
 667  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
 668  *                           exist (e.g. port instance 3 on a two port
 
 672 SK_AC *pAC,             /* Pointer to adapter context */
 
 673 SK_IOC IoC,             /* IO context handle */
 
 674 SK_U32 Id,              /* Object ID that is to be processed */
 
 675 void *pBuf,             /* Buffer to which the management data will be copied */
 
 676 unsigned int *pLen,     /* Total length of management data */
 
 677 SK_U32 Instance,        /* Instance (1..n) that is to be set or -1 */
 
 678 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
 680         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
 681                 ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
 
 682                         Id, *pLen, Instance, NetIndex));
 
 684         return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
 
 685                 Instance, NetIndex));
 
 688 /*****************************************************************************
 
 690  * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA
 
 693  *      Runs through the IdTable, queries the single OIDs and stores the
 
 694  *      returned data into the management database structure
 
 695  *      SK_PNMI_STRUCT_DATA. The offset of the OID in the structure
 
 696  *      is stored in the IdTable. The return value of the function will also
 
 697  *      be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
 
 698  *      minimum size of SK_PNMI_MIN_STRUCT_SIZE.
 
 701  *      SK_PNMI_ERR_OK           The request was successfully performed
 
 702  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured
 
 703  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to take
 
 705  *      SK_PNMI_ERR_UNKNOWN_NET  The requested NetIndex doesn't exist
 
 708 SK_AC *pAC,             /* Pointer to adapter context */
 
 709 SK_IOC IoC,             /* IO context handle */
 
 710 void *pBuf,             /* Buffer to which the management data will be copied. */
 
 711 unsigned int *pLen,     /* Length of buffer */
 
 712 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
 715         unsigned int    TableIndex;
 
 716         unsigned int    DstOffset;
 
 717         unsigned int    InstanceNo;
 
 718         unsigned int    InstanceCnt;
 
 721         char            KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
 
 724         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
 725                 ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
 
 728         if (*pLen < SK_PNMI_STRUCT_SIZE) {
 
 730                 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
 
 732                         SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
 
 736                 *pLen = SK_PNMI_STRUCT_SIZE;
 
 737                 return (SK_PNMI_ERR_TOO_SHORT);
 
 743         if (NetIndex >= pAC->Rlmt.NumNets) {
 
 744                 return (SK_PNMI_ERR_UNKNOWN_NET);
 
 747         /* Update statistic */
 
 748         SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
 
 750         if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
 
 753                 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
 
 754                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
 
 758         if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
 
 760                 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
 
 761                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
 
 765         if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
 
 767                 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
 
 768                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
 
 773          * Increment semaphores to indicate that an update was
 
 776         pAC->Pnmi.MacUpdatedFlag ++;
 
 777         pAC->Pnmi.RlmtUpdatedFlag ++;
 
 778         pAC->Pnmi.SirqUpdatedFlag ++;
 
 780         /* Get vpd keys for instance calculation */
 
 781         Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
 
 782         if (Ret != SK_PNMI_ERR_OK) {
 
 784                 pAC->Pnmi.MacUpdatedFlag --;
 
 785                 pAC->Pnmi.RlmtUpdatedFlag --;
 
 786                 pAC->Pnmi.SirqUpdatedFlag --;
 
 788                 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
 
 789                 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
 
 790                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
 
 791                 return (SK_PNMI_ERR_GENERAL);
 
 794         /* Retrieve values */
 
 795         SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
 
 796         for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
 
 798                 InstanceNo = IdTable[TableIndex].InstanceNo;
 
 799                 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
 
 802                         DstOffset = IdTable[TableIndex].Offset +
 
 804                                 IdTable[TableIndex].StructSize;
 
 807                          * For the VPD the instance is not an index number
 
 808                          * but the key itself. Determin with the instance
 
 809                          * counter the VPD key to be used.
 
 811                         if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
 
 812                                 IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
 
 813                                 IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
 
 814                                 IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
 
 816                                 SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
 
 819                                 Instance = (SK_U32)InstanceCnt;
 
 822                         TmpLen = *pLen - DstOffset;
 
 823                         Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
 
 824                                 IdTable[TableIndex].Id, (char *)pBuf +
 
 825                                 DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
 
 828                          * An unknown instance error means that we reached
 
 829                          * the last instance of that variable. Proceed with
 
 830                          * the next OID in the table and ignore the return
 
 833                         if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
 
 838                         if (Ret != SK_PNMI_ERR_OK) {
 
 840                                 pAC->Pnmi.MacUpdatedFlag --;
 
 841                                 pAC->Pnmi.RlmtUpdatedFlag --;
 
 842                                 pAC->Pnmi.SirqUpdatedFlag --;
 
 844                                 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
 
 845                                 SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
 
 846                                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
 
 852         pAC->Pnmi.MacUpdatedFlag --;
 
 853         pAC->Pnmi.RlmtUpdatedFlag --;
 
 854         pAC->Pnmi.SirqUpdatedFlag --;
 
 856         *pLen = SK_PNMI_STRUCT_SIZE;
 
 857         SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
 
 858         SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
 
 859         return (SK_PNMI_ERR_OK);
 
 862 /*****************************************************************************
 
 864  * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
 
 867  *      Calls a general sub-function for all this set stuff. The preset does
 
 868  *      the same as a set, but returns just before finally setting the
 
 869  *      new value. This is useful to check if a set might be successfull.
 
 870  *      The sub-function runs through the IdTable, checks which OIDs are able
 
 871  *      to set, and calls the handler function of the OID to perform the
 
 872  *      preset. The return value of the function will also be stored in
 
 873  *      SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
 
 874  *      SK_PNMI_MIN_STRUCT_SIZE.
 
 877  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
 878  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
 879  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
 880  *                               the correct data (e.g. a 32bit value is
 
 881  *                               needed, but a 16 bit value was passed).
 
 882  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 
 885 int SkPnmiPreSetStruct(
 
 886 SK_AC *pAC,             /* Pointer to adapter context */
 
 887 SK_IOC IoC,             /* IO context handle */
 
 888 void *pBuf,             /* Buffer which contains the data to be set */
 
 889 unsigned int *pLen,     /* Length of buffer */
 
 890 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
 892         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
 893                 ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
 
 896         return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf,
 
 900 /*****************************************************************************
 
 902  * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA
 
 905  *      Calls a general sub-function for all this set stuff. The return value
 
 906  *      of the function will also be stored in SK_PNMI_STRUCT_DATA if the
 
 907  *      passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE.
 
 908  *      The sub-function runs through the IdTable, checks which OIDs are able
 
 909  *      to set, and calls the handler function of the OID to perform the
 
 910  *      set. The return value of the function will also be stored in
 
 911  *      SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
 
 912  *      SK_PNMI_MIN_STRUCT_SIZE.
 
 915  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
 916  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
 917  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
 918  *                               the correct data (e.g. a 32bit value is
 
 919  *                               needed, but a 16 bit value was passed).
 
 920  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 
 924 SK_AC *pAC,             /* Pointer to adapter context */
 
 925 SK_IOC IoC,             /* IO context handle */
 
 926 void *pBuf,             /* Buffer which contains the data to be set */
 
 927 unsigned int *pLen,     /* Length of buffer */
 
 928 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
 930         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
 931                 ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
 
 934         return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf,
 
 938 /*****************************************************************************
 
 940  * SkPnmiEvent - Event handler
 
 943  *      Handles the following events:
 
 944  *      SK_PNMI_EVT_SIRQ_OVERFLOW     When a hardware counter overflows an
 
 945  *                                    interrupt will be generated which is
 
 946  *                                    first handled by SIRQ which generates a
 
 947  *                                    this event. The event increments the
 
 948  *                                    upper 32 bit of the 64 bit counter.
 
 949  *      SK_PNMI_EVT_SEN_XXX           The event is generated by the I2C module
 
 950  *                                    when a sensor reports a warning or
 
 951  *                                    error. The event will store a trap
 
 952  *                                    message in the trap buffer.
 
 953  *      SK_PNMI_EVT_CHG_EST_TIMER     The timer event was initiated by this
 
 954  *                                    module and is used to calculate the
 
 955  *                                    port switches per hour.
 
 956  *      SK_PNMI_EVT_CLEAR_COUNTER     The event clears all counters and
 
 958  *      SK_PNMI_EVT_XMAC_RESET        The event is generated by the driver
 
 959  *                                    before a hard reset of the XMAC is
 
 960  *                                    performed. All counters will be saved
 
 961  *                                    and added to the hardware counter
 
 962  *                                    values after reset to grant continuous
 
 964  *      SK_PNMI_EVT_RLMT_PORT_UP      Generated by RLMT to notify that a port
 
 965  *                                    went logically up. A trap message will
 
 966  *                                    be stored to the trap buffer.
 
 967  *      SK_PNMI_EVT_RLMT_PORT_DOWN    Generated by RLMT to notify that a port
 
 968  *                                    went logically down. A trap message will
 
 969  *                                    be stored to the trap buffer.
 
 970  *      SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
 
 971  *                                    spanning tree root bridges were
 
 972  *                                    detected. A trap message will be stored
 
 973  *                                    to the trap buffer.
 
 974  *      SK_PNMI_EVT_RLMT_ACTIVE_DOWN  Notifies PNMI that an active port went
 
 975  *                                    down. PNMI will not further add the
 
 976  *                                    statistic values to the virtual port.
 
 977  *      SK_PNMI_EVT_RLMT_ACTIVE_UP    Notifies PNMI that a port went up and
 
 978  *                                    is now an active port. PNMI will now
 
 979  *                                    add the statistic data of this port to
 
 981  *      SK_PNMI_EVT_RLMT_SET_NETS     Notifies PNMI about the net mode. The first parameter
 
 982  *                                    contains the number of nets. 1 means single net, 2 means
 
 983  *                                    dual net. The second parameter is -1
 
 989 SK_AC *pAC,             /* Pointer to adapter context */
 
 990 SK_IOC IoC,             /* IO context handle */
 
 991 SK_U32 Event,           /* Event-Id */
 
 992 SK_EVPARA Param)        /* Event dependent parameter */
 
 994         unsigned int    PhysPortIndex;
 
 995     unsigned int        MaxNetNumber;
 
 999         SK_U64          OverflowStatus;
 
1005         SK_EVPARA       EventParam;
 
1009         SK_PNMI_ESTIMATE *pEst;
 
1012         SK_PNMI_VCT     *pVctBackupData;
 
1019         if (Event != SK_PNMI_EVT_XMAC_RESET) {
 
1021                 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1022                         ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n",
 
1023                         (unsigned int)Event, (unsigned int)Param.Para64));
 
1026         SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call");
 
1028         MacType = pAC->GIni.GIMacType;
 
1032         case SK_PNMI_EVT_SIRQ_OVERFLOW:
 
1033                 PhysPortIndex = (int)Param.Para32[0];
 
1034                 MacStatus = (SK_U16)Param.Para32[1];
 
1036                 if (PhysPortIndex >= SK_MAX_MACS) {
 
1038                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1039                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter"
 
1040                                  " wrong, PhysPortIndex=0x%x\n",
 
1048                  * Check which source caused an overflow interrupt.
 
1050                 if ((pAC->GIni.GIFunc.pFnMacOverflow(pAC, IoC, PhysPortIndex,
 
1051                                 MacStatus, &OverflowStatus) != 0) ||
 
1052                         (OverflowStatus == 0)) {
 
1054                         SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
 
1059                  * Check the overflow status register and increment
 
1060                  * the upper dword of corresponding counter.
 
1062                 for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8;
 
1065                         Mask = (SK_U64)1 << CounterIndex;
 
1066                         if ((OverflowStatus & Mask) == 0) {
 
1071                         switch (StatOvrflwBit[CounterIndex][MacType]) {
 
1073                         case SK_PNMI_HTX_UTILUNDER:
 
1074                         case SK_PNMI_HTX_UTILOVER:
 
1075                                 if (MacType == SK_MAC_XMAC) {
 
1076                                         XM_IN16(IoC, PhysPortIndex, XM_TX_CMD, &Register);
 
1077                                         Register |= XM_TX_SAM_LINE;
 
1078                                         XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD, Register);
 
1082                         case SK_PNMI_HRX_UTILUNDER:
 
1083                         case SK_PNMI_HRX_UTILOVER:
 
1084                                 if (MacType == SK_MAC_XMAC) {
 
1085                                         XM_IN16(IoC, PhysPortIndex, XM_RX_CMD, &Register);
 
1086                                         Register |= XM_RX_SAM_LINE;
 
1087                                         XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD, Register);
 
1091                         case SK_PNMI_HTX_OCTETHIGH:
 
1092                         case SK_PNMI_HTX_OCTETLOW:
 
1093                         case SK_PNMI_HTX_RESERVED:
 
1094                         case SK_PNMI_HRX_OCTETHIGH:
 
1095                         case SK_PNMI_HRX_OCTETLOW:
 
1096                         case SK_PNMI_HRX_IRLENGTH:
 
1097                         case SK_PNMI_HRX_RESERVED:
 
1100                          * the following counters aren't be handled (id > 63)
 
1102                         case SK_PNMI_HTX_SYNC:
 
1103                         case SK_PNMI_HTX_SYNC_OCTET:
 
1106                         case SK_PNMI_HRX_LONGFRAMES:
 
1107                                 if (MacType == SK_MAC_GMAC) {
 
1108                                         pAC->Pnmi.Port[PhysPortIndex].
 
1109                                                 CounterHigh[CounterIndex] ++;
 
1114                                 pAC->Pnmi.Port[PhysPortIndex].
 
1115                                         CounterHigh[CounterIndex] ++;
 
1120         case SK_PNMI_EVT_SEN_WAR_LOW:
 
1122                 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
 
1124                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1125                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n",
 
1126                                 (unsigned int)Param.Para64));
 
1132                  * Store a trap message in the trap buffer and generate
 
1133                  * an event for user space applications with the
 
1134                  * SK_DRIVER_SENDEVENT macro.
 
1136                 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW,
 
1137                         (unsigned int)Param.Para64);
 
1138                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
 
1141         case SK_PNMI_EVT_SEN_WAR_UPP:
 
1143                 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
 
1145                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1146                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n",
 
1147                                 (unsigned int)Param.Para64));
 
1153                  * Store a trap message in the trap buffer and generate
 
1154                  * an event for user space applications with the
 
1155                  * SK_DRIVER_SENDEVENT macro.
 
1157                 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP,
 
1158                         (unsigned int)Param.Para64);
 
1159                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
 
1162         case SK_PNMI_EVT_SEN_ERR_LOW:
 
1164                 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
 
1166                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1167                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n",
 
1168                                 (unsigned int)Param.Para64));
 
1174                  * Store a trap message in the trap buffer and generate
 
1175                  * an event for user space applications with the
 
1176                  * SK_DRIVER_SENDEVENT macro.
 
1178                 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW,
 
1179                         (unsigned int)Param.Para64);
 
1180                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
 
1183         case SK_PNMI_EVT_SEN_ERR_UPP:
 
1185                 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
 
1187                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1188                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
 
1189                                 (unsigned int)Param.Para64));
 
1195                  * Store a trap message in the trap buffer and generate
 
1196                  * an event for user space applications with the
 
1197                  * SK_DRIVER_SENDEVENT macro.
 
1199                 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP,
 
1200                         (unsigned int)Param.Para64);
 
1201                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
 
1204         case SK_PNMI_EVT_CHG_EST_TIMER:
 
1206                  * Calculate port switch average on a per hour basis
 
1207                  *   Time interval for check       : 28125 ms
 
1208                  *   Number of values for average  : 8
 
1210                  * Be careful in changing these values, on change check
 
1211                  *   - typedef of SK_PNMI_ESTIMATE (Size of EstValue
 
1212                  *     array one less than value number)
 
1213                  *   - Timer initialization SkTimerStart() in SkPnmiInit
 
1214                  *   - Delta value below must be multiplicated with
 
1218                 pEst = &pAC->Pnmi.RlmtChangeEstimate;
 
1219                 CounterIndex = pEst->EstValueIndex + 1;
 
1220                 if (CounterIndex == 7) {
 
1224                 pEst->EstValueIndex = CounterIndex;
 
1226                 NewestValue = pAC->Pnmi.RlmtChangeCts;
 
1227                 OldestValue = pEst->EstValue[CounterIndex];
 
1228                 pEst->EstValue[CounterIndex] = NewestValue;
 
1231                  * Calculate average. Delta stores the number of
 
1232                  * port switches per 28125 * 8 = 225000 ms
 
1234                 if (NewestValue >= OldestValue) {
 
1236                         Delta = NewestValue - OldestValue;
 
1239                         /* Overflow situation */
 
1240                         Delta = (SK_U64)(0 - OldestValue) + NewestValue;
 
1244                  * Extrapolate delta to port switches per hour.
 
1245                  *     Estimate = Delta * (3600000 / 225000)
 
1249                 pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4;
 
1252                  * Check if threshold is exceeded. If the threshold is
 
1253                  * permanently exceeded every 28125 ms an event will be
 
1254                  * generated to remind the user of this condition.
 
1256                 if ((pAC->Pnmi.RlmtChangeThreshold != 0) &&
 
1257                         (pAC->Pnmi.RlmtChangeEstimate.Estimate >=
 
1258                         pAC->Pnmi.RlmtChangeThreshold)) {
 
1260                         QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES);
 
1261                         (void)SK_DRIVER_SENDEVENT(pAC, IoC);
 
1264                 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
 
1265                 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
 
1266                         28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
 
1270         case SK_PNMI_EVT_CLEAR_COUNTER:
 
1272                  *  Param.Para32[0] contains the NetIndex (0 ..1).
 
1273                  *  Param.Para32[1] is reserved, contains -1.
 
1275                 NetIndex = (SK_U32)Param.Para32[0];
 
1278                 if (NetIndex >= pAC->Rlmt.NumNets) {
 
1280                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1281                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
 
1289                  * Set all counters and timestamps to zero.
 
1290                  * The according NetIndex is required as a
 
1291                  * parameter of the event.
 
1293                 ResetCounter(pAC, IoC, NetIndex);
 
1296         case SK_PNMI_EVT_XMAC_RESET:
 
1298                  * To grant continuous counter values store the current
 
1299                  * XMAC statistic values to the entries 1..n of the
 
1300                  * CounterOffset array. XMAC Errata #2
 
1303                 if ((unsigned int)Param.Para64 >= SK_MAX_MACS) {
 
1305                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1306                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n",
 
1307                                 (unsigned int)Param.Para64));
 
1311                 PhysPortIndex = (unsigned int)Param.Para64;
 
1314                  * Update XMAC statistic to get fresh values
 
1316                 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
 
1317                 if (Ret != SK_PNMI_ERR_OK) {
 
1319                         SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
 
1323                  * Increment semaphore to indicate that an update was
 
1326                 pAC->Pnmi.MacUpdatedFlag ++;
 
1328                 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
 
1331                         if (!StatAddr[CounterIndex][MacType].GetOffset) {
 
1336                         pAC->Pnmi.Port[PhysPortIndex].CounterOffset[CounterIndex] =
 
1337                                 GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
 
1339                         pAC->Pnmi.Port[PhysPortIndex].CounterHigh[CounterIndex] = 0;
 
1342                 pAC->Pnmi.MacUpdatedFlag --;
 
1345         case SK_PNMI_EVT_RLMT_PORT_UP:
 
1346                 PhysPortIndex = (unsigned int)Param.Para32[0];
 
1348                 if (PhysPortIndex >= SK_MAX_MACS) {
 
1350                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1351                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter"
 
1352                  " wrong, PhysPortIndex=%d\n", PhysPortIndex));
 
1359                  * Store a trap message in the trap buffer and generate an event for
 
1360                  * user space applications with the SK_DRIVER_SENDEVENT macro.
 
1362                 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
 
1363                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
 
1365                 /* Bugfix for XMAC errata (#10620)*/
 
1366                 if (MacType == SK_MAC_XMAC) {
 
1367                         /* Add incremental difference to offset (#10620)*/
 
1368                         (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
1369                                 XM_RXE_SHT_ERR, &Val32);
 
1371                         Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
 
1372                                  CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
 
1373                         pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
 
1374                                 Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
 
1377                 /* Tell VctStatus() that a link was up meanwhile. */
 
1378                 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK;         
 
1381     case SK_PNMI_EVT_RLMT_PORT_DOWN:
 
1382                 PhysPortIndex = (unsigned int)Param.Para32[0];
 
1385                 if (PhysPortIndex >= SK_MAX_MACS) {
 
1387                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1388                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter"
 
1389                  " wrong, PhysPortIndex=%d\n", PhysPortIndex));
 
1396                  * Store a trap message in the trap buffer and generate an event for
 
1397                  * user space applications with the SK_DRIVER_SENDEVENT macro.
 
1399                 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
 
1400                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
 
1402                 /* Bugfix #10620 - get zero level for incremental difference */
 
1403                 if (MacType == SK_MAC_XMAC) {
 
1405                         (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
1406                                 XM_RXE_SHT_ERR, &Val32);
 
1408                         pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark =
 
1409                                 (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
 
1410                                  CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
 
1414         case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
 
1415                 PhysPortIndex = (unsigned int)Param.Para32[0];
 
1416                 NetIndex = (SK_U32)Param.Para32[1];
 
1419                 if (PhysPortIndex >= SK_MAX_MACS) {
 
1421                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1422                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
 
1426                 if (NetIndex >= pAC->Rlmt.NumNets) {
 
1428                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1429                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
 
1435                  * For now, ignore event if NetIndex != 0.
 
1437                 if (Param.Para32[1] != 0) {
 
1443                  * Nothing to do if port is already inactive
 
1445                 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
 
1451                  * Update statistic counters to calculate new offset for the virtual
 
1452                  * port and increment semaphore to indicate that an update was already
 
1455                 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
 
1458                         SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
 
1461                 pAC->Pnmi.MacUpdatedFlag ++;
 
1464                  * Calculate new counter offset for virtual port to grant continous
 
1465                  * counting on port switches. The virtual port consists of all currently
 
1466                  * active ports. The port down event indicates that a port is removed
 
1467                  * from the virtual port. Therefore add the counter value of the removed
 
1468                  * port to the CounterOffset for the virtual port to grant the same
 
1471                 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
 
1474                         if (!StatAddr[CounterIndex][MacType].GetOffset) {
 
1479                         Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
 
1481                         pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
 
1485                  * Set port to inactive
 
1487                 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
 
1489                 pAC->Pnmi.MacUpdatedFlag --;
 
1492         case SK_PNMI_EVT_RLMT_ACTIVE_UP:
 
1493                 PhysPortIndex = (unsigned int)Param.Para32[0];
 
1494                 NetIndex = (SK_U32)Param.Para32[1];
 
1497                 if (PhysPortIndex >= SK_MAX_MACS) {
 
1499                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1500                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
 
1504                 if (NetIndex >= pAC->Rlmt.NumNets) {
 
1506                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1507                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
 
1513                  * For now, ignore event if NetIndex != 0.
 
1515                 if (Param.Para32[1] != 0) {
 
1521                  * Nothing to do if port is already active
 
1523                 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
 
1529                  * Statistic maintenance
 
1531                 pAC->Pnmi.RlmtChangeCts ++;
 
1532                 pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
 
1535                  * Store a trap message in the trap buffer and generate an event for
 
1536                  * user space applications with the SK_DRIVER_SENDEVENT macro.
 
1538                 QueueRlmtNewMacTrap(pAC, PhysPortIndex);
 
1539                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
 
1542                  * Update statistic counters to calculate new offset for the virtual
 
1543                  * port and increment semaphore to indicate that an update was
 
1546                 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
 
1549                         SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
 
1552                 pAC->Pnmi.MacUpdatedFlag ++;
 
1555                  * Calculate new counter offset for virtual port to grant continous
 
1556                  * counting on port switches. A new port is added to the virtual port.
 
1557                  * Therefore substract the counter value of the new port from the
 
1558                  * CounterOffset for the virtual port to grant the same value.
 
1560                 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
 
1563                         if (!StatAddr[CounterIndex][MacType].GetOffset) {
 
1568                         Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
 
1570                         pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
 
1573                 /* Set port to active */
 
1574                 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
 
1576                 pAC->Pnmi.MacUpdatedFlag --;
 
1579         case SK_PNMI_EVT_RLMT_SEGMENTATION:
 
1581                  * Para.Para32[0] contains the NetIndex.
 
1585                  * Store a trap message in the trap buffer and generate an event for
 
1586                  * user space applications with the SK_DRIVER_SENDEVENT macro.
 
1588                 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
 
1589                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
 
1592     case SK_PNMI_EVT_RLMT_SET_NETS:
 
1594                  *  Param.Para32[0] contains the number of Nets.
 
1595                  *  Param.Para32[1] is reserved, contains -1.
 
1598          * Check number of nets
 
1600                 MaxNetNumber = pAC->GIni.GIMacsFound;
 
1601                 if (((unsigned int)Param.Para32[0] < 1)
 
1602                         || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
 
1603                         return (SK_PNMI_ERR_UNKNOWN_NET);
 
1606         if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
 
1607                 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
 
1609         else { /* dual net mode */
 
1610                 pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
 
1614     case SK_PNMI_EVT_VCT_RESET:
 
1615                 PhysPortIndex = Param.Para32[0];
 
1616                 pPrt = &pAC->GIni.GP[PhysPortIndex];
 
1617                 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
 
1619                 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
 
1620                         RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
 
1623                                  * VCT test is still running.
 
1624                                  * Start VCT timer counter again.
 
1626                                 SK_MEMSET((char *) &Param, 0, sizeof(Param));
 
1627                                 Param.Para32[0] = PhysPortIndex;
 
1628                                 Param.Para32[1] = -1;
 
1629                                 SkTimerStart(pAC, IoC,
 
1630                                         &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
 
1631                                 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
 
1634                         pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
 
1635                         pAC->Pnmi.VctStatus[PhysPortIndex] |=
 
1636                                 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
 
1638                         /* Copy results for later use to PNMI struct. */
 
1639                         for (i = 0; i < 4; i++)  {
 
1640                                 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
 
1641                                         if ((pPrt->PMdiPairLen[i] > 35) &&
 
1642                                                 (pPrt->PMdiPairLen[i] < 0xff)) {
 
1643                                                 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
 
1646                                 if ((pPrt->PMdiPairLen[i] > 35) &&
 
1647                                         (pPrt->PMdiPairLen[i] != 0xff)) {
 
1648                                         CableLength = 1000 *
 
1649                                                 (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
 
1654                                 pVctBackupData->PMdiPairLen[i] = CableLength;
 
1655                                 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
 
1658                         Param.Para32[0] = PhysPortIndex;
 
1659                         Param.Para32[1] = -1;
 
1660                         SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
 
1661                         SkEventDispatcher(pAC, IoC);
 
1670         SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
 
1675 /******************************************************************************
 
1681 /*****************************************************************************
 
1683  * PnmiVar - Gets, presets, and sets single OIDs
 
1686  *      Looks up the requested OID, calls the corresponding handler
 
1687  *      function, and passes the parameters with the get, preset, or
 
1688  *      set command. The function is called by SkGePnmiGetVar,
 
1689  *      SkGePnmiPreSetVar, or SkGePnmiSetVar.
 
1692  *      SK_PNMI_ERR_XXX. For details have a look at the description of the
 
1693  *      calling functions.
 
1694  *      SK_PNMI_ERR_UNKNOWN_NET  The requested NetIndex doesn't exist
 
1696 PNMI_STATIC int PnmiVar(
 
1697 SK_AC *pAC,             /* Pointer to adapter context */
 
1698 SK_IOC IoC,             /* IO context handle */
 
1699 int Action,             /* GET/PRESET/SET action */
 
1700 SK_U32 Id,              /* Object ID that is to be processed */
 
1701 char *pBuf,             /* Buffer used for the management data transfer */
 
1702 unsigned int *pLen,     /* Total length of pBuf management data  */
 
1703 SK_U32 Instance,        /* Instance (1..n) that is to be set or -1 */
 
1704 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
1706         unsigned int    TableIndex;
 
1710         if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
 
1713                 return (SK_PNMI_ERR_UNKNOWN_OID);
 
1716     /* Check NetIndex */
 
1717         if (NetIndex >= pAC->Rlmt.NumNets) {
 
1718                 return (SK_PNMI_ERR_UNKNOWN_NET);
 
1721         SK_PNMI_CHECKFLAGS("PnmiVar: On call");
 
1723         Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
 
1724                 Instance, TableIndex, NetIndex);
 
1726         SK_PNMI_CHECKFLAGS("PnmiVar: On return");
 
1731 /*****************************************************************************
 
1733  * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA
 
1736  *      The return value of the function will also be stored in
 
1737  *      SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
 
1738  *      SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable,
 
1739  *      checks which OIDs are able to set, and calls the handler function of
 
1740  *      the OID to perform the set. The return value of the function will
 
1741  *      also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
 
1742  *      minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called
 
1743  *      by SkGePnmiPreSetStruct and SkGePnmiSetStruct.
 
1746  *      SK_PNMI_ERR_XXX. The codes are described in the calling functions.
 
1747  *      SK_PNMI_ERR_UNKNOWN_NET  The requested NetIndex doesn't exist
 
1749 PNMI_STATIC int PnmiStruct(
 
1750 SK_AC *pAC,             /* Pointer to adapter context */
 
1751 SK_IOC IoC,             /* IO context handle */
 
1752 int  Action,    /* PRESET/SET action to be performed */
 
1753 char *pBuf,             /* Buffer used for the management data transfer */
 
1754 unsigned int *pLen,     /* Length of pBuf management data buffer */
 
1755 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
1758         unsigned int    TableIndex;
 
1759         unsigned int    DstOffset;
 
1761         unsigned int    InstanceNo;
 
1762         unsigned int    InstanceCnt;
 
1767         /* Check if the passed buffer has the right size */
 
1768         if (*pLen < SK_PNMI_STRUCT_SIZE) {
 
1770                 /* Check if we can return the error within the buffer */
 
1771                 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
 
1773                         SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
 
1777                 *pLen = SK_PNMI_STRUCT_SIZE;
 
1778                 return (SK_PNMI_ERR_TOO_SHORT);
 
1781     /* Check NetIndex */
 
1782         if (NetIndex >= pAC->Rlmt.NumNets) {
 
1783                 return (SK_PNMI_ERR_UNKNOWN_NET);
 
1786         SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
 
1789          * Update the values of RLMT and SIRQ and increment semaphores to
 
1790          * indicate that an update was already done.
 
1792         if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
 
1794                 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
 
1795                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
 
1799         if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
 
1801                 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
 
1802                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
 
1806         pAC->Pnmi.RlmtUpdatedFlag ++;
 
1807         pAC->Pnmi.SirqUpdatedFlag ++;
 
1809         /* Preset/Set values */
 
1810         for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
 
1812                 if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
 
1813                         (IdTable[TableIndex].Access != SK_PNMI_WO)) {
 
1818                 InstanceNo = IdTable[TableIndex].InstanceNo;
 
1819                 Id = IdTable[TableIndex].Id;
 
1821                 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
 
1824                         DstOffset = IdTable[TableIndex].Offset +
 
1826                                 IdTable[TableIndex].StructSize;
 
1829                          * Because VPD multiple instance variables are
 
1830                          * not setable we do not need to evaluate VPD
 
1831                          * instances. Have a look to VPD instance
 
1832                          * calculation in SkPnmiGetStruct().
 
1834                         Instance = (SK_U32)InstanceCnt;
 
1837                          * Evaluate needed buffer length
 
1840                         Ret = IdTable[TableIndex].Func(pAC, IoC,
 
1841                                 SK_PNMI_GET, IdTable[TableIndex].Id,
 
1842                                 NULL, &Len, Instance, TableIndex, NetIndex);
 
1844                         if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
 
1848                         if (Ret != SK_PNMI_ERR_TOO_SHORT) {
 
1850                                 pAC->Pnmi.RlmtUpdatedFlag --;
 
1851                                 pAC->Pnmi.SirqUpdatedFlag --;
 
1853                                 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
 
1854                                 SK_PNMI_SET_STAT(pBuf,
 
1855                                         SK_PNMI_ERR_GENERAL, DstOffset);
 
1856                                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
 
1857                                 return (SK_PNMI_ERR_GENERAL);
 
1859                         if (Id == OID_SKGE_VPD_ACTION) {
 
1861                                 switch (*(pBuf + DstOffset)) {
 
1863                                 case SK_PNMI_VPD_CREATE:
 
1864                                         Len = 3 + *(pBuf + DstOffset + 3);
 
1867                                 case SK_PNMI_VPD_DELETE:
 
1877                         /* Call the OID handler function */
 
1878                         Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
 
1879                                 IdTable[TableIndex].Id, pBuf + DstOffset,
 
1880                                 &Len, Instance, TableIndex, NetIndex);
 
1882                         if (Ret != SK_PNMI_ERR_OK) {
 
1884                                 pAC->Pnmi.RlmtUpdatedFlag --;
 
1885                                 pAC->Pnmi.SirqUpdatedFlag --;
 
1887                                 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
 
1888                                 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
 
1890                                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
 
1891                                 return (SK_PNMI_ERR_BAD_VALUE);
 
1896         pAC->Pnmi.RlmtUpdatedFlag --;
 
1897         pAC->Pnmi.SirqUpdatedFlag --;
 
1899         SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
 
1900         SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
 
1901         return (SK_PNMI_ERR_OK);
 
1904 /*****************************************************************************
 
1906  * LookupId - Lookup an OID in the IdTable
 
1909  *      Scans the IdTable to find the table entry of an OID.
 
1912  *      The table index or -1 if not found.
 
1914 PNMI_STATIC int LookupId(
 
1915 SK_U32 Id)              /* Object identifier to be searched */
 
1919         for (i = 0; i < ID_TABLE_SIZE; i++) {
 
1921                 if (IdTable[i].Id == Id) {
 
1930 /*****************************************************************************
 
1932  * OidStruct - Handler of OID_SKGE_ALL_DATA
 
1935  *      This OID performs a Get/Preset/SetStruct call and returns all data
 
1936  *      in a SK_PNMI_STRUCT_DATA structure.
 
1939  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
1940  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
1941  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
1942  *                               the correct data (e.g. a 32bit value is
 
1943  *                               needed, but a 16 bit value was passed).
 
1944  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 
1946  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 
1947  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
1948  *                           exist (e.g. port instance 3 on a two port
 
1951 PNMI_STATIC int OidStruct(
 
1952 SK_AC *pAC,             /* Pointer to adapter context */
 
1953 SK_IOC IoC,             /* IO context handle */
 
1954 int Action,             /* GET/PRESET/SET action */
 
1955 SK_U32 Id,              /* Object ID that is to be processed */
 
1956 char *pBuf,             /* Buffer used for the management data transfer */
 
1957 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
1958 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
1959 unsigned int TableIndex, /* Index to the Id table */
 
1960 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
1962         if (Id != OID_SKGE_ALL_DATA) {
 
1964                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
 
1968                 return (SK_PNMI_ERR_GENERAL);
 
1972          * Check instance. We only handle single instance variables
 
1974         if (Instance != (SK_U32)(-1) && Instance != 1) {
 
1977                 return (SK_PNMI_ERR_UNKNOWN_INST);
 
1983                 return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
 
1985         case SK_PNMI_PRESET:
 
1986                 return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
 
1989                 return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
 
1992         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
 
1995         return (SK_PNMI_ERR_GENERAL);
 
1998 /*****************************************************************************
 
2000  * Perform - OID handler of OID_SKGE_ACTION
 
2006  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
2007  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
2008  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
2009  *                               the correct data (e.g. a 32bit value is
 
2010  *                               needed, but a 16 bit value was passed).
 
2011  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 
2013  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 
2014  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
2015  *                           exist (e.g. port instance 3 on a two port
 
2018 PNMI_STATIC int Perform(
 
2019 SK_AC *pAC,             /* Pointer to adapter context */
 
2020 SK_IOC IoC,             /* IO context handle */
 
2021 int Action,             /* GET/PRESET/SET action */
 
2022 SK_U32 Id,              /* Object ID that is to be processed */
 
2023 char *pBuf,             /* Buffer used for the management data transfer */
 
2024 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
2025 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
2026 unsigned int TableIndex, /* Index to the Id table */
 
2027 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
2034          * Check instance. We only handle single instance variables
 
2036         if (Instance != (SK_U32)(-1) && Instance != 1) {
 
2039                 return (SK_PNMI_ERR_UNKNOWN_INST);
 
2042         if (*pLen < sizeof(SK_U32)) {
 
2044                 *pLen = sizeof(SK_U32);
 
2045                 return (SK_PNMI_ERR_TOO_SHORT);
 
2048         /* Check if a get should be performed */
 
2049         if (Action == SK_PNMI_GET) {
 
2051                 /* A get is easy. We always return the same value */
 
2052                 ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
 
2053                 SK_PNMI_STORE_U32(pBuf, ActionOp);
 
2054                 *pLen = sizeof(SK_U32);
 
2056                 return (SK_PNMI_ERR_OK);
 
2059         /* Continue with PRESET/SET action */
 
2060         if (*pLen > sizeof(SK_U32)) {
 
2062                 return (SK_PNMI_ERR_BAD_VALUE);
 
2065         /* Check if the command is a known one */
 
2066         SK_PNMI_READ_U32(pBuf, ActionOp);
 
2067         if (*pLen > sizeof(SK_U32) ||
 
2068                 (ActionOp != SK_PNMI_ACT_IDLE &&
 
2069                 ActionOp != SK_PNMI_ACT_RESET &&
 
2070                 ActionOp != SK_PNMI_ACT_SELFTEST &&
 
2071                 ActionOp != SK_PNMI_ACT_RESETCNT)) {
 
2074                 return (SK_PNMI_ERR_BAD_VALUE);
 
2077         /* A preset ends here */
 
2078         if (Action == SK_PNMI_PRESET) {
 
2080                 return (SK_PNMI_ERR_OK);
 
2085         case SK_PNMI_ACT_IDLE:
 
2089         case SK_PNMI_ACT_RESET:
 
2091                  * Perform a driver reset or something that comes near
 
2094                 Ret = SK_DRIVER_RESET(pAC, IoC);
 
2097                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
 
2100                         return (SK_PNMI_ERR_GENERAL);
 
2104         case SK_PNMI_ACT_SELFTEST:
 
2106                  * Perform a driver selftest or something similar to this.
 
2107                  * Currently this feature is not used and will probably
 
2108                  * implemented in another way.
 
2110                 Ret = SK_DRIVER_SELFTEST(pAC, IoC);
 
2111                 pAC->Pnmi.TestResult = Ret;
 
2114         case SK_PNMI_ACT_RESETCNT:
 
2115                 /* Set all counters and timestamps to zero */
 
2116                 ResetCounter(pAC, IoC, NetIndex);
 
2120                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
 
2123                 return (SK_PNMI_ERR_GENERAL);
 
2126         return (SK_PNMI_ERR_OK);
 
2129 /*****************************************************************************
 
2131  * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX
 
2134  *      Retrieves the statistic values of the virtual port (logical
 
2135  *      index 0). Only special OIDs of NDIS are handled which consist
 
2136  *      of a 32 bit instead of a 64 bit value. The OIDs are public
 
2137  *      because perhaps some other platform can use them too.
 
2140  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
2141  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
2142  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
2143  *                               the correct data (e.g. a 32bit value is
 
2144  *                               needed, but a 16 bit value was passed).
 
2145  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
2146  *                           exist (e.g. port instance 3 on a two port
 
2149 PNMI_STATIC int Mac8023Stat(
 
2150 SK_AC *pAC,             /* Pointer to adapter context */
 
2151 SK_IOC IoC,             /* IO context handle */
 
2152 int Action,             /* GET/PRESET/SET action */
 
2153 SK_U32 Id,              /* Object ID that is to be processed */
 
2154 char *pBuf,             /* Buffer used for the management data transfer */
 
2155 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
2156 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
2157 unsigned int TableIndex,        /* Index to the Id table */
 
2158 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
2163         SK_BOOL Is64BitReq = SK_FALSE;
 
2166          * Only the active Mac is returned
 
2168         if (Instance != (SK_U32)(-1) && Instance != 1) {
 
2171                 return (SK_PNMI_ERR_UNKNOWN_INST);
 
2177         if (Action != SK_PNMI_GET) {
 
2180                 return (SK_PNMI_ERR_READ_ONLY);
 
2186         case OID_802_3_PERMANENT_ADDRESS:
 
2187         case OID_802_3_CURRENT_ADDRESS:
 
2188                 if (*pLen < sizeof(SK_MAC_ADDR)) {
 
2190                         *pLen = sizeof(SK_MAC_ADDR);
 
2191                         return (SK_PNMI_ERR_TOO_SHORT);
 
2196 #ifndef SK_NDIS_64BIT_CTR
 
2197                 if (*pLen < sizeof(SK_U32)) {
 
2198                         *pLen = sizeof(SK_U32);
 
2199                         return (SK_PNMI_ERR_TOO_SHORT);
 
2202 #else /* SK_NDIS_64BIT_CTR */
 
2204                 /* for compatibility, at least 32bit are required for OID */
 
2205                 if (*pLen < sizeof(SK_U32)) {
 
2207                         * but indicate handling for 64bit values,
 
2208                         * if insufficient space is provided
 
2210                         *pLen = sizeof(SK_U64);
 
2211                         return (SK_PNMI_ERR_TOO_SHORT);
 
2214                 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
 
2215 #endif /* SK_NDIS_64BIT_CTR */
 
2220          * Update all statistics, because we retrieve virtual MAC, which
 
2221          * consists of multiple physical statistics and increment semaphore
 
2222          * to indicate that an update was already done.
 
2224         Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
 
2225         if ( Ret != SK_PNMI_ERR_OK) {
 
2230         pAC->Pnmi.MacUpdatedFlag ++;
 
2233          * Get value (MAC Index 0 identifies the virtual MAC)
 
2237         case OID_802_3_PERMANENT_ADDRESS:
 
2238                 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
 
2239                 *pLen = sizeof(SK_MAC_ADDR);
 
2242         case OID_802_3_CURRENT_ADDRESS:
 
2243                 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
 
2244                 *pLen = sizeof(SK_MAC_ADDR);
 
2248                 StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
 
2250                 /* by default 32bit values are evaluated */
 
2252                         StatVal32 = (SK_U32)StatVal;
 
2253                         SK_PNMI_STORE_U32(pBuf, StatVal32);
 
2254                         *pLen = sizeof(SK_U32);
 
2257                         SK_PNMI_STORE_U64(pBuf, StatVal);
 
2258                         *pLen = sizeof(SK_U64);
 
2263         pAC->Pnmi.MacUpdatedFlag --;
 
2265         return (SK_PNMI_ERR_OK);
 
2268 /*****************************************************************************
 
2270  * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX
 
2273  *      Retrieves the MAC statistic data.
 
2276  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
2277  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
2278  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
2279  *                               the correct data (e.g. a 32bit value is
 
2280  *                               needed, but a 16 bit value was passed).
 
2281  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
2282  *                           exist (e.g. port instance 3 on a two port
 
2285 PNMI_STATIC int MacPrivateStat(
 
2286 SK_AC *pAC,             /* Pointer to adapter context */
 
2287 SK_IOC IoC,             /* IO context handle */
 
2288 int Action,             /* GET/PRESET/SET action */
 
2289 SK_U32 Id,              /* Object ID that is to be processed */
 
2290 char *pBuf,             /* Buffer used for the management data transfer */
 
2291 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
2292 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
2293 unsigned int TableIndex, /* Index to the Id table */
 
2294 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
2296         unsigned int    LogPortMax;
 
2297         unsigned int    LogPortIndex;
 
2298         unsigned int    PhysPortMax;
 
2300         unsigned int    Offset;
 
2307         /* Calculate instance if wished. MAC index 0 is the virtual MAC */
 
2308         PhysPortMax = pAC->GIni.GIMacsFound;
 
2309         LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
 
2311         MacType = pAC->GIni.GIMacType;
 
2313         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
 
2317         if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
 
2318                 /* Check instance range */
 
2319                 if ((Instance < 1) || (Instance > LogPortMax)) {
 
2322                         return (SK_PNMI_ERR_UNKNOWN_INST);
 
2324                 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
 
2325                 Limit = LogPortIndex + 1;
 
2328         else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
 
2335         if (Action != SK_PNMI_GET) {
 
2338                 return (SK_PNMI_ERR_READ_ONLY);
 
2342         if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
 
2344                 *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
 
2345                 return (SK_PNMI_ERR_TOO_SHORT);
 
2349          * Update MAC statistic and increment semaphore to indicate that
 
2350          * an update was already done.
 
2352         Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
 
2353         if (Ret != SK_PNMI_ERR_OK) {
 
2358         pAC->Pnmi.MacUpdatedFlag ++;
 
2362         for (; LogPortIndex < Limit; LogPortIndex ++) {
 
2366 /* XXX not yet implemented due to XMAC problems
 
2367                 case OID_SKGE_STAT_TX_UTIL:
 
2368                         return (SK_PNMI_ERR_GENERAL);
 
2370 /* XXX not yet implemented due to XMAC problems
 
2371                 case OID_SKGE_STAT_RX_UTIL:
 
2372                         return (SK_PNMI_ERR_GENERAL);
 
2374                 case OID_SKGE_STAT_RX:
 
2375                         if (MacType == SK_MAC_GMAC) {
 
2377                                         GetStatVal(pAC, IoC, LogPortIndex,
 
2378                                                            SK_PNMI_HRX_BROADCAST, NetIndex) +
 
2379                                         GetStatVal(pAC, IoC, LogPortIndex,
 
2380                                                            SK_PNMI_HRX_MULTICAST, NetIndex) +
 
2381                                         GetStatVal(pAC, IoC, LogPortIndex,
 
2382                                                            SK_PNMI_HRX_UNICAST, NetIndex) +
 
2383                                         GetStatVal(pAC, IoC, LogPortIndex,
 
2384                                                            SK_PNMI_HRX_UNDERSIZE, NetIndex);
 
2387                                 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
 
2388                                         IdTable[TableIndex].Param, NetIndex);
 
2392                 case OID_SKGE_STAT_TX:
 
2393                         if (MacType == SK_MAC_GMAC) {
 
2395                                         GetStatVal(pAC, IoC, LogPortIndex,
 
2396                                                            SK_PNMI_HTX_BROADCAST, NetIndex) +
 
2397                                         GetStatVal(pAC, IoC, LogPortIndex,
 
2398                                                            SK_PNMI_HTX_MULTICAST, NetIndex) +
 
2399                                         GetStatVal(pAC, IoC, LogPortIndex,
 
2400                                                            SK_PNMI_HTX_UNICAST, NetIndex);
 
2403                                 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
 
2404                                         IdTable[TableIndex].Param, NetIndex);
 
2409                         StatVal = GetStatVal(pAC, IoC, LogPortIndex,
 
2410                                 IdTable[TableIndex].Param, NetIndex);
 
2412                 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
 
2414                 Offset += sizeof(SK_U64);
 
2418         pAC->Pnmi.MacUpdatedFlag --;
 
2420         return (SK_PNMI_ERR_OK);
 
2423 /*****************************************************************************
 
2425  * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR
 
2428  *      Get/Presets/Sets the current and factory MAC address. The MAC
 
2429  *      address of the virtual port, which is reported to the OS, may
 
2430  *      not be changed, but the physical ones. A set to the virtual port
 
2431  *      will be ignored. No error should be reported because otherwise
 
2432  *      a multiple instance set (-1) would always fail.
 
2435  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
2436  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
2437  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
2438  *                               the correct data (e.g. a 32bit value is
 
2439  *                               needed, but a 16 bit value was passed).
 
2440  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 
2442  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 
2443  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
2444  *                           exist (e.g. port instance 3 on a two port
 
2447 PNMI_STATIC int Addr(
 
2448 SK_AC *pAC,             /* Pointer to adapter context */
 
2449 SK_IOC IoC,             /* IO context handle */
 
2450 int Action,             /* GET/PRESET/SET action */
 
2451 SK_U32 Id,              /* Object ID that is to be processed */
 
2452 char *pBuf,             /* Buffer used for the management data transfer */
 
2453 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
2454 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
2455 unsigned int TableIndex, /* Index to the Id table */
 
2456 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
2459         unsigned int    LogPortMax;
 
2460         unsigned int    PhysPortMax;
 
2461         unsigned int    LogPortIndex;
 
2462         unsigned int    PhysPortIndex;
 
2464         unsigned int    Offset = 0;
 
2467          * Calculate instance if wished. MAC index 0 is the virtual
 
2470         PhysPortMax = pAC->GIni.GIMacsFound;
 
2471         LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
 
2473         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
 
2477         if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
 
2478                 /* Check instance range */
 
2479                 if ((Instance < 1) || (Instance > LogPortMax)) {
 
2482                         return (SK_PNMI_ERR_UNKNOWN_INST);
 
2484                 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
 
2485                 Limit = LogPortIndex + 1;
 
2487         else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
 
2496         if (Action == SK_PNMI_GET) {
 
2499                 if (*pLen < (Limit - LogPortIndex) * 6) {
 
2501                         *pLen = (Limit - LogPortIndex) * 6;
 
2502                         return (SK_PNMI_ERR_TOO_SHORT);
 
2508                 for (; LogPortIndex < Limit; LogPortIndex ++) {
 
2512                         case OID_SKGE_PHYS_CUR_ADDR:
 
2513                                 if (LogPortIndex == 0) {
 
2514                                         CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
 
2517                                         PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
 
2519                                         CopyMac(pBuf + Offset,
 
2520                                                 &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
 
2525                         case OID_SKGE_PHYS_FAC_ADDR:
 
2526                                 if (LogPortIndex == 0) {
 
2527                                         CopyMac(pBuf + Offset,
 
2528                                                 &pAC->Addr.Net[NetIndex].PermanentMacAddress);
 
2531                                         PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
2534                                         CopyMac(pBuf + Offset,
 
2535                                                 &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
 
2541                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
 
2545                                 return (SK_PNMI_ERR_GENERAL);
 
2553                  * The logical MAC address may not be changed only
 
2556                 if (Id == OID_SKGE_PHYS_FAC_ADDR) {
 
2559                         return (SK_PNMI_ERR_READ_ONLY);
 
2563                  * Only the current address may be changed
 
2565                 if (Id != OID_SKGE_PHYS_CUR_ADDR) {
 
2567                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
 
2571                         return (SK_PNMI_ERR_GENERAL);
 
2575                 if (*pLen < (Limit - LogPortIndex) * 6) {
 
2577                         *pLen = (Limit - LogPortIndex) * 6;
 
2578                         return (SK_PNMI_ERR_TOO_SHORT);
 
2580                 if (*pLen > (Limit - LogPortIndex) * 6) {
 
2583                         return (SK_PNMI_ERR_BAD_VALUE);
 
2589                 if (Action == SK_PNMI_PRESET) {
 
2592                         return (SK_PNMI_ERR_OK);
 
2596                  * Set OID_SKGE_MAC_CUR_ADDR
 
2598                 for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
 
2601                          * A set to virtual port and set of broadcast
 
2602                          * address will be ignored
 
2604                         if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
 
2605                                 "\xff\xff\xff\xff\xff\xff", 6) == 0) {
 
2610                         PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
 
2613                         Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
 
2614                                 (SK_MAC_ADDR *)(pBuf + Offset),
 
2615                                 (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
 
2616                                 SK_ADDR_PHYSICAL_ADDRESS));
 
2617                         if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {
 
2619                                 return (SK_PNMI_ERR_GENERAL);
 
2625         return (SK_PNMI_ERR_OK);
 
2628 /*****************************************************************************
 
2630  * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
 
2633  *      Retrieves the statistic values of the CSUM module. The CSUM data
 
2634  *      structure must be available in the SK_AC even if the CSUM module
 
2635  *      is not included, because PNMI reads the statistic data from the
 
2636  *      CSUM part of SK_AC directly.
 
2639  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
2640  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
2641  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
2642  *                               the correct data (e.g. a 32bit value is
 
2643  *                               needed, but a 16 bit value was passed).
 
2644  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
2645  *                           exist (e.g. port instance 3 on a two port
 
2648 PNMI_STATIC int CsumStat(
 
2649 SK_AC *pAC,             /* Pointer to adapter context */
 
2650 SK_IOC IoC,             /* IO context handle */
 
2651 int Action,             /* GET/PRESET/SET action */
 
2652 SK_U32 Id,              /* Object ID that is to be processed */
 
2653 char *pBuf,             /* Buffer used for the management data transfer */
 
2654 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
2655 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
2656 unsigned int TableIndex, /* Index to the Id table */
 
2657 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
2661         unsigned int    Offset = 0;
 
2666          * Calculate instance if wished
 
2668         if (Instance != (SK_U32)(-1)) {
 
2670                 if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
 
2673                         return (SK_PNMI_ERR_UNKNOWN_INST);
 
2675                 Index = (unsigned int)Instance - 1;
 
2680                 Limit = SKCS_NUM_PROTOCOLS;
 
2686         if (Action != SK_PNMI_GET) {
 
2689                 return (SK_PNMI_ERR_READ_ONLY);
 
2693         if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
 
2695                 *pLen = (Limit - Index) * sizeof(SK_U64);
 
2696                 return (SK_PNMI_ERR_TOO_SHORT);
 
2702         for (; Index < Limit; Index ++) {
 
2706                 case OID_SKGE_CHKSM_RX_OK_CTS:
 
2707                         StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
 
2710                 case OID_SKGE_CHKSM_RX_UNABLE_CTS:
 
2711                         StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
 
2714                 case OID_SKGE_CHKSM_RX_ERR_CTS:
 
2715                         StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
 
2718                 case OID_SKGE_CHKSM_TX_OK_CTS:
 
2719                         StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
 
2722                 case OID_SKGE_CHKSM_TX_UNABLE_CTS:
 
2723                         StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
 
2727                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
 
2731                         return (SK_PNMI_ERR_GENERAL);
 
2734                 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
 
2735                 Offset += sizeof(SK_U64);
 
2739          * Store used buffer space
 
2743         return (SK_PNMI_ERR_OK);
 
2746 /*****************************************************************************
 
2748  * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
 
2751  *      Retrieves the statistic values of the I2C module, which handles
 
2752  *      the temperature and voltage sensors.
 
2755  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
2756  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
2757  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
2758  *                               the correct data (e.g. a 32bit value is
 
2759  *                               needed, but a 16 bit value was passed).
 
2760  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
2761  *                           exist (e.g. port instance 3 on a two port
 
2764 PNMI_STATIC int SensorStat(
 
2765 SK_AC *pAC,             /* Pointer to adapter context */
 
2766 SK_IOC IoC,             /* IO context handle */
 
2767 int Action,             /* GET/PRESET/SET action */
 
2768 SK_U32 Id,              /* Object ID that is to be processed */
 
2769 char *pBuf,             /* Buffer used for the management data transfer */
 
2770 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
2771 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
2772 unsigned int TableIndex, /* Index to the Id table */
 
2773 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
2778         unsigned int    Offset;
 
2785          * Calculate instance if wished
 
2787         if ((Instance != (SK_U32)(-1))) {
 
2789                 if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
 
2792                         return (SK_PNMI_ERR_UNKNOWN_INST);
 
2795                 Index = (unsigned int)Instance -1;
 
2796                 Limit = (unsigned int)Instance;
 
2800                 Limit = (unsigned int) pAC->I2c.MaxSens;
 
2806         if (Action != SK_PNMI_GET) {
 
2809                 return (SK_PNMI_ERR_READ_ONLY);
 
2815         case OID_SKGE_SENSOR_VALUE:
 
2816         case OID_SKGE_SENSOR_WAR_THRES_LOW:
 
2817         case OID_SKGE_SENSOR_WAR_THRES_UPP:
 
2818         case OID_SKGE_SENSOR_ERR_THRES_LOW:
 
2819         case OID_SKGE_SENSOR_ERR_THRES_UPP:
 
2820                 if (*pLen < (Limit - Index) * sizeof(SK_U32)) {
 
2822                         *pLen = (Limit - Index) * sizeof(SK_U32);
 
2823                         return (SK_PNMI_ERR_TOO_SHORT);
 
2827         case OID_SKGE_SENSOR_DESCR:
 
2828                 for (Offset = 0, i = Index; i < Limit; i ++) {
 
2830                         Len = (unsigned int)
 
2831                                 SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1;
 
2832                         if (Len >= SK_PNMI_STRINGLEN2) {
 
2834                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011,
 
2838                                 return (SK_PNMI_ERR_GENERAL);
 
2842                 if (*pLen < Offset) {
 
2845                         return (SK_PNMI_ERR_TOO_SHORT);
 
2849         case OID_SKGE_SENSOR_INDEX:
 
2850         case OID_SKGE_SENSOR_TYPE:
 
2851         case OID_SKGE_SENSOR_STATUS:
 
2852                 if (*pLen < Limit - Index) {
 
2854                         *pLen = Limit - Index;
 
2855                         return (SK_PNMI_ERR_TOO_SHORT);
 
2859         case OID_SKGE_SENSOR_WAR_CTS:
 
2860         case OID_SKGE_SENSOR_WAR_TIME:
 
2861         case OID_SKGE_SENSOR_ERR_CTS:
 
2862         case OID_SKGE_SENSOR_ERR_TIME:
 
2863                 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
 
2865                         *pLen = (Limit - Index) * sizeof(SK_U64);
 
2866                         return (SK_PNMI_ERR_TOO_SHORT);
 
2871                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
 
2875                 return (SK_PNMI_ERR_GENERAL);
 
2882         for (Offset = 0; Index < Limit; Index ++) {
 
2886                 case OID_SKGE_SENSOR_INDEX:
 
2887                         *(pBuf + Offset) = (char)Index;
 
2888                         Offset += sizeof(char);
 
2891                 case OID_SKGE_SENSOR_DESCR:
 
2892                         Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
 
2893                         SK_MEMCPY(pBuf + Offset + 1,
 
2894                                 pAC->I2c.SenTable[Index].SenDesc, Len);
 
2895                         *(pBuf + Offset) = (char)Len;
 
2899                 case OID_SKGE_SENSOR_TYPE:
 
2901                                 (char)pAC->I2c.SenTable[Index].SenType;
 
2902                         Offset += sizeof(char);
 
2905                 case OID_SKGE_SENSOR_VALUE:
 
2906                         Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
 
2907                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
2908                         Offset += sizeof(SK_U32);
 
2911                 case OID_SKGE_SENSOR_WAR_THRES_LOW:
 
2912                         Val32 = (SK_U32)pAC->I2c.SenTable[Index].
 
2914                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
2915                         Offset += sizeof(SK_U32);
 
2918                 case OID_SKGE_SENSOR_WAR_THRES_UPP:
 
2919                         Val32 = (SK_U32)pAC->I2c.SenTable[Index].
 
2921                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
2922                         Offset += sizeof(SK_U32);
 
2925                 case OID_SKGE_SENSOR_ERR_THRES_LOW:
 
2926                         Val32 = (SK_U32)pAC->I2c.SenTable[Index].
 
2928                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
2929                         Offset += sizeof(SK_U32);
 
2932                 case OID_SKGE_SENSOR_ERR_THRES_UPP:
 
2933                         Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
 
2934                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
2935                         Offset += sizeof(SK_U32);
 
2938                 case OID_SKGE_SENSOR_STATUS:
 
2940                                 (char)pAC->I2c.SenTable[Index].SenErrFlag;
 
2941                         Offset += sizeof(char);
 
2944                 case OID_SKGE_SENSOR_WAR_CTS:
 
2945                         Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
 
2946                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
 
2947                         Offset += sizeof(SK_U64);
 
2950                 case OID_SKGE_SENSOR_ERR_CTS:
 
2951                         Val64 = pAC->I2c.SenTable[Index].SenErrCts;
 
2952                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
 
2953                         Offset += sizeof(SK_U64);
 
2956                 case OID_SKGE_SENSOR_WAR_TIME:
 
2957                         Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
 
2959                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
 
2960                         Offset += sizeof(SK_U64);
 
2963                 case OID_SKGE_SENSOR_ERR_TIME:
 
2964                         Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
 
2966                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
 
2967                         Offset += sizeof(SK_U64);
 
2971                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
 
2972                                 ("SensorStat: Unknown OID should be handled before"));
 
2974                         return (SK_PNMI_ERR_GENERAL);
 
2979          * Store used buffer space
 
2983         return (SK_PNMI_ERR_OK);
 
2986 /*****************************************************************************
 
2988  * Vpd - OID handler function of OID_SKGE_VPD_XXX
 
2991  *      Get/preset/set of VPD data. As instance the name of a VPD key
 
2992  *      can be passed. The Instance parameter is a SK_U32 and can be
 
2993  *      used as a string buffer for the VPD key, because their maximum
 
2997  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
2998  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
2999  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
3000  *                               the correct data (e.g. a 32bit value is
 
3001  *                               needed, but a 16 bit value was passed).
 
3002  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 
3004  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 
3005  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
3006  *                           exist (e.g. port instance 3 on a two port
 
3009 PNMI_STATIC int Vpd(
 
3010 SK_AC *pAC,             /* Pointer to adapter context */
 
3011 SK_IOC IoC,             /* IO context handle */
 
3012 int Action,             /* GET/PRESET/SET action */
 
3013 SK_U32 Id,              /* Object ID that is to be processed */
 
3014 char *pBuf,             /* Buffer used for the management data transfer */
 
3015 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
3016 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
3017 unsigned int TableIndex, /* Index to the Id table */
 
3018 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
3020         SK_VPD_STATUS   *pVpdStatus;
 
3021         unsigned int    BufLen;
 
3023         char            KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
 
3024         char            KeyStr[SK_PNMI_VPD_KEY_SIZE];
 
3026         unsigned int    Offset;
 
3028         unsigned int    FirstIndex;
 
3029         unsigned int    LastIndex;
 
3035          * Get array of all currently stored VPD keys
 
3037         Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &KeyNo);
 
3038         if (Ret != SK_PNMI_ERR_OK) {
 
3044          * If instance is not -1, try to find the requested VPD key for
 
3045          * the multiple instance variables. The other OIDs as for example
 
3046          * OID VPD_ACTION are single instance variables and must be
 
3047          * handled separatly.
 
3052         if ((Instance != (SK_U32)(-1))) {
 
3054                 if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
 
3055                         Id == OID_SKGE_VPD_ACCESS) {
 
3057                         SK_STRNCPY(KeyStr, (char *)&Instance, 4);
 
3060                         for (Index = 0; Index < KeyNo; Index ++) {
 
3062                                 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
 
3064                                         LastIndex = Index+1;
 
3068                         if (Index == KeyNo) {
 
3071                                 return (SK_PNMI_ERR_UNKNOWN_INST);
 
3074                 else if (Instance != 1) {
 
3077                         return (SK_PNMI_ERR_UNKNOWN_INST);
 
3082          * Get value, if a query should be performed
 
3084         if (Action == SK_PNMI_GET) {
 
3088                 case OID_SKGE_VPD_FREE_BYTES:
 
3089                         /* Check length of buffer */
 
3090                         if (*pLen < sizeof(SK_U32)) {
 
3092                                 *pLen = sizeof(SK_U32);
 
3093                                 return (SK_PNMI_ERR_TOO_SHORT);
 
3095                         /* Get number of free bytes */
 
3096                         pVpdStatus = VpdStat(pAC, IoC);
 
3097                         if (pVpdStatus == NULL) {
 
3099                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
 
3103                                 return (SK_PNMI_ERR_GENERAL);
 
3105                         if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
 
3107                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
 
3111                                 return (SK_PNMI_ERR_GENERAL);
 
3114                         Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
 
3115                         SK_PNMI_STORE_U32(pBuf, Val32);
 
3116                         *pLen = sizeof(SK_U32);
 
3119                 case OID_SKGE_VPD_ENTRIES_LIST:
 
3121                         for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
 
3123                                 Len += SK_STRLEN(KeyArr[Index]) + 1;
 
3128                                 return (SK_PNMI_ERR_TOO_SHORT);
 
3132                         *(pBuf) = (char)Len - 1;
 
3133                         for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
 
3135                                 Len = SK_STRLEN(KeyArr[Index]);
 
3136                                 SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
 
3140                                 if (Index < KeyNo - 1) {
 
3142                                         *(pBuf + Offset) = ' ';
 
3149                 case OID_SKGE_VPD_ENTRIES_NUMBER:
 
3151                         if (*pLen < sizeof(SK_U32)) {
 
3153                                 *pLen = sizeof(SK_U32);
 
3154                                 return (SK_PNMI_ERR_TOO_SHORT);
 
3157                         Val32 = (SK_U32)KeyNo;
 
3158                         SK_PNMI_STORE_U32(pBuf, Val32);
 
3159                         *pLen = sizeof(SK_U32);
 
3162                 case OID_SKGE_VPD_KEY:
 
3163                         /* Check buffer length, if it is large enough */
 
3164                         for (Len = 0, Index = FirstIndex;
 
3165                                 Index < LastIndex; Index ++) {
 
3167                                 Len += SK_STRLEN(KeyArr[Index]) + 1;
 
3172                                 return (SK_PNMI_ERR_TOO_SHORT);
 
3176                          * Get the key to an intermediate buffer, because
 
3177                          * we have to prepend a length byte.
 
3179                         for (Offset = 0, Index = FirstIndex;
 
3180                                 Index < LastIndex; Index ++) {
 
3182                                 Len = SK_STRLEN(KeyArr[Index]);
 
3184                                 *(pBuf + Offset) = (char)Len;
 
3185                                 SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
 
3192                 case OID_SKGE_VPD_VALUE:
 
3193                         /* Check the buffer length if it is large enough */
 
3194                         for (Offset = 0, Index = FirstIndex;
 
3195                                 Index < LastIndex; Index ++) {
 
3198                                 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
 
3199                                         (int *)&BufLen) > 0 ||
 
3200                                         BufLen >= SK_PNMI_VPD_DATALEN) {
 
3202                                         SK_ERR_LOG(pAC, SK_ERRCL_SW,
 
3206                                         return (SK_PNMI_ERR_GENERAL);
 
3208                                 Offset += BufLen + 1;
 
3210                         if (*pLen < Offset) {
 
3213                                 return (SK_PNMI_ERR_TOO_SHORT);
 
3217                          * Get the value to an intermediate buffer, because
 
3218                          * we have to prepend a length byte.
 
3220                         for (Offset = 0, Index = FirstIndex;
 
3221                                 Index < LastIndex; Index ++) {
 
3224                                 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
 
3225                                         (int *)&BufLen) > 0 ||
 
3226                                         BufLen >= SK_PNMI_VPD_DATALEN) {
 
3228                                         SK_ERR_LOG(pAC, SK_ERRCL_SW,
 
3233                                         return (SK_PNMI_ERR_GENERAL);
 
3236                                 *(pBuf + Offset) = (char)BufLen;
 
3237                                 SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
 
3238                                 Offset += BufLen + 1;
 
3243                 case OID_SKGE_VPD_ACCESS:
 
3244                         if (*pLen < LastIndex - FirstIndex) {
 
3246                                 *pLen = LastIndex - FirstIndex;
 
3247                                 return (SK_PNMI_ERR_TOO_SHORT);
 
3250                         for (Offset = 0, Index = FirstIndex;
 
3251                                 Index < LastIndex; Index ++) {
 
3253                                 if (VpdMayWrite(KeyArr[Index])) {
 
3255                                         *(pBuf + Offset) = SK_PNMI_VPD_RW;
 
3258                                         *(pBuf + Offset) = SK_PNMI_VPD_RO;
 
3265                 case OID_SKGE_VPD_ACTION:
 
3266                         Offset = LastIndex - FirstIndex;
 
3267                         if (*pLen < Offset) {
 
3270                                 return (SK_PNMI_ERR_TOO_SHORT);
 
3272                         SK_MEMSET(pBuf, 0, Offset);
 
3277                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
 
3281                         return (SK_PNMI_ERR_GENERAL);
 
3285                 /* The only OID which can be set is VPD_ACTION */
 
3286                 if (Id != OID_SKGE_VPD_ACTION) {
 
3288                         if (Id == OID_SKGE_VPD_FREE_BYTES ||
 
3289                                 Id == OID_SKGE_VPD_ENTRIES_LIST ||
 
3290                                 Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
 
3291                                 Id == OID_SKGE_VPD_KEY ||
 
3292                                 Id == OID_SKGE_VPD_VALUE ||
 
3293                                 Id == OID_SKGE_VPD_ACCESS) {
 
3296                                 return (SK_PNMI_ERR_READ_ONLY);
 
3299                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
 
3303                         return (SK_PNMI_ERR_GENERAL);
 
3307                  * From this point we handle VPD_ACTION. Check the buffer
 
3308                  * length. It should at least have the size of one byte.
 
3313                         return (SK_PNMI_ERR_TOO_SHORT);
 
3317                  * The first byte contains the VPD action type we should
 
3322                 case SK_PNMI_VPD_IGNORE:
 
3326                 case SK_PNMI_VPD_CREATE:
 
3328                          * We have to create a new VPD entry or we modify
 
3329                          * an existing one. Check first the buffer length.
 
3334                                 return (SK_PNMI_ERR_TOO_SHORT);
 
3336                         KeyStr[0] = pBuf[1];
 
3337                         KeyStr[1] = pBuf[2];
 
3341                          * Is the entry writable or does it belong to the
 
3344                         if (!VpdMayWrite(KeyStr)) {
 
3347                                 return (SK_PNMI_ERR_BAD_VALUE);
 
3350                         Offset = (int)pBuf[3] & 0xFF;
 
3352                         SK_MEMCPY(Buf, pBuf + 4, Offset);
 
3355                         /* A preset ends here */
 
3356                         if (Action == SK_PNMI_PRESET) {
 
3358                                 return (SK_PNMI_ERR_OK);
 
3361                         /* Write the new entry or modify an existing one */
 
3362                         Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
 
3363                         if (Ret == SK_PNMI_VPD_NOWRITE ) {
 
3366                                 return (SK_PNMI_ERR_BAD_VALUE);
 
3368                         else if (Ret != SK_PNMI_VPD_OK) {
 
3370                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
 
3374                                 return (SK_PNMI_ERR_GENERAL);
 
3378                          * Perform an update of the VPD data. This is
 
3379                          * not mandantory, but just to be sure.
 
3381                         Ret = VpdUpdate(pAC, IoC);
 
3382                         if (Ret != SK_PNMI_VPD_OK) {
 
3384                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
 
3388                                 return (SK_PNMI_ERR_GENERAL);
 
3392                 case SK_PNMI_VPD_DELETE:
 
3393                         /* Check if the buffer size is plausible */
 
3397                                 return (SK_PNMI_ERR_TOO_SHORT);
 
3402                                 return (SK_PNMI_ERR_BAD_VALUE);
 
3404                         KeyStr[0] = pBuf[1];
 
3405                         KeyStr[1] = pBuf[2];
 
3408                         /* Find the passed key in the array */
 
3409                         for (Index = 0; Index < KeyNo; Index ++) {
 
3411                                 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
 
3417                          * If we cannot find the key it is wrong, so we
 
3418                          * return an appropriate error value.
 
3420                         if (Index == KeyNo) {
 
3423                                 return (SK_PNMI_ERR_BAD_VALUE);
 
3426                         if (Action == SK_PNMI_PRESET) {
 
3428                                 return (SK_PNMI_ERR_OK);
 
3431                         /* Ok, you wanted it and you will get it */
 
3432                         Ret = VpdDelete(pAC, IoC, KeyStr);
 
3433                         if (Ret != SK_PNMI_VPD_OK) {
 
3435                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
 
3439                                 return (SK_PNMI_ERR_GENERAL);
 
3443                          * Perform an update of the VPD data. This is
 
3444                          * not mandantory, but just to be sure.
 
3446                         Ret = VpdUpdate(pAC, IoC);
 
3447                         if (Ret != SK_PNMI_VPD_OK) {
 
3449                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
 
3453                                 return (SK_PNMI_ERR_GENERAL);
 
3459                         return (SK_PNMI_ERR_BAD_VALUE);
 
3463         return (SK_PNMI_ERR_OK);
 
3466 /*****************************************************************************
 
3468  * General - OID handler function of various single instance OIDs
 
3471  *      The code is simple. No description necessary.
 
3474  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
3475  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
3476  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
3477  *                               the correct data (e.g. a 32bit value is
 
3478  *                               needed, but a 16 bit value was passed).
 
3479  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
3480  *                           exist (e.g. port instance 3 on a two port
 
3483 PNMI_STATIC int General(
 
3484 SK_AC *pAC,             /* Pointer to adapter context */
 
3485 SK_IOC IoC,             /* IO context handle */
 
3486 int Action,             /* GET/PRESET/SET action */
 
3487 SK_U32 Id,              /* Object ID that is to be processed */
 
3488 char *pBuf,             /* Buffer used for the management data transfer */
 
3489 unsigned int *pLen,     /* On call: buffer length. On return: used buffer */
 
3490 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
3491 unsigned int TableIndex, /* Index to the Id table */
 
3492 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
3497         unsigned int    Offset;
 
3503         SK_U64          Val64RxHwErrs = 0;
 
3504         SK_U64          Val64TxHwErrs = 0;
 
3505         SK_BOOL         Is64BitReq = SK_FALSE;
 
3510          * Check instance. We only handle single instance variables.
 
3512         if (Instance != (SK_U32)(-1) && Instance != 1) {
 
3515                 return (SK_PNMI_ERR_UNKNOWN_INST);
 
3519          * Check action. We only allow get requests.
 
3521         if (Action != SK_PNMI_GET) {
 
3524                 return (SK_PNMI_ERR_READ_ONLY);
 
3527         MacType = pAC->GIni.GIMacType;
 
3530          * Check length for the various supported OIDs
 
3534         case OID_GEN_XMIT_ERROR:
 
3535         case OID_GEN_RCV_ERROR:
 
3536         case OID_GEN_RCV_NO_BUFFER:
 
3537 #ifndef SK_NDIS_64BIT_CTR
 
3538                 if (*pLen < sizeof(SK_U32)) {
 
3539                         *pLen = sizeof(SK_U32);
 
3540                         return (SK_PNMI_ERR_TOO_SHORT);
 
3543 #else /* SK_NDIS_64BIT_CTR */
 
3546                  * for compatibility, at least 32bit are required for oid
 
3548                 if (*pLen < sizeof(SK_U32)) {
 
3550                         * but indicate handling for 64bit values,
 
3551                         * if insufficient space is provided
 
3553                         *pLen = sizeof(SK_U64);
 
3554                         return (SK_PNMI_ERR_TOO_SHORT);
 
3557                 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
 
3558 #endif /* SK_NDIS_64BIT_CTR */
 
3561         case OID_SKGE_PORT_NUMBER:
 
3562         case OID_SKGE_DEVICE_TYPE:
 
3563         case OID_SKGE_RESULT:
 
3564         case OID_SKGE_RLMT_MONITOR_NUMBER:
 
3565         case OID_GEN_TRANSMIT_QUEUE_LENGTH:
 
3566         case OID_SKGE_TRAP_NUMBER:
 
3567         case OID_SKGE_MDB_VERSION:
 
3568         case OID_SKGE_BOARDLEVEL:
 
3569         case OID_SKGE_CHIPID:
 
3570         case OID_SKGE_RAMSIZE:
 
3571                 if (*pLen < sizeof(SK_U32)) {
 
3573                         *pLen = sizeof(SK_U32);
 
3574                         return (SK_PNMI_ERR_TOO_SHORT);
 
3578         case OID_SKGE_CHIPSET:
 
3579                 if (*pLen < sizeof(SK_U16)) {
 
3581                         *pLen = sizeof(SK_U16);
 
3582                         return (SK_PNMI_ERR_TOO_SHORT);
 
3586         case OID_SKGE_BUS_TYPE:
 
3587         case OID_SKGE_BUS_SPEED:
 
3588         case OID_SKGE_BUS_WIDTH:
 
3589         case OID_SKGE_SENSOR_NUMBER:
 
3590         case OID_SKGE_CHKSM_NUMBER:
 
3591         case OID_SKGE_VAUXAVAIL:
 
3592                 if (*pLen < sizeof(SK_U8)) {
 
3594                         *pLen = sizeof(SK_U8);
 
3595                         return (SK_PNMI_ERR_TOO_SHORT);
 
3599         case OID_SKGE_TX_SW_QUEUE_LEN:
 
3600         case OID_SKGE_TX_SW_QUEUE_MAX:
 
3601         case OID_SKGE_TX_RETRY:
 
3602         case OID_SKGE_RX_INTR_CTS:
 
3603         case OID_SKGE_TX_INTR_CTS:
 
3604         case OID_SKGE_RX_NO_BUF_CTS:
 
3605         case OID_SKGE_TX_NO_BUF_CTS:
 
3606         case OID_SKGE_TX_USED_DESCR_NO:
 
3607         case OID_SKGE_RX_DELIVERED_CTS:
 
3608         case OID_SKGE_RX_OCTETS_DELIV_CTS:
 
3609         case OID_SKGE_RX_HW_ERROR_CTS:
 
3610         case OID_SKGE_TX_HW_ERROR_CTS:
 
3611         case OID_SKGE_IN_ERRORS_CTS:
 
3612         case OID_SKGE_OUT_ERROR_CTS:
 
3613         case OID_SKGE_ERR_RECOVERY_CTS:
 
3614         case OID_SKGE_SYSUPTIME:
 
3615                 if (*pLen < sizeof(SK_U64)) {
 
3617                         *pLen = sizeof(SK_U64);
 
3618                         return (SK_PNMI_ERR_TOO_SHORT);
 
3627         /* Update statistic */
 
3628         if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
 
3629                 Id == OID_SKGE_TX_HW_ERROR_CTS ||
 
3630                 Id == OID_SKGE_IN_ERRORS_CTS ||
 
3631                 Id == OID_SKGE_OUT_ERROR_CTS ||
 
3632                 Id == OID_GEN_XMIT_ERROR ||
 
3633                 Id == OID_GEN_RCV_ERROR) {
 
3635                 /* Force the XMAC to update its statistic counters and
 
3636                  * Increment semaphore to indicate that an update was
 
3639                 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
 
3640                 if (Ret != SK_PNMI_ERR_OK) {
 
3645                 pAC->Pnmi.MacUpdatedFlag ++;
 
3648                  * Some OIDs consist of multiple hardware counters. Those
 
3649                  * values which are contained in all of them will be added
 
3654                 case OID_SKGE_RX_HW_ERROR_CTS:
 
3655                 case OID_SKGE_IN_ERRORS_CTS:
 
3656                 case OID_GEN_RCV_ERROR:
 
3658                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
 
3659                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
 
3660                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex) +
 
3661                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
 
3662                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
 
3663                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex) +
 
3664                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
 
3665                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
 
3666                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
 
3667                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
 
3668                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
 
3669                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
 
3672                 case OID_SKGE_TX_HW_ERROR_CTS:
 
3673                 case OID_SKGE_OUT_ERROR_CTS:
 
3674                 case OID_GEN_XMIT_ERROR:
 
3676                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
 
3677                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex) +
 
3678                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex) +
 
3679                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex);
 
3689         case OID_SKGE_SUPPORTED_LIST:
 
3690                 Len = ID_TABLE_SIZE * sizeof(SK_U32);
 
3694                         return (SK_PNMI_ERR_TOO_SHORT);
 
3696                 for (Offset = 0, Index = 0; Offset < Len;
 
3697                         Offset += sizeof(SK_U32), Index ++) {
 
3699                         Val32 = (SK_U32)IdTable[Index].Id;
 
3700                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
3705         case OID_SKGE_BOARDLEVEL:
 
3706                 Val32 = (SK_U32)pAC->GIni.GILevel;
 
3707                 SK_PNMI_STORE_U32(pBuf, Val32);
 
3708                 *pLen = sizeof(SK_U32);
 
3711         case OID_SKGE_PORT_NUMBER:
 
3712                 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
 
3713                 SK_PNMI_STORE_U32(pBuf, Val32);
 
3714                 *pLen = sizeof(SK_U32);
 
3717         case OID_SKGE_DEVICE_TYPE:
 
3718                 Val32 = (SK_U32)pAC->Pnmi.DeviceType;
 
3719                 SK_PNMI_STORE_U32(pBuf, Val32);
 
3720                 *pLen = sizeof(SK_U32);
 
3723         case OID_SKGE_DRIVER_DESCR:
 
3724                 if (pAC->Pnmi.pDriverDescription == NULL) {
 
3726                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
 
3730                         return (SK_PNMI_ERR_GENERAL);
 
3733                 Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
 
3734                 if (Len > SK_PNMI_STRINGLEN1) {
 
3736                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
 
3740                         return (SK_PNMI_ERR_GENERAL);
 
3746                         return (SK_PNMI_ERR_TOO_SHORT);
 
3748                 *pBuf = (char)(Len - 1);
 
3749                 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
 
3753         case OID_SKGE_DRIVER_VERSION:
 
3754                 if (pAC->Pnmi.pDriverVersion == NULL) {
 
3756                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
 
3760                         return (SK_PNMI_ERR_GENERAL);
 
3763                 Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
 
3764                 if (Len > SK_PNMI_STRINGLEN1) {
 
3766                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
 
3770                         return (SK_PNMI_ERR_GENERAL);
 
3776                         return (SK_PNMI_ERR_TOO_SHORT);
 
3778                 *pBuf = (char)(Len - 1);
 
3779                 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
 
3783         case OID_SKGE_DRIVER_RELDATE:
 
3784                 if (pAC->Pnmi.pDriverReleaseDate == NULL) {
 
3786                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
 
3790                         return (SK_PNMI_ERR_GENERAL);
 
3793                 Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1;
 
3794                 if (Len > SK_PNMI_STRINGLEN1) {
 
3796                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
 
3800                         return (SK_PNMI_ERR_GENERAL);
 
3806                         return (SK_PNMI_ERR_TOO_SHORT);
 
3808                 *pBuf = (char)(Len - 1);
 
3809                 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverReleaseDate, Len - 1);
 
3813         case OID_SKGE_DRIVER_FILENAME:
 
3814                 if (pAC->Pnmi.pDriverFileName == NULL) {
 
3816                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
 
3820                         return (SK_PNMI_ERR_GENERAL);
 
3823                 Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1;
 
3824                 if (Len > SK_PNMI_STRINGLEN1) {
 
3826                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
 
3830                         return (SK_PNMI_ERR_GENERAL);
 
3836                         return (SK_PNMI_ERR_TOO_SHORT);
 
3838                 *pBuf = (char)(Len - 1);
 
3839                 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverFileName, Len - 1);
 
3843         case OID_SKGE_HW_DESCR:
 
3845                  * The hardware description is located in the VPD. This
 
3846                  * query may move to the initialisation routine. But
 
3847                  * the VPD data is cached and therefore a call here
 
3848                  * will not make much difference.
 
3851                 if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
 
3853                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
 
3857                         return (SK_PNMI_ERR_GENERAL);
 
3860                 if (Len > SK_PNMI_STRINGLEN1) {
 
3862                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
 
3866                         return (SK_PNMI_ERR_GENERAL);
 
3871                         return (SK_PNMI_ERR_TOO_SHORT);
 
3873                 *pBuf = (char)(Len - 1);
 
3874                 SK_MEMCPY(pBuf + 1, Buf, Len - 1);
 
3878         case OID_SKGE_HW_VERSION:
 
3879                 /* Oh, I love to do some string manipulation */
 
3883                         return (SK_PNMI_ERR_TOO_SHORT);
 
3885                 Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
 
3888                 pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
 
3890                 pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
 
3894         case OID_SKGE_CHIPSET:
 
3895                 Val16 = pAC->Pnmi.Chipset;
 
3896                 SK_PNMI_STORE_U16(pBuf, Val16);
 
3897                 *pLen = sizeof(SK_U16);
 
3900         case OID_SKGE_CHIPID:
 
3901                 Val32 = pAC->GIni.GIChipId;
 
3902                 SK_PNMI_STORE_U32(pBuf, Val32);
 
3903                 *pLen = sizeof(SK_U32);
 
3906         case OID_SKGE_RAMSIZE:
 
3907                 Val32 = pAC->GIni.GIRamSize;
 
3908                 SK_PNMI_STORE_U32(pBuf, Val32);
 
3909                 *pLen = sizeof(SK_U32);
 
3912         case OID_SKGE_VAUXAVAIL:
 
3913                 *pBuf = (char) pAC->GIni.GIVauxAvail;
 
3914                 *pLen = sizeof(char);
 
3917         case OID_SKGE_BUS_TYPE:
 
3918                 *pBuf = (char) SK_PNMI_BUS_PCI;
 
3919                 *pLen = sizeof(char);
 
3922         case OID_SKGE_BUS_SPEED:
 
3923                 *pBuf = pAC->Pnmi.PciBusSpeed;
 
3924                 *pLen = sizeof(char);
 
3927         case OID_SKGE_BUS_WIDTH:
 
3928                 *pBuf = pAC->Pnmi.PciBusWidth;
 
3929                 *pLen = sizeof(char);
 
3932         case OID_SKGE_RESULT:
 
3933                 Val32 = pAC->Pnmi.TestResult;
 
3934                 SK_PNMI_STORE_U32(pBuf, Val32);
 
3935                 *pLen = sizeof(SK_U32);
 
3938         case OID_SKGE_SENSOR_NUMBER:
 
3939                 *pBuf = (char)pAC->I2c.MaxSens;
 
3940                 *pLen = sizeof(char);
 
3943         case OID_SKGE_CHKSM_NUMBER:
 
3944                 *pBuf = SKCS_NUM_PROTOCOLS;
 
3945                 *pLen = sizeof(char);
 
3948         case OID_SKGE_TRAP_NUMBER:
 
3949                 GetTrapQueueLen(pAC, &Len, &Val);
 
3950                 Val32 = (SK_U32)Val;
 
3951                 SK_PNMI_STORE_U32(pBuf, Val32);
 
3952                 *pLen = sizeof(SK_U32);
 
3956                 GetTrapQueueLen(pAC, &Len, &Val);
 
3960                         return (SK_PNMI_ERR_TOO_SHORT);
 
3962                 CopyTrapQueue(pAC, pBuf);
 
3966         case OID_SKGE_RLMT_MONITOR_NUMBER:
 
3967 /* XXX Not yet implemented by RLMT therefore we return zero elements */
 
3969                 SK_PNMI_STORE_U32(pBuf, Val32);
 
3970                 *pLen = sizeof(SK_U32);
 
3973         case OID_SKGE_TX_SW_QUEUE_LEN:
 
3974                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
3975                 if (MacType == SK_MAC_XMAC) {
 
3977                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
3978                                 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
 
3980                         /* Single net mode */
 
3982                                 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
 
3983                                         pAC->Pnmi.BufPort[1].TxSwQueueLen;
 
3988                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
3989                                 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
 
3991                         /* Single net mode */
 
3993                                 Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
 
3994                                         pAC->Pnmi.Port[1].TxSwQueueLen;
 
3997                 SK_PNMI_STORE_U64(pBuf, Val64);
 
3998                 *pLen = sizeof(SK_U64);
 
4002         case OID_SKGE_TX_SW_QUEUE_MAX:
 
4003                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4004                 if (MacType == SK_MAC_XMAC) {
 
4006                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4007                                 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
 
4009                         /* Single net mode */
 
4011                                 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
 
4012                                         pAC->Pnmi.BufPort[1].TxSwQueueMax;
 
4017                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4018                                 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
 
4020                         /* Single net mode */
 
4022                                 Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
 
4023                                         pAC->Pnmi.Port[1].TxSwQueueMax;
 
4026                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4027                 *pLen = sizeof(SK_U64);
 
4030         case OID_SKGE_TX_RETRY:
 
4031                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4032                 if (MacType == SK_MAC_XMAC) {
 
4034                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4035                                 Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
 
4037                         /* Single net mode */
 
4039                                 Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
 
4040                                         pAC->Pnmi.BufPort[1].TxRetryCts;
 
4045                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4046                                 Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
 
4048                         /* Single net mode */
 
4050                                 Val64 = pAC->Pnmi.Port[0].TxRetryCts +
 
4051                                         pAC->Pnmi.Port[1].TxRetryCts;
 
4054                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4055                 *pLen = sizeof(SK_U64);
 
4058         case OID_SKGE_RX_INTR_CTS:
 
4059                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4060                 if (MacType == SK_MAC_XMAC) {
 
4062                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4063                                 Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
 
4065                         /* Single net mode */
 
4067                                 Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
 
4068                                         pAC->Pnmi.BufPort[1].RxIntrCts;
 
4073                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4074                                 Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
 
4076                         /* Single net mode */
 
4078                                 Val64 = pAC->Pnmi.Port[0].RxIntrCts +
 
4079                                         pAC->Pnmi.Port[1].RxIntrCts;
 
4082                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4083                 *pLen = sizeof(SK_U64);
 
4086         case OID_SKGE_TX_INTR_CTS:
 
4087                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4088                 if (MacType == SK_MAC_XMAC) {
 
4090                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4091                                 Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
 
4093                         /* Single net mode */
 
4095                                 Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
 
4096                                         pAC->Pnmi.BufPort[1].TxIntrCts;
 
4101                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4102                                 Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
 
4104                         /* Single net mode */
 
4106                                 Val64 = pAC->Pnmi.Port[0].TxIntrCts +
 
4107                                         pAC->Pnmi.Port[1].TxIntrCts;
 
4110                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4111                 *pLen = sizeof(SK_U64);
 
4114         case OID_SKGE_RX_NO_BUF_CTS:
 
4115                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4116                 if (MacType == SK_MAC_XMAC) {
 
4118                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4119                                 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
 
4121                         /* Single net mode */
 
4123                                 Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
 
4124                                         pAC->Pnmi.BufPort[1].RxNoBufCts;
 
4129                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4130                                 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
 
4132                         /* Single net mode */
 
4134                                 Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
 
4135                                         pAC->Pnmi.Port[1].RxNoBufCts;
 
4138                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4139                 *pLen = sizeof(SK_U64);
 
4142         case OID_SKGE_TX_NO_BUF_CTS:
 
4143                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4144                 if (MacType == SK_MAC_XMAC) {
 
4146                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4147                                 Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
 
4149                         /* Single net mode */
 
4151                                 Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
 
4152                                         pAC->Pnmi.BufPort[1].TxNoBufCts;
 
4157                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4158                                 Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
 
4160                         /* Single net mode */
 
4162                                 Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
 
4163                                         pAC->Pnmi.Port[1].TxNoBufCts;
 
4166                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4167                 *pLen = sizeof(SK_U64);
 
4170         case OID_SKGE_TX_USED_DESCR_NO:
 
4171                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4172                 if (MacType == SK_MAC_XMAC) {
 
4174                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4175                                 Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
 
4177                         /* Single net mode */
 
4179                                 Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
 
4180                                         pAC->Pnmi.BufPort[1].TxUsedDescrNo;
 
4185                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4186                                 Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
 
4188                         /* Single net mode */
 
4190                                 Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
 
4191                                         pAC->Pnmi.Port[1].TxUsedDescrNo;
 
4194                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4195                 *pLen = sizeof(SK_U64);
 
4198         case OID_SKGE_RX_DELIVERED_CTS:
 
4199                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4200                 if (MacType == SK_MAC_XMAC) {
 
4202                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4203                                 Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
 
4205                         /* Single net mode */
 
4207                                 Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
 
4208                                         pAC->Pnmi.BufPort[1].RxDeliveredCts;
 
4213                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4214                                 Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
 
4216                         /* Single net mode */
 
4218                                 Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
 
4219                                         pAC->Pnmi.Port[1].RxDeliveredCts;
 
4222                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4223                 *pLen = sizeof(SK_U64);
 
4226         case OID_SKGE_RX_OCTETS_DELIV_CTS:
 
4227                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4228                 if (MacType == SK_MAC_XMAC) {
 
4230                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4231                                 Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
 
4233                         /* Single net mode */
 
4235                                 Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
 
4236                                         pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
 
4241                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4242                                 Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
 
4244                         /* Single net mode */
 
4246                                 Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
 
4247                                         pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
 
4250                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4251                 *pLen = sizeof(SK_U64);
 
4254         case OID_SKGE_RX_HW_ERROR_CTS:
 
4255                 SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
 
4256                 *pLen = sizeof(SK_U64);
 
4259         case OID_SKGE_TX_HW_ERROR_CTS:
 
4260                 SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
 
4261                 *pLen = sizeof(SK_U64);
 
4264         case OID_SKGE_IN_ERRORS_CTS:
 
4265                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4266                 if (MacType == SK_MAC_XMAC) {
 
4268                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4269                                 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
 
4271                         /* Single net mode */
 
4273                                 Val64 = Val64RxHwErrs +
 
4274                                         pAC->Pnmi.BufPort[0].RxNoBufCts +
 
4275                                         pAC->Pnmi.BufPort[1].RxNoBufCts;
 
4280                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4281                                 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
 
4283                         /* Single net mode */
 
4285                                 Val64 = Val64RxHwErrs +
 
4286                                         pAC->Pnmi.Port[0].RxNoBufCts +
 
4287                                         pAC->Pnmi.Port[1].RxNoBufCts;
 
4290                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4291                 *pLen = sizeof(SK_U64);
 
4294         case OID_SKGE_OUT_ERROR_CTS:
 
4295                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4296                 if (MacType == SK_MAC_XMAC) {
 
4298                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4299                                 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
 
4301                         /* Single net mode */
 
4303                                 Val64 = Val64TxHwErrs +
 
4304                                         pAC->Pnmi.BufPort[0].TxNoBufCts +
 
4305                                         pAC->Pnmi.BufPort[1].TxNoBufCts;
 
4310                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4311                                 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
 
4313                         /* Single net mode */
 
4315                                 Val64 = Val64TxHwErrs +
 
4316                                         pAC->Pnmi.Port[0].TxNoBufCts +
 
4317                                         pAC->Pnmi.Port[1].TxNoBufCts;
 
4320                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4321                 *pLen = sizeof(SK_U64);
 
4324         case OID_SKGE_ERR_RECOVERY_CTS:
 
4325                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4326                 if (MacType == SK_MAC_XMAC) {
 
4328                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4329                                 Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
 
4331                         /* Single net mode */
 
4333                                 Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
 
4334                                         pAC->Pnmi.BufPort[1].ErrRecoveryCts;
 
4339                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4340                                 Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
 
4342                         /* Single net mode */
 
4344                                 Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
 
4345                                         pAC->Pnmi.Port[1].ErrRecoveryCts;
 
4348                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4349                 *pLen = sizeof(SK_U64);
 
4352         case OID_SKGE_SYSUPTIME:
 
4353                 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
 
4354                 Val64 -= pAC->Pnmi.StartUpTime;
 
4355                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4356                 *pLen = sizeof(SK_U64);
 
4359         case OID_SKGE_MDB_VERSION:
 
4360                 Val32 = SK_PNMI_MDB_VERSION;
 
4361                 SK_PNMI_STORE_U32(pBuf, Val32);
 
4362                 *pLen = sizeof(SK_U32);
 
4365         case OID_GEN_RCV_ERROR:
 
4366                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4367                 if (MacType == SK_MAC_XMAC) {
 
4368                         Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
 
4371                         Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
 
4375                  * by default 32bit values are evaluated
 
4378                         Val32 = (SK_U32)Val64;
 
4379                         SK_PNMI_STORE_U32(pBuf, Val32);
 
4380                         *pLen = sizeof(SK_U32);
 
4383                         SK_PNMI_STORE_U64(pBuf, Val64);
 
4384                         *pLen = sizeof(SK_U64);
 
4388         case OID_GEN_XMIT_ERROR:
 
4389                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4390                 if (MacType == SK_MAC_XMAC) {
 
4391                         Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
 
4394                         Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
 
4398                  * by default 32bit values are evaluated
 
4401                         Val32 = (SK_U32)Val64;
 
4402                         SK_PNMI_STORE_U32(pBuf, Val32);
 
4403                         *pLen = sizeof(SK_U32);
 
4406                         SK_PNMI_STORE_U64(pBuf, Val64);
 
4407                         *pLen = sizeof(SK_U64);
 
4411         case OID_GEN_RCV_NO_BUFFER:
 
4412                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4413                 if (MacType == SK_MAC_XMAC) {
 
4414                         Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
 
4417                         Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
 
4421                  * by default 32bit values are evaluated
 
4424                         Val32 = (SK_U32)Val64;
 
4425                         SK_PNMI_STORE_U32(pBuf, Val32);
 
4426                         *pLen = sizeof(SK_U32);
 
4429                         SK_PNMI_STORE_U64(pBuf, Val64);
 
4430                         *pLen = sizeof(SK_U64);
 
4434         case OID_GEN_TRANSMIT_QUEUE_LENGTH:
 
4435                 Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
 
4436                 SK_PNMI_STORE_U32(pBuf, Val32);
 
4437                 *pLen = sizeof(SK_U32);
 
4441                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
 
4445                 return (SK_PNMI_ERR_GENERAL);
 
4448         if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
 
4449                 Id == OID_SKGE_TX_HW_ERROR_CTS ||
 
4450                 Id == OID_SKGE_IN_ERRORS_CTS ||
 
4451                 Id == OID_SKGE_OUT_ERROR_CTS ||
 
4452                 Id == OID_GEN_XMIT_ERROR ||
 
4453                 Id == OID_GEN_RCV_ERROR) {
 
4455                 pAC->Pnmi.MacUpdatedFlag --;
 
4458         return (SK_PNMI_ERR_OK);
 
4461 /*****************************************************************************
 
4463  * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
 
4466  *      Get/Presets/Sets the RLMT OIDs.
 
4469  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
4470  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
4471  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
4472  *                               the correct data (e.g. a 32bit value is
 
4473  *                               needed, but a 16 bit value was passed).
 
4474  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 
4476  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 
4477  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
4478  *                           exist (e.g. port instance 3 on a two port
 
4481 PNMI_STATIC int Rlmt(
 
4482 SK_AC *pAC,             /* Pointer to adapter context */
 
4483 SK_IOC IoC,             /* IO context handle */
 
4484 int Action,             /* GET/PRESET/SET action */
 
4485 SK_U32 Id,              /* Object ID that is to be processed */
 
4486 char *pBuf,             /* Buffer used for the management data transfer */
 
4487 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
4488 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
4489 unsigned int TableIndex, /* Index to the Id table */
 
4490 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
4493         unsigned int    PhysPortIndex;
 
4494         unsigned int    PhysPortMax;
 
4495         SK_EVPARA       EventParam;
 
4501          * Check instance. Only single instance OIDs are allowed here.
 
4503         if (Instance != (SK_U32)(-1) && Instance != 1) {
 
4506                 return (SK_PNMI_ERR_UNKNOWN_INST);
 
4510          * Perform the requested action.
 
4512         if (Action == SK_PNMI_GET) {
 
4515                  * Check if the buffer length is large enough.
 
4520                 case OID_SKGE_RLMT_MODE:
 
4521                 case OID_SKGE_RLMT_PORT_ACTIVE:
 
4522                 case OID_SKGE_RLMT_PORT_PREFERRED:
 
4523                         if (*pLen < sizeof(SK_U8)) {
 
4525                                 *pLen = sizeof(SK_U8);
 
4526                                 return (SK_PNMI_ERR_TOO_SHORT);
 
4530                 case OID_SKGE_RLMT_PORT_NUMBER:
 
4531                         if (*pLen < sizeof(SK_U32)) {
 
4533                                 *pLen = sizeof(SK_U32);
 
4534                                 return (SK_PNMI_ERR_TOO_SHORT);
 
4538                 case OID_SKGE_RLMT_CHANGE_CTS:
 
4539                 case OID_SKGE_RLMT_CHANGE_TIME:
 
4540                 case OID_SKGE_RLMT_CHANGE_ESTIM:
 
4541                 case OID_SKGE_RLMT_CHANGE_THRES:
 
4542                         if (*pLen < sizeof(SK_U64)) {
 
4544                                 *pLen = sizeof(SK_U64);
 
4545                                 return (SK_PNMI_ERR_TOO_SHORT);
 
4550                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
 
4554                         return (SK_PNMI_ERR_GENERAL);
 
4558                  * Update RLMT statistic and increment semaphores to indicate
 
4559                  * that an update was already done. Maybe RLMT will hold its
 
4560                  * statistic always up to date some time. Then we can
 
4561                  * remove this type of call.
 
4563                 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
 
4568                 pAC->Pnmi.RlmtUpdatedFlag ++;
 
4575                 case OID_SKGE_RLMT_MODE:
 
4576                         *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
 
4577                         *pLen = sizeof(char);
 
4580                 case OID_SKGE_RLMT_PORT_NUMBER:
 
4581                         Val32 = (SK_U32)pAC->GIni.GIMacsFound;
 
4582                         SK_PNMI_STORE_U32(pBuf, Val32);
 
4583                         *pLen = sizeof(SK_U32);
 
4586                 case OID_SKGE_RLMT_PORT_ACTIVE:
 
4589                          * If multiple ports may become active this OID
 
4590                          * doesn't make sense any more. A new variable in
 
4591                          * the port structure should be created. However,
 
4592                          * for this variable the first active port is
 
4595                         PhysPortMax = pAC->GIni.GIMacsFound;
 
4597                         for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
 
4600                                 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
 
4602                                         *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
 
4606                         *pLen = sizeof(char);
 
4609                 case OID_SKGE_RLMT_PORT_PREFERRED:
 
4610                         *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
 
4611                         *pLen = sizeof(char);
 
4614                 case OID_SKGE_RLMT_CHANGE_CTS:
 
4615                         Val64 = pAC->Pnmi.RlmtChangeCts;
 
4616                         SK_PNMI_STORE_U64(pBuf, Val64);
 
4617                         *pLen = sizeof(SK_U64);
 
4620                 case OID_SKGE_RLMT_CHANGE_TIME:
 
4621                         Val64 = pAC->Pnmi.RlmtChangeTime;
 
4622                         SK_PNMI_STORE_U64(pBuf, Val64);
 
4623                         *pLen = sizeof(SK_U64);
 
4626                 case OID_SKGE_RLMT_CHANGE_ESTIM:
 
4627                         Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
 
4628                         SK_PNMI_STORE_U64(pBuf, Val64);
 
4629                         *pLen = sizeof(SK_U64);
 
4632                 case OID_SKGE_RLMT_CHANGE_THRES:
 
4633                         Val64 = pAC->Pnmi.RlmtChangeThreshold;
 
4634                         SK_PNMI_STORE_U64(pBuf, Val64);
 
4635                         *pLen = sizeof(SK_U64);
 
4639                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
 
4640                                 ("Rlmt: Unknown OID should be handled before"));
 
4642                         pAC->Pnmi.RlmtUpdatedFlag --;
 
4644                         return (SK_PNMI_ERR_GENERAL);
 
4647                 pAC->Pnmi.RlmtUpdatedFlag --;
 
4650                 /* Perform a preset or set */
 
4653                 case OID_SKGE_RLMT_MODE:
 
4654                         /* Check if the buffer length is plausible */
 
4655                         if (*pLen < sizeof(char)) {
 
4657                                 *pLen = sizeof(char);
 
4658                                 return (SK_PNMI_ERR_TOO_SHORT);
 
4660                         /* Check if the value range is correct */
 
4661                         if (*pLen != sizeof(char) ||
 
4662                                 (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
 
4663                                 *(SK_U8 *)pBuf > 15) {
 
4666                                 return (SK_PNMI_ERR_BAD_VALUE);
 
4668                         /* The preset ends here */
 
4669                         if (Action == SK_PNMI_PRESET) {
 
4672                                 return (SK_PNMI_ERR_OK);
 
4674                         /* Send an event to RLMT to change the mode */
 
4675                         SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
 
4676                         EventParam.Para32[0] |= (SK_U32)(*pBuf);
 
4677                         EventParam.Para32[1] = 0;
 
4678                         if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
 
4681                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
 
4685                                 return (SK_PNMI_ERR_GENERAL);
 
4689                 case OID_SKGE_RLMT_PORT_PREFERRED:
 
4690                         /* Check if the buffer length is plausible */
 
4691                         if (*pLen < sizeof(char)) {
 
4693                                 *pLen = sizeof(char);
 
4694                                 return (SK_PNMI_ERR_TOO_SHORT);
 
4696                         /* Check if the value range is correct */
 
4697                         if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
 
4698                                 (SK_U8)pAC->GIni.GIMacsFound) {
 
4701                                 return (SK_PNMI_ERR_BAD_VALUE);
 
4703                         /* The preset ends here */
 
4704                         if (Action == SK_PNMI_PRESET) {
 
4707                                 return (SK_PNMI_ERR_OK);
 
4711                          * Send an event to RLMT change the preferred port.
 
4712                          * A param of -1 means automatic mode. RLMT will
 
4713                          * make the decision which is the preferred port.
 
4715                         SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
 
4716                         EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
 
4717                         EventParam.Para32[1] = NetIndex;
 
4718                         if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
 
4721                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
 
4725                                 return (SK_PNMI_ERR_GENERAL);
 
4729                 case OID_SKGE_RLMT_CHANGE_THRES:
 
4730                         /* Check if the buffer length is plausible */
 
4731                         if (*pLen < sizeof(SK_U64)) {
 
4733                                 *pLen = sizeof(SK_U64);
 
4734                                 return (SK_PNMI_ERR_TOO_SHORT);
 
4737                          * There are not many restrictions to the
 
4740                         if (*pLen != sizeof(SK_U64)) {
 
4743                                 return (SK_PNMI_ERR_BAD_VALUE);
 
4745                         /* A preset ends here */
 
4746                         if (Action == SK_PNMI_PRESET) {
 
4749                                 return (SK_PNMI_ERR_OK);
 
4752                          * Store the new threshold, which will be taken
 
4753                          * on the next timer event.
 
4755                         SK_PNMI_READ_U64(pBuf, Val64);
 
4756                         pAC->Pnmi.RlmtChangeThreshold = Val64;
 
4760                         /* The other OIDs are not be able for set */
 
4762                         return (SK_PNMI_ERR_READ_ONLY);
 
4766         return (SK_PNMI_ERR_OK);
 
4769 /*****************************************************************************
 
4771  * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
 
4774  *      Performs get requests on multiple instance variables.
 
4777  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
4778  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
4779  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
4780  *                               the correct data (e.g. a 32bit value is
 
4781  *                               needed, but a 16 bit value was passed).
 
4782  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
4783  *                           exist (e.g. port instance 3 on a two port
 
4786 PNMI_STATIC int RlmtStat(
 
4787 SK_AC *pAC,             /* Pointer to adapter context */
 
4788 SK_IOC IoC,             /* IO context handle */
 
4789 int Action,             /* GET/PRESET/SET action */
 
4790 SK_U32 Id,              /* Object ID that is to be processed */
 
4791 char *pBuf,             /* Buffer used for the management data transfer */
 
4792 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
4793 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
4794 unsigned int TableIndex, /* Index to the Id table */
 
4795 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
4797         unsigned int    PhysPortMax;
 
4798         unsigned int    PhysPortIndex;
 
4800         unsigned int    Offset;
 
4806          * Calculate the port indexes from the instance.
 
4808         PhysPortMax = pAC->GIni.GIMacsFound;
 
4810         if ((Instance != (SK_U32)(-1))) {
 
4811                 /* Check instance range */
 
4812                 if ((Instance < 1) || (Instance > PhysPortMax)) {
 
4815                         return (SK_PNMI_ERR_UNKNOWN_INST);
 
4818                 /* Single net mode */
 
4819                 PhysPortIndex = Instance - 1;
 
4822                 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4823                         PhysPortIndex = NetIndex;
 
4826                 /* Both net modes */
 
4827                 Limit = PhysPortIndex + 1;
 
4830                 /* Single net mode */
 
4832                 Limit = PhysPortMax;
 
4835                 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4836                         PhysPortIndex = NetIndex;
 
4837                         Limit = PhysPortIndex + 1;
 
4842          * Currently only get requests are allowed.
 
4844         if (Action != SK_PNMI_GET) {
 
4847                 return (SK_PNMI_ERR_READ_ONLY);
 
4851          * Check if the buffer length is large enough.
 
4855         case OID_SKGE_RLMT_PORT_INDEX:
 
4856         case OID_SKGE_RLMT_STATUS:
 
4857                 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
 
4859                         *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
 
4860                         return (SK_PNMI_ERR_TOO_SHORT);
 
4864         case OID_SKGE_RLMT_TX_HELLO_CTS:
 
4865         case OID_SKGE_RLMT_RX_HELLO_CTS:
 
4866         case OID_SKGE_RLMT_TX_SP_REQ_CTS:
 
4867         case OID_SKGE_RLMT_RX_SP_CTS:
 
4868                 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
 
4870                         *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
 
4871                         return (SK_PNMI_ERR_TOO_SHORT);
 
4876                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
 
4880                 return (SK_PNMI_ERR_GENERAL);
 
4885          * Update statistic and increment semaphores to indicate that
 
4886          * an update was already done.
 
4888         if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
 
4893         pAC->Pnmi.RlmtUpdatedFlag ++;
 
4899         for (; PhysPortIndex < Limit; PhysPortIndex ++) {
 
4903                 case OID_SKGE_RLMT_PORT_INDEX:
 
4904                         Val32 = PhysPortIndex;
 
4905                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
4906                         Offset += sizeof(SK_U32);
 
4909                 case OID_SKGE_RLMT_STATUS:
 
4910                         if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
 
4912                                 pAC->Rlmt.Port[PhysPortIndex].PortState ==
 
4915                                 Val32 = SK_PNMI_RLMT_STATUS_ERROR;
 
4917                         else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
 
4919                                 Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
 
4922                                 Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
 
4924                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
4925                         Offset += sizeof(SK_U32);
 
4928                 case OID_SKGE_RLMT_TX_HELLO_CTS:
 
4929                         Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
 
4930                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
 
4931                         Offset += sizeof(SK_U64);
 
4934                 case OID_SKGE_RLMT_RX_HELLO_CTS:
 
4935                         Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
 
4936                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
 
4937                         Offset += sizeof(SK_U64);
 
4940                 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
 
4941                         Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
 
4942                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
 
4943                         Offset += sizeof(SK_U64);
 
4946                 case OID_SKGE_RLMT_RX_SP_CTS:
 
4947                         Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
 
4948                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
 
4949                         Offset += sizeof(SK_U64);
 
4953                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
 
4954                                 ("RlmtStat: Unknown OID should be errored before"));
 
4956                         pAC->Pnmi.RlmtUpdatedFlag --;
 
4958                         return (SK_PNMI_ERR_GENERAL);
 
4963         pAC->Pnmi.RlmtUpdatedFlag --;
 
4965         return (SK_PNMI_ERR_OK);
 
4968 /*****************************************************************************
 
4970  * MacPrivateConf - OID handler function of OIDs concerning the configuration
 
4973  *      Get/Presets/Sets the OIDs concerning the configuration.
 
4976  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
4977  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
4978  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
4979  *                               the correct data (e.g. a 32bit value is
 
4980  *                               needed, but a 16 bit value was passed).
 
4981  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 
4983  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 
4984  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
4985  *                           exist (e.g. port instance 3 on a two port
 
4988 PNMI_STATIC int MacPrivateConf(
 
4989 SK_AC *pAC,             /* Pointer to adapter context */
 
4990 SK_IOC IoC,             /* IO context handle */
 
4991 int Action,             /* GET/PRESET/SET action */
 
4992 SK_U32 Id,              /* Object ID that is to be processed */
 
4993 char *pBuf,             /* Buffer used for the management data transfer */
 
4994 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
4995 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
4996 unsigned int TableIndex, /* Index to the Id table */
 
4997 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
4999         unsigned int    PhysPortMax;
 
5000         unsigned int    PhysPortIndex;
 
5001         unsigned int    LogPortMax;
 
5002         unsigned int    LogPortIndex;
 
5004         unsigned int    Offset;
 
5008         SK_EVPARA       EventParam;
 
5012          * Calculate instance if wished. MAC index 0 is the virtual MAC.
 
5014         PhysPortMax = pAC->GIni.GIMacsFound;
 
5015         LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
 
5017         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
 
5021         if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
 
5022                 /* Check instance range */
 
5023                 if ((Instance < 1) || (Instance > LogPortMax)) {
 
5026                         return (SK_PNMI_ERR_UNKNOWN_INST);
 
5028                 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
 
5029                 Limit = LogPortIndex + 1;
 
5032         else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
 
5041         if (Action == SK_PNMI_GET) {
 
5047                 case OID_SKGE_CONNECTOR:
 
5048                 case OID_SKGE_LINK_CAP:
 
5049                 case OID_SKGE_LINK_MODE:
 
5050                 case OID_SKGE_LINK_MODE_STATUS:
 
5051                 case OID_SKGE_LINK_STATUS:
 
5052                 case OID_SKGE_FLOWCTRL_CAP:
 
5053                 case OID_SKGE_FLOWCTRL_MODE:
 
5054                 case OID_SKGE_FLOWCTRL_STATUS:
 
5055                 case OID_SKGE_PHY_OPERATION_CAP:
 
5056                 case OID_SKGE_PHY_OPERATION_MODE:
 
5057                 case OID_SKGE_PHY_OPERATION_STATUS:
 
5058                 case OID_SKGE_SPEED_CAP:
 
5059                 case OID_SKGE_SPEED_MODE:
 
5060                 case OID_SKGE_SPEED_STATUS:
 
5061                         if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
 
5063                                 *pLen = (Limit - LogPortIndex) * sizeof(SK_U8);
 
5064                                 return (SK_PNMI_ERR_TOO_SHORT);
 
5069         case OID_SKGE_PHY_TYPE:
 
5070                         if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) {
 
5072                                 *pLen = (Limit - LogPortIndex) * sizeof(SK_U32);
 
5073                                 return (SK_PNMI_ERR_TOO_SHORT);
 
5078                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
 
5081                         return (SK_PNMI_ERR_GENERAL);
 
5085                  * Update statistic and increment semaphore to indicate
 
5086                  * that an update was already done.
 
5088                 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
 
5093                 pAC->Pnmi.SirqUpdatedFlag ++;
 
5099                 for (; LogPortIndex < Limit; LogPortIndex ++) {
 
5101                         pBufPtr = pBuf + Offset;
 
5106                                 *pBufPtr = pAC->Pnmi.PMD;
 
5107                                 Offset += sizeof(char);
 
5110                         case OID_SKGE_CONNECTOR:
 
5111                                 *pBufPtr = pAC->Pnmi.Connector;
 
5112                                 Offset += sizeof(char);
 
5115                         case OID_SKGE_PHY_TYPE:
 
5116                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5117                                         if (LogPortIndex == 0) {
 
5121                                                 /* Get value for physical ports */
 
5122                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5124                                                 Val32 = pAC->GIni.GP[PhysPortIndex].PhyType;
 
5125                                                 SK_PNMI_STORE_U32(pBufPtr, Val32);
 
5128                                 else { /* DualNetMode */
 
5130                                         Val32 = pAC->GIni.GP[NetIndex].PhyType;
 
5131                                         SK_PNMI_STORE_U32(pBufPtr, Val32);
 
5133                                 Offset += sizeof(SK_U32);
 
5136                         case OID_SKGE_LINK_CAP:
 
5137                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5138                                         if (LogPortIndex == 0) {
 
5139                                                 /* Get value for virtual port */
 
5140                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5143                                                 /* Get value for physical ports */
 
5144                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5147                                                 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkCap;
 
5150                                 else { /* DualNetMode */
 
5152                                         *pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap;
 
5154                                 Offset += sizeof(char);
 
5157                         case OID_SKGE_LINK_MODE:
 
5158                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5159                                         if (LogPortIndex == 0) {
 
5160                                                 /* Get value for virtual port */
 
5161                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5164                                                 /* Get value for physical ports */
 
5165                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5168                                                 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
 
5171                                 else { /* DualNetMode */
 
5173                                         *pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf;
 
5175                                 Offset += sizeof(char);
 
5178                         case OID_SKGE_LINK_MODE_STATUS:
 
5179                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5180                                         if (LogPortIndex == 0) {
 
5181                                                 /* Get value for virtual port */
 
5182                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5185                                                 /* Get value for physical port */
 
5186                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5190                                                         CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
 
5193                                 else { /* DualNetMode */
 
5195                                         *pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex);
 
5197                                 Offset += sizeof(char);
 
5200                         case OID_SKGE_LINK_STATUS:
 
5201                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5202                                         if (LogPortIndex == 0) {
 
5203                                                 /* Get value for virtual port */
 
5204                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5207                                                 /* Get value for physical ports */
 
5208                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5211                                                 *pBufPtr = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
 
5214                                 else { /* DualNetMode */
 
5216                                         *pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex);
 
5218                                 Offset += sizeof(char);
 
5221                         case OID_SKGE_FLOWCTRL_CAP:
 
5222                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5223                                         if (LogPortIndex == 0) {
 
5224                                                 /* Get value for virtual port */
 
5225                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5228                                                 /* Get value for physical ports */
 
5229                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5232                                                 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
 
5235                                 else { /* DualNetMode */
 
5237                                         *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
 
5239                                 Offset += sizeof(char);
 
5242                         case OID_SKGE_FLOWCTRL_MODE:
 
5243                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5244                                         if (LogPortIndex == 0) {
 
5245                                                 /* Get value for virtual port */
 
5246                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5249                                                 /* Get value for physical port */
 
5250                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5253                                                 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
 
5256                                 else { /* DualNetMode */
 
5258                                         *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
 
5260                                 Offset += sizeof(char);
 
5263                         case OID_SKGE_FLOWCTRL_STATUS:
 
5264                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5265                                         if (LogPortIndex == 0) {
 
5266                                                 /* Get value for virtual port */
 
5267                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5270                                                 /* Get value for physical port */
 
5271                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5274                                                 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
 
5277                                 else { /* DualNetMode */
 
5279                                         *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
 
5281                                 Offset += sizeof(char);
 
5284                         case OID_SKGE_PHY_OPERATION_CAP:
 
5285                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5286                                         if (LogPortIndex == 0) {
 
5287                                                 /* Get value for virtual port */
 
5288                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5291                                                 /* Get value for physical ports */
 
5292                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5295                                                 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSCap;
 
5298                                 else { /* DualNetMode */
 
5300                                         *pBufPtr = pAC->GIni.GP[NetIndex].PMSCap;
 
5302                                 Offset += sizeof(char);
 
5305                         case OID_SKGE_PHY_OPERATION_MODE:
 
5306                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5307                                         if (LogPortIndex == 0) {
 
5308                                                 /* Get value for virtual port */
 
5309                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5312                                                 /* Get value for physical port */
 
5313                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5316                                                 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSMode;
 
5319                                 else { /* DualNetMode */
 
5321                                         *pBufPtr = pAC->GIni.GP[NetIndex].PMSMode;
 
5323                                 Offset += sizeof(char);
 
5326                         case OID_SKGE_PHY_OPERATION_STATUS:
 
5327                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5328                                         if (LogPortIndex == 0) {
 
5329                                                 /* Get value for virtual port */
 
5330                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5333                                                 /* Get value for physical port */
 
5334                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5337                                                 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSStatus;
 
5342                                         *pBufPtr = pAC->GIni.GP[NetIndex].PMSStatus;
 
5344                                 Offset += sizeof(char);
 
5347                         case OID_SKGE_SPEED_CAP:
 
5348                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5349                                         if (LogPortIndex == 0) {
 
5350                                                 /* Get value for virtual port */
 
5351                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5354                                                 /* Get value for physical ports */
 
5355                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5358                                                 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedCap;
 
5361                                 else { /* DualNetMode */
 
5363                                         *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
 
5365                                 Offset += sizeof(char);
 
5368                         case OID_SKGE_SPEED_MODE:
 
5369                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5370                                         if (LogPortIndex == 0) {
 
5371                                                 /* Get value for virtual port */
 
5372                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5375                                                 /* Get value for physical port */
 
5376                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5379                                                 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
 
5382                                 else { /* DualNetMode */
 
5384                                         *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed;
 
5386                                 Offset += sizeof(char);
 
5389                         case OID_SKGE_SPEED_STATUS:
 
5390                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5391                                         if (LogPortIndex == 0) {
 
5392                                                 /* Get value for virtual port */
 
5393                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5396                                                 /* Get value for physical port */
 
5397                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5400                                                 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
 
5403                                 else { /* DualNetMode */
 
5405                                         *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
 
5407                                 Offset += sizeof(char);
 
5411                                 Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
 
5412                                 SK_PNMI_STORE_U32(pBufPtr, Val32);
 
5413                                 Offset += sizeof(SK_U32);
 
5417                                 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
 
5418                                         ("MacPrivateConf: Unknown OID should be handled before"));
 
5420                                 pAC->Pnmi.SirqUpdatedFlag --;
 
5421                                 return (SK_PNMI_ERR_GENERAL);
 
5425                 pAC->Pnmi.SirqUpdatedFlag --;
 
5427                 return (SK_PNMI_ERR_OK);
 
5431          * From here SET or PRESET action. Check if the passed
 
5432          * buffer length is plausible.
 
5436         case OID_SKGE_LINK_MODE:
 
5437         case OID_SKGE_FLOWCTRL_MODE:
 
5438         case OID_SKGE_PHY_OPERATION_MODE:
 
5439         case OID_SKGE_SPEED_MODE:
 
5440                 if (*pLen < Limit - LogPortIndex) {
 
5442                         *pLen = Limit - LogPortIndex;
 
5443                         return (SK_PNMI_ERR_TOO_SHORT);
 
5445                 if (*pLen != Limit - LogPortIndex) {
 
5448                         return (SK_PNMI_ERR_BAD_VALUE);
 
5453                 if (*pLen < sizeof(SK_U32)) {
 
5455                         *pLen = sizeof(SK_U32);
 
5456                         return (SK_PNMI_ERR_TOO_SHORT);
 
5458                 if (*pLen != sizeof(SK_U32)) {
 
5461                         return (SK_PNMI_ERR_BAD_VALUE);
 
5467                 return (SK_PNMI_ERR_READ_ONLY);
 
5471          * Perform preset or set
 
5474         for (; LogPortIndex < Limit; LogPortIndex ++) {
 
5478                 case OID_SKGE_LINK_MODE:
 
5479                         /* Check the value range */
 
5480                         Val8 = *(pBuf + Offset);
 
5483                                 Offset += sizeof(char);
 
5486                         if (Val8 < SK_LMODE_HALF ||
 
5487                                 (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
 
5488                                 (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
 
5491                                 return (SK_PNMI_ERR_BAD_VALUE);
 
5494                         /* The preset ends here */
 
5495                         if (Action == SK_PNMI_PRESET) {
 
5497                                 return (SK_PNMI_ERR_OK);
 
5500                         if (LogPortIndex == 0) {
 
5503                                  * The virtual port consists of all currently
 
5504                                  * active ports. Find them and send an event
 
5505                                  * with the new link mode to SIRQ.
 
5507                                 for (PhysPortIndex = 0;
 
5508                                         PhysPortIndex < PhysPortMax;
 
5511                                         if (!pAC->Pnmi.Port[PhysPortIndex].
 
5517                                         EventParam.Para32[0] = PhysPortIndex;
 
5518                                         EventParam.Para32[1] = (SK_U32)Val8;
 
5519                                         if (SkGeSirqEvent(pAC, IoC,
 
5523                                                 SK_ERR_LOG(pAC, SK_ERRCL_SW,
 
5528                                                 return (SK_PNMI_ERR_GENERAL);
 
5534                                  * Send an event with the new link mode to
 
5537                                 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
 
5539                                 EventParam.Para32[1] = (SK_U32)Val8;
 
5540                                 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
 
5543                                         SK_ERR_LOG(pAC, SK_ERRCL_SW,
 
5548                                         return (SK_PNMI_ERR_GENERAL);
 
5551                         Offset += sizeof(char);
 
5554                 case OID_SKGE_FLOWCTRL_MODE:
 
5555                         /* Check the value range */
 
5556                         Val8 = *(pBuf + Offset);
 
5559                                 Offset += sizeof(char);
 
5562                         if (Val8 < SK_FLOW_MODE_NONE ||
 
5563                                 (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
 
5564                                 (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
 
5567                                 return (SK_PNMI_ERR_BAD_VALUE);
 
5570                         /* The preset ends here */
 
5571                         if (Action == SK_PNMI_PRESET) {
 
5573                                 return (SK_PNMI_ERR_OK);
 
5576                         if (LogPortIndex == 0) {
 
5579                                  * The virtual port consists of all currently
 
5580                                  * active ports. Find them and send an event
 
5581                                  * with the new flow control mode to SIRQ.
 
5583                                 for (PhysPortIndex = 0;
 
5584                                         PhysPortIndex < PhysPortMax;
 
5587                                         if (!pAC->Pnmi.Port[PhysPortIndex].
 
5593                                         EventParam.Para32[0] = PhysPortIndex;
 
5594                                         EventParam.Para32[1] = (SK_U32)Val8;
 
5595                                         if (SkGeSirqEvent(pAC, IoC,
 
5596                                                 SK_HWEV_SET_FLOWMODE,
 
5599                                                 SK_ERR_LOG(pAC, SK_ERRCL_SW,
 
5604                                                 return (SK_PNMI_ERR_GENERAL);
 
5610                                  * Send an event with the new flow control
 
5611                                  * mode to the SIRQ module.
 
5613                                 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
 
5615                                 EventParam.Para32[1] = (SK_U32)Val8;
 
5616                                 if (SkGeSirqEvent(pAC, IoC,
 
5617                                         SK_HWEV_SET_FLOWMODE, EventParam)
 
5620                                         SK_ERR_LOG(pAC, SK_ERRCL_SW,
 
5625                                         return (SK_PNMI_ERR_GENERAL);
 
5628                         Offset += sizeof(char);
 
5631                 case OID_SKGE_PHY_OPERATION_MODE :
 
5632                         /* Check the value range */
 
5633                         Val8 = *(pBuf + Offset);
 
5635                                 /* mode of this port remains unchanged */
 
5636                                 Offset += sizeof(char);
 
5639                         if (Val8 < SK_MS_MODE_AUTO ||
 
5640                                 (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
 
5641                                 (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
 
5644                                 return (SK_PNMI_ERR_BAD_VALUE);
 
5647                         /* The preset ends here */
 
5648                         if (Action == SK_PNMI_PRESET) {
 
5650                                 return (SK_PNMI_ERR_OK);
 
5653                         if (LogPortIndex == 0) {
 
5656                                  * The virtual port consists of all currently
 
5657                                  * active ports. Find them and send an event
 
5658                                  * with new master/slave (role) mode to SIRQ.
 
5660                                 for (PhysPortIndex = 0;
 
5661                                         PhysPortIndex < PhysPortMax;
 
5664                                         if (!pAC->Pnmi.Port[PhysPortIndex].
 
5670                                         EventParam.Para32[0] = PhysPortIndex;
 
5671                                         EventParam.Para32[1] = (SK_U32)Val8;
 
5672                                         if (SkGeSirqEvent(pAC, IoC,
 
5676                                                 SK_ERR_LOG(pAC, SK_ERRCL_SW,
 
5681                                                 return (SK_PNMI_ERR_GENERAL);
 
5687                                  * Send an event with the new master/slave
 
5688                                  * (role) mode to the SIRQ module.
 
5690                                 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
 
5692                                 EventParam.Para32[1] = (SK_U32)Val8;
 
5693                                 if (SkGeSirqEvent(pAC, IoC,
 
5694                                         SK_HWEV_SET_ROLE, EventParam) > 0) {
 
5696                                         SK_ERR_LOG(pAC, SK_ERRCL_SW,
 
5701                                         return (SK_PNMI_ERR_GENERAL);
 
5705                         Offset += sizeof(char);
 
5708                 case OID_SKGE_SPEED_MODE:
 
5709                         /* Check the value range */
 
5710                         Val8 = *(pBuf + Offset);
 
5713                                 Offset += sizeof(char);
 
5716                         if (Val8 < (SK_LSPEED_AUTO) ||
 
5717                                 (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) ||
 
5718                                 (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) {
 
5721                                 return (SK_PNMI_ERR_BAD_VALUE);
 
5724                         /* The preset ends here */
 
5725                         if (Action == SK_PNMI_PRESET) {
 
5727                                 return (SK_PNMI_ERR_OK);
 
5730                         if (LogPortIndex == 0) {
 
5733                                  * The virtual port consists of all currently
 
5734                                  * active ports. Find them and send an event
 
5735                                  * with the new flow control mode to SIRQ.
 
5737                                 for (PhysPortIndex = 0;
 
5738                                         PhysPortIndex < PhysPortMax;
 
5741                                         if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
 
5746                                         EventParam.Para32[0] = PhysPortIndex;
 
5747                                         EventParam.Para32[1] = (SK_U32)Val8;
 
5748                                         if (SkGeSirqEvent(pAC, IoC,
 
5752                                                 SK_ERR_LOG(pAC, SK_ERRCL_SW,
 
5757                                                 return (SK_PNMI_ERR_GENERAL);
 
5763                                  * Send an event with the new flow control
 
5764                                  * mode to the SIRQ module.
 
5766                                 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
 
5768                                 EventParam.Para32[1] = (SK_U32)Val8;
 
5769                                 if (SkGeSirqEvent(pAC, IoC,
 
5773                                         SK_ERR_LOG(pAC, SK_ERRCL_SW,
 
5778                                         return (SK_PNMI_ERR_GENERAL);
 
5781                         Offset += sizeof(char);
 
5785                         /* Check the value range */
 
5786                         Val32 = *(SK_U32*)(pBuf + Offset);
 
5788                                 /* mtu of this port remains unchanged */
 
5789                                 Offset += sizeof(SK_U32);
 
5792                         if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
 
5794                                 return (SK_PNMI_ERR_BAD_VALUE);
 
5797                         /* The preset ends here */
 
5798                         if (Action == SK_PNMI_PRESET) {
 
5799                                 return (SK_PNMI_ERR_OK);
 
5802                         if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
 
5803                                 return (SK_PNMI_ERR_GENERAL);
 
5806                         Offset += sizeof(SK_U32);
 
5810             SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
 
5811                 ("MacPrivateConf: Unknown OID should be handled before set"));
 
5814                         return (SK_PNMI_ERR_GENERAL);
 
5818         return (SK_PNMI_ERR_OK);
 
5821 /*****************************************************************************
 
5823  * Monitor - OID handler function for RLMT_MONITOR_XXX
 
5826  *      Because RLMT currently does not support the monitoring of
 
5827  *      remote adapter cards, we return always an empty table.
 
5830  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
5831  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
5832  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
5833  *                               the correct data (e.g. a 32bit value is
 
5834  *                               needed, but a 16 bit value was passed).
 
5835  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 
5837  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 
5838  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
5839  *                           exist (e.g. port instance 3 on a two port
 
5842 PNMI_STATIC int Monitor(
 
5843 SK_AC *pAC,             /* Pointer to adapter context */
 
5844 SK_IOC IoC,             /* IO context handle */
 
5845 int Action,             /* GET/PRESET/SET action */
 
5846 SK_U32 Id,              /* Object ID that is to be processed */
 
5847 char *pBuf,             /* Buffer used for the management data transfer */
 
5848 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
5849 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
5850 unsigned int TableIndex, /* Index to the Id table */
 
5851 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
5855         unsigned int    Offset;
 
5856         unsigned int    Entries;
 
5860          * Calculate instance if wished.
 
5862         /* XXX Not yet implemented. Return always an empty table. */
 
5865         if ((Instance != (SK_U32)(-1))) {
 
5867                 if ((Instance < 1) || (Instance > Entries)) {
 
5870                         return (SK_PNMI_ERR_UNKNOWN_INST);
 
5873                 Index = (unsigned int)Instance - 1;
 
5874                 Limit = (unsigned int)Instance;
 
5884         if (Action == SK_PNMI_GET) {
 
5886                 for (Offset=0; Index < Limit; Index ++) {
 
5890                         case OID_SKGE_RLMT_MONITOR_INDEX:
 
5891                         case OID_SKGE_RLMT_MONITOR_ADDR:
 
5892                         case OID_SKGE_RLMT_MONITOR_ERRS:
 
5893                         case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
 
5894                         case OID_SKGE_RLMT_MONITOR_ADMIN:
 
5898                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
 
5902                                 return (SK_PNMI_ERR_GENERAL);
 
5908                 /* Only MONITOR_ADMIN can be set */
 
5909                 if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
 
5912                         return (SK_PNMI_ERR_READ_ONLY);
 
5915                 /* Check if the length is plausible */
 
5916                 if (*pLen < (Limit - Index)) {
 
5918                         return (SK_PNMI_ERR_TOO_SHORT);
 
5920                 /* Okay, we have a wide value range */
 
5921                 if (*pLen != (Limit - Index)) {
 
5924                         return (SK_PNMI_ERR_BAD_VALUE);
 
5927                 for (Offset=0; Index < Limit; Index ++) {
 
5931  * XXX Not yet implemented. Return always BAD_VALUE, because the table
 
5935                 return (SK_PNMI_ERR_BAD_VALUE);
 
5938         return (SK_PNMI_ERR_OK);
 
5941 /*****************************************************************************
 
5943  * VirtualConf - Calculates the values of configuration OIDs for virtual port
 
5946  *      We handle here the get of the configuration group OIDs, which are
 
5947  *      a little bit complicated. The virtual port consists of all currently
 
5948  *      active physical ports. If multiple ports are active and configured
 
5949  *      differently we get in some trouble to return a single value. So we
 
5950  *      get the value of the first active port and compare it with that of
 
5951  *      the other active ports. If they are not the same, we return a value
 
5952  *      that indicates that the state is indeterminated.
 
5957 PNMI_STATIC void VirtualConf(
 
5958 SK_AC *pAC,             /* Pointer to adapter context */
 
5959 SK_IOC IoC,             /* IO context handle */
 
5960 SK_U32 Id,              /* Object ID that is to be processed */
 
5961 char *pBuf)             /* Buffer used for the management data transfer */
 
5963         unsigned int    PhysPortMax;
 
5964         unsigned int    PhysPortIndex;
 
5967         SK_BOOL         PortActiveFlag;
 
5971         PortActiveFlag = SK_FALSE;
 
5972         PhysPortMax = pAC->GIni.GIMacsFound;
 
5974         for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
 
5977                 pPrt = &pAC->GIni.GP[PhysPortIndex];
 
5979                 /* Check if the physical port is active */
 
5980                 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
 
5985                 PortActiveFlag = SK_TRUE;
 
5989                 case OID_SKGE_PHY_TYPE:
 
5990                         /* Check if it is the first active port */
 
5992                                 Val32 = pPrt->PhyType;
 
5993                                 SK_PNMI_STORE_U32(pBuf, Val32);
 
5997                 case OID_SKGE_LINK_CAP:
 
6000                          * Different capabilities should not happen, but
 
6001                          * in the case of the cases OR them all together.
 
6002                          * From a curious point of view the virtual port
 
6003                          * is capable of all found capabilities.
 
6005                         *pBuf |= pPrt->PLinkCap;
 
6008                 case OID_SKGE_LINK_MODE:
 
6009                         /* Check if it is the first active port */
 
6012                                 *pBuf = pPrt->PLinkModeConf;
 
6017                          * If we find an active port with a different link
 
6018                          * mode than the first one we return a value that
 
6019                          * indicates that the link mode is indeterminated.
 
6021                         if (*pBuf != pPrt->PLinkModeConf) {
 
6023                                 *pBuf = SK_LMODE_INDETERMINATED;
 
6027                 case OID_SKGE_LINK_MODE_STATUS:
 
6028                         /* Get the link mode of the physical port */
 
6029                         Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
 
6031                         /* Check if it is the first active port */
 
6039                          * If we find an active port with a different link
 
6040                          * mode status than the first one we return a value
 
6041                          * that indicates that the link mode status is
 
6044                         if (*pBuf != Val8) {
 
6046                                 *pBuf = SK_LMODE_STAT_INDETERMINATED;
 
6050                 case OID_SKGE_LINK_STATUS:
 
6051                         /* Get the link status of the physical port */
 
6052                         Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
 
6054                         /* Check if it is the first active port */
 
6062                          * If we find an active port with a different link
 
6063                          * status than the first one, we return a value
 
6064                          * that indicates that the link status is
 
6067                         if (*pBuf != Val8) {
 
6069                                 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
 
6073                 case OID_SKGE_FLOWCTRL_CAP:
 
6074                         /* Check if it is the first active port */
 
6077                                 *pBuf = pPrt->PFlowCtrlCap;
 
6082                          * From a curious point of view the virtual port
 
6083                          * is capable of all found capabilities.
 
6085                         *pBuf |= pPrt->PFlowCtrlCap;
 
6088                 case OID_SKGE_FLOWCTRL_MODE:
 
6089                         /* Check if it is the first active port */
 
6092                                 *pBuf = pPrt->PFlowCtrlMode;
 
6097                          * If we find an active port with a different flow
 
6098                          * control mode than the first one, we return a value
 
6099                          * that indicates that the mode is indeterminated.
 
6101                         if (*pBuf != pPrt->PFlowCtrlMode) {
 
6103                                 *pBuf = SK_FLOW_MODE_INDETERMINATED;
 
6107                 case OID_SKGE_FLOWCTRL_STATUS:
 
6108                         /* Check if it is the first active port */
 
6111                                 *pBuf = pPrt->PFlowCtrlStatus;
 
6116                          * If we find an active port with a different flow
 
6117                          * control status than the first one, we return a
 
6118                          * value that indicates that the status is
 
6121                         if (*pBuf != pPrt->PFlowCtrlStatus) {
 
6123                                 *pBuf = SK_FLOW_STAT_INDETERMINATED;
 
6127                 case OID_SKGE_PHY_OPERATION_CAP:
 
6128                         /* Check if it is the first active port */
 
6131                                 *pBuf = pPrt->PMSCap;
 
6136                          * From a curious point of view the virtual port
 
6137                          * is capable of all found capabilities.
 
6139                         *pBuf |= pPrt->PMSCap;
 
6142                 case OID_SKGE_PHY_OPERATION_MODE:
 
6143                         /* Check if it is the first active port */
 
6146                                 *pBuf = pPrt->PMSMode;
 
6151                          * If we find an active port with a different master/
 
6152                          * slave mode than the first one, we return a value
 
6153                          * that indicates that the mode is indeterminated.
 
6155                         if (*pBuf != pPrt->PMSMode) {
 
6157                                 *pBuf = SK_MS_MODE_INDETERMINATED;
 
6161                 case OID_SKGE_PHY_OPERATION_STATUS:
 
6162                         /* Check if it is the first active port */
 
6165                                 *pBuf = pPrt->PMSStatus;
 
6170                          * If we find an active port with a different master/
 
6171                          * slave status than the first one, we return a
 
6172                          * value that indicates that the status is
 
6175                         if (*pBuf != pPrt->PMSStatus) {
 
6177                                 *pBuf = SK_MS_STAT_INDETERMINATED;
 
6181                 case OID_SKGE_SPEED_MODE:
 
6182                         /* Check if it is the first active port */
 
6185                                 *pBuf = pPrt->PLinkSpeed;
 
6190                          * If we find an active port with a different flow
 
6191                          * control mode than the first one, we return a value
 
6192                          * that indicates that the mode is indeterminated.
 
6194                         if (*pBuf != pPrt->PLinkSpeed) {
 
6196                                 *pBuf = SK_LSPEED_INDETERMINATED;
 
6200                 case OID_SKGE_SPEED_STATUS:
 
6201                         /* Check if it is the first active port */
 
6204                                 *pBuf = pPrt->PLinkSpeedUsed;
 
6209                          * If we find an active port with a different flow
 
6210                          * control status than the first one, we return a
 
6211                          * value that indicates that the status is
 
6214                         if (*pBuf != pPrt->PLinkSpeedUsed) {
 
6216                                 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
 
6223          * If no port is active return an indeterminated answer
 
6225         if (!PortActiveFlag) {
 
6229                 case OID_SKGE_LINK_CAP:
 
6230                         *pBuf = SK_LMODE_CAP_INDETERMINATED;
 
6233                 case OID_SKGE_LINK_MODE:
 
6234                         *pBuf = SK_LMODE_INDETERMINATED;
 
6237                 case OID_SKGE_LINK_MODE_STATUS:
 
6238                         *pBuf = SK_LMODE_STAT_INDETERMINATED;
 
6241                 case OID_SKGE_LINK_STATUS:
 
6242                         *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
 
6245                 case OID_SKGE_FLOWCTRL_CAP:
 
6246                 case OID_SKGE_FLOWCTRL_MODE:
 
6247                         *pBuf = SK_FLOW_MODE_INDETERMINATED;
 
6250                 case OID_SKGE_FLOWCTRL_STATUS:
 
6251                         *pBuf = SK_FLOW_STAT_INDETERMINATED;
 
6254                 case OID_SKGE_PHY_OPERATION_CAP:
 
6255                         *pBuf = SK_MS_CAP_INDETERMINATED;
 
6258                 case OID_SKGE_PHY_OPERATION_MODE:
 
6259                         *pBuf = SK_MS_MODE_INDETERMINATED;
 
6262                 case OID_SKGE_PHY_OPERATION_STATUS:
 
6263                         *pBuf = SK_MS_STAT_INDETERMINATED;
 
6265                 case OID_SKGE_SPEED_CAP:
 
6266                         *pBuf = SK_LSPEED_CAP_INDETERMINATED;
 
6269                 case OID_SKGE_SPEED_MODE:
 
6270                         *pBuf = SK_LSPEED_INDETERMINATED;
 
6273                 case OID_SKGE_SPEED_STATUS:
 
6274                         *pBuf = SK_LSPEED_STAT_INDETERMINATED;
 
6280 /*****************************************************************************
 
6282  * CalculateLinkStatus - Determins the link status of a physical port
 
6285  *      Determins the link status the following way:
 
6286  *        LSTAT_PHY_DOWN:  Link is down
 
6287  *        LSTAT_AUTONEG:   Auto-negotiation failed
 
6288  *        LSTAT_LOG_DOWN:  Link is up but RLMT did not yet put the port
 
6290  *        LSTAT_LOG_UP:    RLMT marked the port as up
 
6293  *      Link status of physical port
 
6295 PNMI_STATIC SK_U8 CalculateLinkStatus(
 
6296 SK_AC *pAC,                     /* Pointer to adapter context */
 
6297 SK_IOC IoC,                     /* IO context handle */
 
6298 unsigned int PhysPortIndex)     /* Physical port index */
 
6302         if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
 
6304                 Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
 
6306         else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
 
6308                 Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
 
6310         else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
 
6312                 Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
 
6315                 Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
 
6321 /*****************************************************************************
 
6323  * CalculateLinkModeStatus - Determins the link mode status of a phys. port
 
6326  *      The COMMON module only tells us if the mode is half or full duplex.
 
6327  *      But in the decade of auto sensing it is useful for the user to
 
6328  *      know if the mode was negotiated or forced. Therefore we have a
 
6329  *      look to the mode, which was last used by the negotiation process.
 
6332  *      The link mode status
 
6334 PNMI_STATIC SK_U8 CalculateLinkModeStatus(
 
6335 SK_AC *pAC,                     /* Pointer to adapter context */
 
6336 SK_IOC IoC,                     /* IO context handle */
 
6337 unsigned int PhysPortIndex)     /* Physical port index */
 
6341         /* Get the current mode, which can be full or half duplex */
 
6342         Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
 
6344         /* Check if no valid mode could be found (link is down) */
 
6345         if (Result < SK_LMODE_STAT_HALF) {
 
6347                 Result = SK_LMODE_STAT_UNKNOWN;
 
6349         else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
 
6352                  * Auto-negotiation was used to bring up the link. Change
 
6353                  * the already found duplex status that it indicates
 
6354                  * auto-negotiation was involved.
 
6356                 if (Result == SK_LMODE_STAT_HALF) {
 
6358                         Result = SK_LMODE_STAT_AUTOHALF;
 
6360                 else if (Result == SK_LMODE_STAT_FULL) {
 
6362                         Result = SK_LMODE_STAT_AUTOFULL;
 
6369 /*****************************************************************************
 
6371  * GetVpdKeyArr - Obtain an array of VPD keys
 
6374  *      Read the VPD keys and build an array of VPD keys, which are
 
6378  *      SK_PNMI_ERR_OK       Task successfully performed.
 
6379  *      SK_PNMI_ERR_GENERAL  Something went wrong.
 
6381 PNMI_STATIC int GetVpdKeyArr(
 
6382 SK_AC *pAC,             /* Pointer to adapter context */
 
6383 SK_IOC IoC,             /* IO context handle */
 
6384 char *pKeyArr,          /* Ptr KeyArray */
 
6385 unsigned int KeyArrLen, /* Length of array in bytes */
 
6386 unsigned int *pKeyNo)   /* Number of keys */
 
6388         unsigned int            BufKeysLen = SK_PNMI_VPD_BUFSIZE;
 
6389         char                    BufKeys[SK_PNMI_VPD_BUFSIZE];
 
6390         unsigned int            StartOffset;
 
6391         unsigned int            Offset;
 
6396         SK_MEMSET(pKeyArr, 0, KeyArrLen);
 
6401         Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
 
6405                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
 
6408                 return (SK_PNMI_ERR_GENERAL);
 
6410         /* If no keys are available return now */
 
6411         if (*pKeyNo == 0 || BufKeysLen == 0) {
 
6413                 return (SK_PNMI_ERR_OK);
 
6416          * If the key list is too long for us trunc it and give a
 
6417          * errorlog notification. This case should not happen because
 
6418          * the maximum number of keys is limited due to RAM limitations
 
6420         if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
 
6422                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
 
6425                 *pKeyNo = SK_PNMI_VPD_ENTRIES;
 
6429          * Now build an array of fixed string length size and copy
 
6430          * the keys together.
 
6432         for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
 
6435                 if (BufKeys[Offset] != 0) {
 
6440                 if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
 
6442                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
 
6444                         return (SK_PNMI_ERR_GENERAL);
 
6447                 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
 
6448                         &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
 
6451                 StartOffset = Offset + 1;
 
6454         /* Last key not zero terminated? Get it anyway */
 
6455         if (StartOffset < Offset) {
 
6457                 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
 
6458                         &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
 
6461         return (SK_PNMI_ERR_OK);
 
6464 /*****************************************************************************
 
6466  * SirqUpdate - Let the SIRQ update its internal values
 
6469  *      Just to be sure that the SIRQ module holds its internal data
 
6470  *      structures up to date, we send an update event before we make
 
6474  *      SK_PNMI_ERR_OK       Task successfully performed.
 
6475  *      SK_PNMI_ERR_GENERAL  Something went wrong.
 
6477 PNMI_STATIC int SirqUpdate(
 
6478 SK_AC *pAC,     /* Pointer to adapter context */
 
6479 SK_IOC IoC)     /* IO context handle */
 
6481         SK_EVPARA       EventParam;
 
6484         /* Was the module already updated during the current PNMI call? */
 
6485         if (pAC->Pnmi.SirqUpdatedFlag > 0) {
 
6487                 return (SK_PNMI_ERR_OK);
 
6490         /* Send an synchronuous update event to the module */
 
6491         SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
 
6492         if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
 
6494                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
 
6497                 return (SK_PNMI_ERR_GENERAL);
 
6500         return (SK_PNMI_ERR_OK);
 
6503 /*****************************************************************************
 
6505  * RlmtUpdate - Let the RLMT update its internal values
 
6508  *      Just to be sure that the RLMT module holds its internal data
 
6509  *      structures up to date, we send an update event before we make
 
6513  *      SK_PNMI_ERR_OK       Task successfully performed.
 
6514  *      SK_PNMI_ERR_GENERAL  Something went wrong.
 
6516 PNMI_STATIC int RlmtUpdate(
 
6517 SK_AC *pAC,     /* Pointer to adapter context */
 
6518 SK_IOC IoC,     /* IO context handle */
 
6519 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode allways zero */
 
6521         SK_EVPARA       EventParam;
 
6524         /* Was the module already updated during the current PNMI call? */
 
6525         if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
 
6527                 return (SK_PNMI_ERR_OK);
 
6530         /* Send an synchronuous update event to the module */
 
6531         SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
 
6532         EventParam.Para32[0] = NetIndex;
 
6533         EventParam.Para32[1] = (SK_U32)-1;
 
6534         if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
 
6536                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
 
6539                 return (SK_PNMI_ERR_GENERAL);
 
6542         return (SK_PNMI_ERR_OK);
 
6545 /*****************************************************************************
 
6547  * MacUpdate - Force the XMAC to output the current statistic
 
6550  *      The XMAC holds its statistic internally. To obtain the current
 
6551  *      values we must send a command so that the statistic data will
 
6552  *      be written to a predefined memory area on the adapter.
 
6555  *      SK_PNMI_ERR_OK       Task successfully performed.
 
6556  *      SK_PNMI_ERR_GENERAL  Something went wrong.
 
6558 PNMI_STATIC int MacUpdate(
 
6559 SK_AC *pAC,             /* Pointer to adapter context */
 
6560 SK_IOC IoC,             /* IO context handle */
 
6561 unsigned int FirstMac,  /* Index of the first Mac to be updated */
 
6562 unsigned int LastMac)   /* Index of the last Mac to be updated */
 
6564         unsigned int    MacIndex;
 
6567          * Were the statistics already updated during the
 
6568          * current PNMI call?
 
6570         if (pAC->Pnmi.MacUpdatedFlag > 0) {
 
6572                 return (SK_PNMI_ERR_OK);
 
6575         /* Send an update command to all MACs specified */
 
6576         for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
 
6579                  * 2002-09-13 pweber:   Freeze the current SW counters.
 
6580                  *                      (That should be done as close as
 
6581                  *                      possible to the update of the
 
6584                 if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
 
6585                         pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
 
6588                 /* 2002-09-13 pweber:  Update the HW counter  */
 
6589                 if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
 
6591                         return (SK_PNMI_ERR_GENERAL);
 
6595         return (SK_PNMI_ERR_OK);
 
6598 /*****************************************************************************
 
6600  * GetStatVal - Retrieve an XMAC statistic counter
 
6603  *      Retrieves the statistic counter of a virtual or physical port. The
 
6604  *      virtual port is identified by the index 0. It consists of all
 
6605  *      currently active ports. To obtain the counter value for this port
 
6606  *      we must add the statistic counter of all active ports. To grant
 
6607  *      continuous counter values for the virtual port even when port
 
6608  *      switches occur we must additionally add a delta value, which was
 
6609  *      calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
 
6612  *      Requested statistic value
 
6614 PNMI_STATIC SK_U64 GetStatVal(
 
6615 SK_AC *pAC,                                     /* Pointer to adapter context */
 
6616 SK_IOC IoC,                                     /* IO context handle */
 
6617 unsigned int LogPortIndex,      /* Index of the logical Port to be processed */
 
6618 unsigned int StatIndex,         /* Index to statistic value */
 
6619 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode allways zero */
 
6621         unsigned int    PhysPortIndex;
 
6622         unsigned int    PhysPortMax;
 
6626         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {   /* Dual net mode */
 
6628                 PhysPortIndex = NetIndex;
 
6630                 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
 
6632         else {  /* Single Net mode */
 
6634                 if (LogPortIndex == 0) {
 
6636                         PhysPortMax = pAC->GIni.GIMacsFound;
 
6638                         /* Add counter of all active ports */
 
6639                         for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
 
6642                                 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
 
6644                                         Val += GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
 
6648                         /* Correct value because of port switches */
 
6649                         Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
 
6652                         /* Get counter value of physical port */
 
6653                         PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
 
6655                         Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
 
6661 /*****************************************************************************
 
6663  * GetPhysStatVal - Get counter value for physical port
 
6666  *      Builds a 64bit counter value. Except for the octet counters
 
6667  *      the lower 32bit are counted in hardware and the upper 32bit
 
6668  *      in software by monitoring counter overflow interrupts in the
 
6669  *      event handler. To grant continous counter values during XMAC
 
6670  *      resets (caused by a workaround) we must add a delta value.
 
6671  *      The delta was calculated in the event handler when a
 
6672  *      SK_PNMI_EVT_XMAC_RESET was received.
 
6677 PNMI_STATIC SK_U64 GetPhysStatVal(
 
6678 SK_AC *pAC,                                     /* Pointer to adapter context */
 
6679 SK_IOC IoC,                                     /* IO context handle */
 
6680 unsigned int PhysPortIndex,     /* Index of the logical Port to be processed */
 
6681 unsigned int StatIndex)         /* Index to statistic value */
 
6688         unsigned int HelpIndex;
 
6691         SK_PNMI_PORT    *pPnmiPrt;
 
6692         SK_GEMACFUNC    *pFnMac;
 
6694         pPrt = &pAC->GIni.GP[PhysPortIndex];
 
6696         MacType = pAC->GIni.GIMacType;
 
6698         /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
6699         if (MacType == SK_MAC_XMAC) {
 
6700                 pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
 
6703                 pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex];
 
6706         pFnMac   = &pAC->GIni.GIFunc;
 
6708         switch (StatIndex) {
 
6710                 if (MacType == SK_MAC_GMAC) {
 
6711                         (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6712                                                         StatAddr[SK_PNMI_HTX_BROADCAST][MacType].Reg,
 
6714                         (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6715                                                         StatAddr[SK_PNMI_HTX_MULTICAST][MacType].Reg,
 
6718                         (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6719                                                         StatAddr[SK_PNMI_HTX_UNICAST][MacType].Reg,
 
6724                         (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6725                                                                                   StatAddr[StatIndex][MacType].Reg,
 
6728                 HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6732                 if (MacType == SK_MAC_GMAC) {
 
6733                         (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6734                                                         StatAddr[SK_PNMI_HRX_BROADCAST][MacType].Reg,
 
6736                         (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6737                                                         StatAddr[SK_PNMI_HRX_MULTICAST][MacType].Reg,
 
6740                         (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6741                                                         StatAddr[SK_PNMI_HRX_UNICAST][MacType].Reg,
 
6746                         (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6747                                                                                   StatAddr[StatIndex][MacType].Reg,
 
6750                 HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6753         case SK_PNMI_HTX_OCTET:
 
6754         case SK_PNMI_HRX_OCTET:
 
6755                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6756                                                                           StatAddr[StatIndex][MacType].Reg,
 
6758                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6759                                                                           StatAddr[StatIndex + 1][MacType].Reg,
 
6763         case SK_PNMI_HTX_BURST:
 
6764         case SK_PNMI_HTX_EXCESS_DEF:
 
6765         case SK_PNMI_HTX_CARRIER:
 
6766                 /* Not supported by GMAC */
 
6767                 if (MacType == SK_MAC_GMAC) {
 
6771                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6772                                                                           StatAddr[StatIndex][MacType].Reg,
 
6774                 HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6777         case SK_PNMI_HTX_MACC:
 
6778                 /* GMAC only supports PAUSE MAC control frames */
 
6779                 if (MacType == SK_MAC_GMAC) {
 
6780                         HelpIndex = SK_PNMI_HTX_PMACC;
 
6783                         HelpIndex = StatIndex;
 
6786                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6787                                                                 StatAddr[HelpIndex][MacType].Reg,
 
6790                 HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6793         case SK_PNMI_HTX_COL:
 
6794         case SK_PNMI_HRX_UNDERSIZE:
 
6795                 /* Not supported by XMAC */
 
6796                 if (MacType == SK_MAC_XMAC) {
 
6800                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6801                                                                           StatAddr[StatIndex][MacType].Reg,
 
6803                 HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6806         case SK_PNMI_HTX_DEFFERAL:
 
6807                 /* Not supported by GMAC */
 
6808                 if (MacType == SK_MAC_GMAC) {
 
6813                  * XMAC counts frames with deferred transmission
 
6814                  * even in full-duplex mode.
 
6816                  * In full-duplex mode the counter remains constant!
 
6818                 if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) ||
 
6819                         (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL)) {
 
6825                         /* Otherwise get contents of hardware register */
 
6826                         (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6827                                                                                   StatAddr[StatIndex][MacType].Reg,
 
6829                         HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6833         case SK_PNMI_HRX_BADOCTET:
 
6834                 /* Not supported by XMAC */
 
6835                 if (MacType == SK_MAC_XMAC) {
 
6839                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6840                                                                           StatAddr[StatIndex][MacType].Reg,
 
6842                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6843                                                                           StatAddr[StatIndex + 1][MacType].Reg,
 
6847         case SK_PNMI_HTX_OCTETLOW:
 
6848         case SK_PNMI_HRX_OCTETLOW:
 
6849         case SK_PNMI_HRX_BADOCTETLOW:
 
6852         case SK_PNMI_HRX_LONGFRAMES:
 
6853                 /* For XMAC the SW counter is managed by PNMI */
 
6854                 if (MacType == SK_MAC_XMAC) {
 
6855                         return (pPnmiPrt->StatRxLongFrameCts);
 
6858                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6859                                                                           StatAddr[StatIndex][MacType].Reg,
 
6861                 HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6864         case SK_PNMI_HRX_TOO_LONG:
 
6865                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6866                                                                 StatAddr[StatIndex][MacType].Reg,
 
6868                 HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6870                 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
 
6872                 if (MacType == SK_MAC_GMAC) {
 
6873                         /* For GMAC the SW counter is additionally managed by PNMI */
 
6874                         Val += pPnmiPrt->StatRxFrameTooLongCts;
 
6878                          * Frames longer than IEEE 802.3 frame max size are counted
 
6879                          * by XMAC in frame_too_long counter even reception of long
 
6880                          * frames was enabled and the frame was correct.
 
6881                          * So correct the value by subtracting RxLongFrame counter.
 
6883                         Val -= pPnmiPrt->StatRxLongFrameCts;
 
6886                 LowVal = (SK_U32)Val;
 
6887                 HighVal = (SK_U32)(Val >> 32);
 
6890         case SK_PNMI_HRX_SHORTS:
 
6891                 /* Not supported by GMAC */
 
6892                 if (MacType == SK_MAC_GMAC) {
 
6898                  * XMAC counts short frame errors even if link down (#10620)
 
6900                  * If link-down the counter remains constant
 
6902                 if (pPrt->PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
 
6904                         /* Otherwise get incremental difference */
 
6905                         (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6906                                                                                   StatAddr[StatIndex][MacType].Reg,
 
6908                         HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6910                         Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
 
6911                         Val -= pPnmiPrt->RxShortZeroMark;
 
6913                         LowVal = (SK_U32)Val;
 
6914                         HighVal = (SK_U32)(Val >> 32);
 
6918         case SK_PNMI_HRX_MACC:
 
6919         case SK_PNMI_HRX_MACC_UNKWN:
 
6920         case SK_PNMI_HRX_BURST:
 
6921         case SK_PNMI_HRX_MISSED:
 
6922         case SK_PNMI_HRX_FRAMING:
 
6923         case SK_PNMI_HRX_CARRIER:
 
6924         case SK_PNMI_HRX_IRLENGTH:
 
6925         case SK_PNMI_HRX_SYMBOL:
 
6926         case SK_PNMI_HRX_CEXT:
 
6927                 /* Not supported by GMAC */
 
6928                 if (MacType == SK_MAC_GMAC) {
 
6932                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6933                                                                           StatAddr[StatIndex][MacType].Reg,
 
6935                 HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6938         case SK_PNMI_HRX_PMACC_ERR:
 
6939                 /* For GMAC the SW counter is managed by PNMI */
 
6940                 if (MacType == SK_MAC_GMAC) {
 
6941                         return (pPnmiPrt->StatRxPMaccErr);
 
6944                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6945                                                                           StatAddr[StatIndex][MacType].Reg,
 
6947                 HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6950         /* SW counter managed by PNMI */
 
6951         case SK_PNMI_HTX_SYNC:
 
6952                 LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
 
6953                 HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
 
6956         /* SW counter managed by PNMI */
 
6957         case SK_PNMI_HTX_SYNC_OCTET:
 
6958                 LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
 
6959                 HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
 
6962         case SK_PNMI_HRX_FCS:
 
6964                  * Broadcom filters FCS errors and counts it in
 
6965                  * Receive Error Counter register
 
6967                 if (pPrt->PhyType == SK_PHY_BCOM) {
 
6968                         /* do not read while not initialized (PHY_READ hangs!)*/
 
6969                         if (pPrt->PState != SK_PRT_RESET) {
 
6970                                 SkXmPhyRead(pAC, IoC, PhysPortIndex, PHY_BCOM_RE_CTR, &Word);
 
6974                         HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6977                         (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6978                                                                                   StatAddr[StatIndex][MacType].Reg,
 
6980                         HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6985                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6986                                                                           StatAddr[StatIndex][MacType].Reg,
 
6988                 HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6992         Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
 
6994         /* Correct value because of possible XMAC reset. XMAC Errata #2 */
 
6995         Val += pPnmiPrt->CounterOffset[StatIndex];
 
7000 /*****************************************************************************
 
7002  * ResetCounter - Set all counters and timestamps to zero
 
7005  *      Notifies other common modules which store statistic data to
 
7006  *      reset their counters and finally reset our own counters.
 
7011 PNMI_STATIC void ResetCounter(
 
7012 SK_AC *pAC,             /* Pointer to adapter context */
 
7013 SK_IOC IoC,             /* IO context handle */
 
7016         unsigned int    PhysPortIndex;
 
7017         SK_EVPARA       EventParam;
 
7020         SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
 
7022         /* Notify sensor module */
 
7023         SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
 
7025         /* Notify RLMT module */
 
7026         EventParam.Para32[0] = NetIndex;
 
7027         EventParam.Para32[1] = (SK_U32)-1;
 
7028         SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
 
7029         EventParam.Para32[1] = 0;
 
7031         /* Notify SIRQ module */
 
7032         SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
 
7034         /* Notify CSUM module */
 
7036         EventParam.Para32[0] = NetIndex;
 
7037         EventParam.Para32[1] = (SK_U32)-1;
 
7038         SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
 
7040 #endif /* SK_USE_CSUM */
 
7042         /* Clear XMAC statistic */
 
7043         for (PhysPortIndex = 0; PhysPortIndex <
 
7044                 (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
 
7046                 (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex);
 
7048                 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
 
7049                         0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
 
7050                 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
 
7051                         CounterOffset, 0, sizeof(pAC->Pnmi.Port[
 
7052                         PhysPortIndex].CounterOffset));
 
7053                 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
 
7054                         0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
 
7055                 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
 
7056                         StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
 
7057                         PhysPortIndex].StatSyncOctetsCts));
 
7058                 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
 
7059                         StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
 
7060                         PhysPortIndex].StatRxLongFrameCts));
 
7061                 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
 
7062                                   StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[
 
7063                         PhysPortIndex].StatRxFrameTooLongCts));
 
7064                 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
 
7065                                   StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[
 
7066                         PhysPortIndex].StatRxPMaccErr));
 
7070          * Clear local statistics
 
7072         SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
 
7073                   sizeof(pAC->Pnmi.VirtualCounterOffset));
 
7074         pAC->Pnmi.RlmtChangeCts = 0;
 
7075         pAC->Pnmi.RlmtChangeTime = 0;
 
7076         SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
 
7077                 sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
 
7078         pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
 
7079         pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
 
7080         pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
 
7081         pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
 
7082         pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
 
7083         pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
 
7084         pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
 
7085         pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
 
7086         pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
 
7087         pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
 
7088         pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
 
7089         pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
 
7092 /*****************************************************************************
 
7094  * GetTrapEntry - Get an entry in the trap buffer
 
7097  *      The trap buffer stores various events. A user application somehow
 
7098  *      gets notified that an event occured and retrieves the trap buffer
 
7099  *      contens (or simply polls the buffer). The buffer is organized as
 
7100  *      a ring which stores the newest traps at the beginning. The oldest
 
7101  *      traps are overwritten by the newest ones. Each trap entry has a
 
7102  *      unique number, so that applications may detect new trap entries.
 
7105  *      A pointer to the trap entry
 
7107 PNMI_STATIC char* GetTrapEntry(
 
7108 SK_AC *pAC,             /* Pointer to adapter context */
 
7109 SK_U32 TrapId,          /* SNMP ID of the trap */
 
7110 unsigned int Size)      /* Space needed for trap entry */
 
7112         unsigned int            BufPad = pAC->Pnmi.TrapBufPad;
 
7113         unsigned int            BufFree = pAC->Pnmi.TrapBufFree;
 
7114         unsigned int            Beg = pAC->Pnmi.TrapQueueBeg;
 
7115         unsigned int            End = pAC->Pnmi.TrapQueueEnd;
 
7116         char                    *pBuf = &pAC->Pnmi.TrapBuf[0];
 
7118         unsigned int            NeededSpace;
 
7119         unsigned int            EntrySize;
 
7124         /* Last byte of entry will get a copy of the entry length */
 
7128          * Calculate needed buffer space */
 
7135                 NeededSpace = Beg + Size;
 
7140          * Check if enough buffer space is provided. Otherwise
 
7141          * free some entries. Leave one byte space between begin
 
7142          * and end of buffer to make it possible to detect whether
 
7143          * the buffer is full or empty
 
7145         while (BufFree < NeededSpace + 1) {
 
7149                         End = SK_PNMI_TRAP_QUEUE_LEN;
 
7152                 EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
 
7153                 BufFree += EntrySize;
 
7156                 SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
 
7158                 if (End == BufPad) {
 
7160                         SK_MEMSET(pBuf, (char)(-1), End);
 
7169          * Insert new entry as first entry. Newest entries are
 
7170          * stored at the beginning of the queue.
 
7175                 Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
 
7180         BufFree -= NeededSpace;
 
7182         /* Save the current offsets */
 
7183         pAC->Pnmi.TrapQueueBeg = Beg;
 
7184         pAC->Pnmi.TrapQueueEnd = End;
 
7185         pAC->Pnmi.TrapBufPad = BufPad;
 
7186         pAC->Pnmi.TrapBufFree = BufFree;
 
7188         /* Initialize the trap entry */
 
7189         *(pBuf + Beg + Size - 1) = (char)Size;
 
7190         *(pBuf + Beg) = (char)Size;
 
7191         Val32 = (pAC->Pnmi.TrapUnique) ++;
 
7192         SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
 
7193         SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
 
7194         Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
 
7195         SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
 
7197         return (pBuf + Beg);
 
7200 /*****************************************************************************
 
7202  * CopyTrapQueue - Copies the trap buffer for the TRAP OID
 
7205  *      On a query of the TRAP OID the trap buffer contents will be
 
7206  *      copied continuously to the request buffer, which must be large
 
7207  *      enough. No length check is performed.
 
7212 PNMI_STATIC void CopyTrapQueue(
 
7213 SK_AC *pAC,             /* Pointer to adapter context */
 
7214 char *pDstBuf)          /* Buffer to which the queued traps will be copied */
 
7216         unsigned int    BufPad = pAC->Pnmi.TrapBufPad;
 
7217         unsigned int    Trap = pAC->Pnmi.TrapQueueBeg;
 
7218         unsigned int    End = pAC->Pnmi.TrapQueueEnd;
 
7219         char            *pBuf = &pAC->Pnmi.TrapBuf[0];
 
7221         unsigned int    DstOff = 0;
 
7224         while (Trap != End) {
 
7226                 Len = (unsigned int)*(pBuf + Trap);
 
7229                  * Last byte containing a copy of the length will
 
7232                 *(pDstBuf + DstOff) = (char)(Len - 1);
 
7233                 SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
 
7237                 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
 
7244 /*****************************************************************************
 
7246  * GetTrapQueueLen - Get the length of the trap buffer
 
7249  *      Evaluates the number of currently stored traps and the needed
 
7250  *      buffer size to retrieve them.
 
7255 PNMI_STATIC void GetTrapQueueLen(
 
7256 SK_AC *pAC,             /* Pointer to adapter context */
 
7257 unsigned int *pLen,     /* Length in Bytes of all queued traps */
 
7258 unsigned int *pEntries) /* Returns number of trapes stored in queue */
 
7260         unsigned int    BufPad = pAC->Pnmi.TrapBufPad;
 
7261         unsigned int    Trap = pAC->Pnmi.TrapQueueBeg;
 
7262         unsigned int    End = pAC->Pnmi.TrapQueueEnd;
 
7263         char            *pBuf = &pAC->Pnmi.TrapBuf[0];
 
7265         unsigned int    Entries = 0;
 
7266         unsigned int    TotalLen = 0;
 
7269         while (Trap != End) {
 
7271                 Len = (unsigned int)*(pBuf + Trap);
 
7272                 TotalLen += Len - 1;
 
7276                 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
 
7282         *pEntries = Entries;
 
7286 /*****************************************************************************
 
7288  * QueueSimpleTrap - Store a simple trap to the trap buffer
 
7291  *      A simple trap is a trap with now additional data. It consists
 
7292  *      simply of a trap code.
 
7297 PNMI_STATIC void QueueSimpleTrap(
 
7298 SK_AC *pAC,             /* Pointer to adapter context */
 
7299 SK_U32 TrapId)          /* Type of sensor trap */
 
7301         GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
 
7304 /*****************************************************************************
 
7306  * QueueSensorTrap - Stores a sensor trap in the trap buffer
 
7309  *      Gets an entry in the trap buffer and fills it with sensor related
 
7315 PNMI_STATIC void QueueSensorTrap(
 
7316 SK_AC *pAC,                     /* Pointer to adapter context */
 
7317 SK_U32 TrapId,                  /* Type of sensor trap */
 
7318 unsigned int SensorIndex)       /* Index of sensor which caused the trap */
 
7321         unsigned int    Offset;
 
7322         unsigned int    DescrLen;
 
7326         /* Get trap buffer entry */
 
7327         DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
 
7328         pBuf = GetTrapEntry(pAC, TrapId,
 
7329                 SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
 
7330         Offset = SK_PNMI_TRAP_SIMPLE_LEN;
 
7332         /* Store additionally sensor trap related data */
 
7333         Val32 = OID_SKGE_SENSOR_INDEX;
 
7334         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
7335         *(pBuf + Offset + 4) = 4;
 
7336         Val32 = (SK_U32)SensorIndex;
 
7337         SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
 
7340         Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
 
7341         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
7342         *(pBuf + Offset + 4) = (char)DescrLen;
 
7343         SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
 
7345         Offset += DescrLen + 5;
 
7347         Val32 = OID_SKGE_SENSOR_TYPE;
 
7348         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
7349         *(pBuf + Offset + 4) = 1;
 
7350         *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
 
7353         Val32 = OID_SKGE_SENSOR_VALUE;
 
7354         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
7355         *(pBuf + Offset + 4) = 4;
 
7356         Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
 
7357         SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
 
7360 /*****************************************************************************
 
7362  * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
 
7365  *      Nothing further to explain.
 
7370 PNMI_STATIC void QueueRlmtNewMacTrap(
 
7371 SK_AC *pAC,             /* Pointer to adapter context */
 
7372 unsigned int ActiveMac) /* Index (0..n) of the currently active port */
 
7378         pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
 
7379                 SK_PNMI_TRAP_RLMT_CHANGE_LEN);
 
7381         Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
 
7382         SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
 
7383         *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
 
7384         *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
 
7387 /*****************************************************************************
 
7389  * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
 
7392  *      Nothing further to explain.
 
7397 PNMI_STATIC void QueueRlmtPortTrap(
 
7398 SK_AC *pAC,             /* Pointer to adapter context */
 
7399 SK_U32 TrapId,          /* Type of RLMT port trap */
 
7400 unsigned int PortIndex) /* Index of the port, which changed its state */
 
7406         pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
 
7408         Val32 = OID_SKGE_RLMT_PORT_INDEX;
 
7409         SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
 
7410         *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
 
7411         *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
 
7414 /*****************************************************************************
 
7416  * CopyMac - Copies a MAC address
 
7419  *      Nothing further to explain.
 
7424 PNMI_STATIC void CopyMac(
 
7425 char *pDst,             /* Pointer to destination buffer */
 
7426 SK_MAC_ADDR *pMac)      /* Pointer of Source */
 
7431         for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
 
7433                 *(pDst + i) = pMac->a[i];
 
7437 #ifdef SK_POWER_MGMT
 
7438 /*****************************************************************************
 
7440  * PowerManagement - OID handler function of PowerManagement OIDs
 
7443  *      The code is simple. No description necessary.
 
7446  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
7447  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
7448  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
7449  *                               the correct data (e.g. a 32bit value is
 
7450  *                               needed, but a 16 bit value was passed).
 
7451  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
7452  *                               exist (e.g. port instance 3 on a two port
 
7456 PNMI_STATIC int PowerManagement(
 
7457 SK_AC *pAC,             /* Pointer to adapter context */
 
7458 SK_IOC IoC,             /* IO context handle */
 
7459 int Action,             /* Get/PreSet/Set action */
 
7460 SK_U32 Id,              /* Object ID that is to be processed */
 
7461 char *pBuf,             /* Buffer to which to mgmt data will be retrieved */
 
7462 unsigned int *pLen,     /* On call: buffer length. On return: used buffer */
 
7463 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
7464 unsigned int TableIndex, /* Index to the Id table */
 
7465 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode allways zero */
 
7468         SK_U32  RetCode = SK_PNMI_ERR_GENERAL;
 
7471          * Check instance. We only handle single instance variables
 
7473         if (Instance != (SK_U32)(-1) && Instance != 1) {
 
7476                 return (SK_PNMI_ERR_UNKNOWN_INST);
 
7483     case OID_PNP_CAPABILITIES:
 
7484         if (*pLen < sizeof(SK_PNP_CAPABILITIES)) {
 
7486             *pLen = sizeof(SK_PNP_CAPABILITIES);
 
7487             return (SK_PNMI_ERR_TOO_SHORT);
 
7491         case OID_PNP_SET_POWER:
 
7492     case OID_PNP_QUERY_POWER:
 
7493         if (*pLen < sizeof(SK_DEVICE_POWER_STATE))
 
7495                 *pLen = sizeof(SK_DEVICE_POWER_STATE);
 
7496                 return (SK_PNMI_ERR_TOO_SHORT);
 
7500     case OID_PNP_ADD_WAKE_UP_PATTERN:
 
7501     case OID_PNP_REMOVE_WAKE_UP_PATTERN:
 
7502                 if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) {
 
7504                         *pLen = sizeof(SK_PM_PACKET_PATTERN);
 
7505                         return (SK_PNMI_ERR_TOO_SHORT);
 
7509     case OID_PNP_ENABLE_WAKE_UP:
 
7510         if (*pLen < sizeof(SK_U32)) {
 
7512             *pLen = sizeof(SK_U32);
 
7513             return (SK_PNMI_ERR_TOO_SHORT);
 
7521         if (Action == SK_PNMI_GET) {
 
7528                 case OID_PNP_CAPABILITIES:
 
7529                         RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen);
 
7532                 case OID_PNP_QUERY_POWER:
 
7533                         /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
 
7534                          the miniport to indicate whether it can transition its NIC
 
7535                          to the low-power state.
 
7536                          A miniport driver must always return NDIS_STATUS_SUCCESS
 
7537                          to a query of OID_PNP_QUERY_POWER. */
 
7538                         *pLen = sizeof(SK_DEVICE_POWER_STATE);
 
7539             RetCode = SK_PNMI_ERR_OK;
 
7542                         /* NDIS handles these OIDs as write-only.
 
7543                          * So in case of get action the buffer with written length = 0
 
7546                 case OID_PNP_SET_POWER:
 
7547                 case OID_PNP_ADD_WAKE_UP_PATTERN:
 
7548                 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
 
7550             RetCode = SK_PNMI_ERR_NOT_SUPPORTED;
 
7553                 case OID_PNP_ENABLE_WAKE_UP:
 
7554                         RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen);
 
7558                         RetCode = SK_PNMI_ERR_GENERAL;
 
7567          * Perform preset or set
 
7570         /* POWER module does not support PRESET action */
 
7571         if (Action == SK_PNMI_PRESET) {
 
7572                 return (SK_PNMI_ERR_OK);
 
7576         case OID_PNP_SET_POWER:
 
7577                 RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen);        
 
7580         case OID_PNP_ADD_WAKE_UP_PATTERN:
 
7581                 RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen);        
 
7584         case OID_PNP_REMOVE_WAKE_UP_PATTERN:
 
7585                 RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen);     
 
7588         case OID_PNP_ENABLE_WAKE_UP:
 
7589                 RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen);
 
7593                 RetCode = SK_PNMI_ERR_READ_ONLY;
 
7598 #endif /* SK_POWER_MGMT */
 
7600 #ifdef SK_DIAG_SUPPORT
 
7601 /*****************************************************************************
 
7603  * DiagActions - OID handler function of Diagnostic driver 
 
7606  *      The code is simple. No description necessary.
 
7609  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
7610  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
7611  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
7612  *                               the correct data (e.g. a 32bit value is
 
7613  *                               needed, but a 16 bit value was passed).
 
7614  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
7615  *                           exist (e.g. port instance 3 on a two port
 
7619 PNMI_STATIC int DiagActions(
 
7620 SK_AC *pAC,             /* Pointer to adapter context */
 
7621 SK_IOC IoC,             /* IO context handle */
 
7622 int Action,             /* GET/PRESET/SET action */
 
7623 SK_U32 Id,              /* Object ID that is to be processed */
 
7624 char *pBuf,             /* Buffer used for the management data transfer */
 
7625 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
7626 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
7627 unsigned int TableIndex, /* Index to the Id table */
 
7628 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
7632         SK_U32  RetCode = SK_PNMI_ERR_GENERAL;
 
7635          * Check instance. We only handle single instance variables.
 
7637         if (Instance != (SK_U32)(-1) && Instance != 1) {
 
7640                 return (SK_PNMI_ERR_UNKNOWN_INST);
 
7648         case OID_SKGE_DIAG_MODE:
 
7649                 if (*pLen < sizeof(SK_U32)) {
 
7651                         *pLen = sizeof(SK_U32);
 
7652                         return (SK_PNMI_ERR_TOO_SHORT);
 
7657                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040, SK_PNMI_ERR040MSG);
 
7659                 return (SK_PNMI_ERR_GENERAL);
 
7662         /* Perform action. */
 
7665         if (Action == SK_PNMI_GET) {
 
7669                 case OID_SKGE_DIAG_MODE:
 
7670                         DiagStatus = pAC->Pnmi.DiagAttached;
 
7671                         SK_PNMI_STORE_U32(pBuf, DiagStatus);
 
7672                         *pLen = sizeof(SK_U32); 
 
7673                         RetCode = SK_PNMI_ERR_OK;
 
7678                         RetCode = SK_PNMI_ERR_GENERAL;
 
7684         /* From here SET or PRESET value. */
 
7686         /* PRESET value is not supported. */
 
7687         if (Action == SK_PNMI_PRESET) {
 
7688                 return (SK_PNMI_ERR_OK); 
 
7693                 case OID_SKGE_DIAG_MODE:
 
7695                         /* Handle the SET. */
 
7698                                 /* Attach the DIAG to this adapter. */
 
7699                                 case SK_DIAG_ATTACHED:
 
7700                                         /* Check if we come from running */
 
7701                                         if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
 
7703                                                 RetCode = SkDrvLeaveDiagMode(pAC);
 
7706                                         else if (pAC->Pnmi.DiagAttached == SK_DIAG_IDLE) {
 
7708                                                 RetCode = SK_PNMI_ERR_OK;
 
7713                                                 RetCode = SK_PNMI_ERR_GENERAL;
 
7717                                         if (RetCode == SK_PNMI_ERR_OK) {
 
7719                                                 pAC->Pnmi.DiagAttached = SK_DIAG_ATTACHED;
 
7723                                 /* Enter the DIAG mode in the driver. */
 
7724                                 case SK_DIAG_RUNNING:
 
7725                                         RetCode = SK_PNMI_ERR_OK;
 
7728                                          * If DiagAttached is set, we can tell the driver
 
7729                                          * to enter the DIAG mode.
 
7731                                         if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
 
7732                                                 /* If DiagMode is not active, we can enter it. */
 
7733                                                 if (!pAC->DiagModeActive) {
 
7735                                                         RetCode = SkDrvEnterDiagMode(pAC); 
 
7739                                                         RetCode = SK_PNMI_ERR_GENERAL;
 
7744                                                 RetCode = SK_PNMI_ERR_GENERAL;
 
7747                                         if (RetCode == SK_PNMI_ERR_OK) {
 
7749                                                 pAC->Pnmi.DiagAttached = SK_DIAG_RUNNING;
 
7754                                         /* Check if we come from running */
 
7755                                         if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
 
7757                                                 RetCode = SkDrvLeaveDiagMode(pAC);
 
7760                                         else if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
 
7762                                                 RetCode = SK_PNMI_ERR_OK;
 
7767                                                 RetCode = SK_PNMI_ERR_GENERAL;
 
7771                                         if (RetCode == SK_PNMI_ERR_OK) {
 
7773                                                 pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
 
7778                                         RetCode = SK_PNMI_ERR_BAD_VALUE;
 
7784                         RetCode = SK_PNMI_ERR_GENERAL;
 
7787         if (RetCode == SK_PNMI_ERR_OK) {
 
7788                 *pLen = sizeof(SK_U32);
 
7796 #endif /* SK_DIAG_SUPPORT */
 
7798 /*****************************************************************************
 
7800  * Vct - OID handler function of  OIDs
 
7803  *      The code is simple. No description necessary.
 
7806  *      SK_PNMI_ERR_OK           The request was performed successfully.
 
7807  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
7808  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
7809  *                               the correct data (e.g. a 32bit value is
 
7810  *                               needed, but a 16 bit value was passed).
 
7811  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
7812  *                           exist (e.g. port instance 3 on a two port
 
7814  *      SK_PNMI_ERR_READ_ONLY    Only the Get action is allowed.
 
7818 PNMI_STATIC int Vct(
 
7819 SK_AC *pAC,             /* Pointer to adapter context */
 
7820 SK_IOC IoC,             /* IO context handle */
 
7821 int Action,             /* GET/PRESET/SET action */
 
7822 SK_U32 Id,              /* Object ID that is to be processed */
 
7823 char *pBuf,             /* Buffer used for the management data transfer */
 
7824 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
7825 SK_U32 Instance,        /* Instance (-1,2..n) that is to be queried */
 
7826 unsigned int TableIndex, /* Index to the Id table */
 
7827 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
7830         SK_PNMI_VCT     *pVctBackupData;
 
7833         SK_U32          PhysPortIndex;
 
7837         SK_U32          RetCode = SK_PNMI_ERR_GENERAL;
 
7843          * Calculate the port indexes from the instance.
 
7845         PhysPortMax = pAC->GIni.GIMacsFound;
 
7846         LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
 
7848         /* Dual net mode? */
 
7849         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
7853         if ((Instance != (SK_U32) (-1))) {
 
7854                 /* Check instance range. */
 
7855                 if ((Instance < 2) || (Instance > LogPortMax)) {
 
7857                         return (SK_PNMI_ERR_UNKNOWN_INST);
 
7860                 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
7861                         PhysPortIndex = NetIndex;
 
7864                         PhysPortIndex = Instance - 2;
 
7866                 Limit = PhysPortIndex + 1;
 
7870                  * Instance == (SK_U32) (-1), get all Instances of that OID.
 
7872                  * Not implemented yet. May be used in future releases.
 
7875                 Limit = PhysPortMax;
 
7878         pPrt = &pAC->GIni.GP[PhysPortIndex];
 
7879         if (pPrt->PHWLinkUp) {
 
7886         /* Check MAC type */
 
7887         if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
 
7889                 return (SK_PNMI_ERR_GENERAL);
 
7892         /* Initialize backup data pointer. */
 
7893         pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
 
7895         /* Check action type */
 
7896         if (Action == SK_PNMI_GET) {
 
7900                 case OID_SKGE_VCT_GET:
 
7901                         if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
 
7902                                 *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
 
7903                                 return (SK_PNMI_ERR_TOO_SHORT);
 
7907                 case OID_SKGE_VCT_STATUS:
 
7908                         if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
 
7909                                 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
 
7910                                 return (SK_PNMI_ERR_TOO_SHORT);
 
7916                         return (SK_PNMI_ERR_GENERAL);
 
7921                 for (; PhysPortIndex < Limit; PhysPortIndex++) {
 
7924                         case OID_SKGE_VCT_GET:
 
7925                                 if ((Link == SK_FALSE) &&
 
7926                                         (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
 
7927                                         RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
 
7929                                                 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
 
7930                                                 pAC->Pnmi.VctStatus[PhysPortIndex] |=
 
7931                                                         (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
 
7933                                                 /* Copy results for later use to PNMI struct. */
 
7934                                                 for (i = 0; i < 4; i++)  {
 
7935                                                         if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
 
7936                                                                 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
 
7937                                                                         pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
 
7940                                                         if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
 
7941                                                                 CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
 
7946                                                         pVctBackupData->PMdiPairLen[i] = CableLength;
 
7947                                                         pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
 
7950                                                 Para.Para32[0] = PhysPortIndex;
 
7951                                                 Para.Para32[1] = -1;
 
7952                                                 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
 
7953                                                 SkEventDispatcher(pAC, IoC);
 
7956                                                 ; /* VCT test is running. */
 
7960                                 /* Get all results. */
 
7961                                 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
 
7962                                 Offset += sizeof(SK_U8);
 
7963                                 *(pBuf + Offset) = pPrt->PCableLen;
 
7964                                 Offset += sizeof(SK_U8);
 
7965                                 for (i = 0; i < 4; i++)  {
 
7966                                         SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
 
7967                                         Offset += sizeof(SK_U32);
 
7969                                 for (i = 0; i < 4; i++)  {
 
7970                                         *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
 
7971                                         Offset += sizeof(SK_U8);
 
7974                                 RetCode = SK_PNMI_ERR_OK;
 
7977                         case OID_SKGE_VCT_STATUS:
 
7978                                 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
 
7979                                 Offset += sizeof(SK_U8);
 
7980                                 RetCode = SK_PNMI_ERR_OK;
 
7985                                 return (SK_PNMI_ERR_GENERAL);
 
7991         } /* if SK_PNMI_GET */
 
7994          * From here SET or PRESET action. Check if the passed
 
7995          * buffer length is plausible.
 
8000         case OID_SKGE_VCT_SET:
 
8001                 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
 
8002                         *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
 
8003                         return (SK_PNMI_ERR_TOO_SHORT);
 
8009                 return (SK_PNMI_ERR_GENERAL);
 
8013          * Perform preset or set.
 
8016         /* VCT does not support PRESET action. */
 
8017         if (Action == SK_PNMI_PRESET) {
 
8018                 return (SK_PNMI_ERR_OK);
 
8022         for (; PhysPortIndex < Limit; PhysPortIndex++) {
 
8024                 case OID_SKGE_VCT_SET: /* Start VCT test. */
 
8025                         if (Link == SK_FALSE) {
 
8026                                 SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
 
8028                                 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
 
8029                                 if (RetCode == 0) { /* RetCode: 0 => Start! */
 
8030                                         pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
 
8031                                         pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
 
8032                                         pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
 
8035                                          * Start VCT timer counter.
 
8037                                         SK_MEMSET((char *) &Para, 0, sizeof(Para));
 
8038                                         Para.Para32[0] = PhysPortIndex;
 
8039                                         Para.Para32[1] = -1;
 
8040                                         SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
 
8041                                                 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
 
8042                                         SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
 
8043                                         RetCode = SK_PNMI_ERR_OK;
 
8045                                 else { /* RetCode: 2 => Running! */
 
8046                                         SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
 
8047                                         RetCode = SK_PNMI_ERR_OK;
 
8050                         else { /* RetCode: 4 => Link! */
 
8052                                 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
 
8053                                 RetCode = SK_PNMI_ERR_OK;
 
8055                         Offset += sizeof(SK_U32);
 
8060                         return (SK_PNMI_ERR_GENERAL);
 
8069 PNMI_STATIC void CheckVctStatus(
 
8074 SK_U32          PhysPortIndex)
 
8077         SK_PNMI_VCT     *pVctData;
 
8080         pPrt = &pAC->GIni.GP[PhysPortIndex];
 
8082         pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
 
8083         pVctData->VctStatus = SK_PNMI_VCT_NONE;
 
8085         if (!pPrt->PHWLinkUp) {
 
8087                 /* Was a VCT test ever made before? */
 
8088                 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
 
8089                         if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
 
8090                                 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
 
8093                                 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
 
8097                 /* Check VCT test status. */
 
8098                 RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
 
8099                 if (RetCode == 2) { /* VCT test is running. */
 
8100                         pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
 
8102                 else { /* VCT data was copied to pAC here. Check PENDING state. */
 
8103                         if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
 
8104                                 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
 
8108                 if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
 
8109                         pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
 
8114                 /* Was a VCT test ever made before? */
 
8115                 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
 
8116                         pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
 
8117                         pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
 
8120                 /* DSP only valid in 100/1000 modes. */
 
8121                 if (pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed !=
 
8122                         SK_LSPEED_STAT_10MBPS) {        
 
8123                         pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
 
8126 } /* CheckVctStatus */
 
8129 /*****************************************************************************
 
8131  *      SkPnmiGenIoctl - Handles new generic PNMI IOCTL, calls the needed
 
8132  *                       PNMI function depending on the subcommand and
 
8133  *                       returns all data belonging to the complete database
 
8137  *      Looks up the requested subcommand, calls the corresponding handler
 
8138  *      function and passes all required parameters to it.
 
8139  *      The function is called by the driver. It is needed to handle the new
 
8140  *  generic PNMI IOCTL. This IOCTL is given to the driver and contains both
 
8141  *  the OID and a subcommand to decide what kind of request has to be done.
 
8144  *      SK_PNMI_ERR_OK           The request was successfully performed
 
8145  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured
 
8146  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to take
 
8148  *      SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown
 
8149  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
8150  *                           exist (e.g. port instance 3 on a two port
 
8154 SK_AC           *pAC,           /* Pointer to adapter context struct */
 
8155 SK_IOC          IoC,            /* I/O context */
 
8156 void            *pBuf,          /* Buffer used for the management data transfer */
 
8157 unsigned int *pLen,             /* Length of buffer */
 
8158 SK_U32          NetIndex)       /* NetIndex (0..n), in single net mode always zero */
 
8160 SK_I32  Mode;                   /* Store value of subcommand. */
 
8161 SK_U32  Oid;                    /* Store value of OID. */
 
8162 int             ReturnCode;             /* Store return value to show status of PNMI action. */
 
8163 int     HeaderLength;   /* Length of desired action plus OID. */
 
8165         ReturnCode = SK_PNMI_ERR_GENERAL;
 
8167         SK_MEMCPY(&Mode, pBuf, sizeof(SK_I32));
 
8168         SK_MEMCPY(&Oid, (char *) pBuf + sizeof(SK_I32), sizeof(SK_U32));
 
8169         HeaderLength = sizeof(SK_I32) + sizeof(SK_U32);
 
8170         *pLen = *pLen - HeaderLength;
 
8171         SK_MEMCPY((char *) pBuf + sizeof(SK_I32), (char *) pBuf + HeaderLength, *pLen);
 
8174         case SK_GET_SINGLE_VAR:
 
8175                 ReturnCode = SkPnmiGetVar(pAC, IoC, Oid, 
 
8176                                 (char *) pBuf + sizeof(SK_I32), pLen,
 
8177                                 ((SK_U32) (-1)), NetIndex);
 
8178                 SK_PNMI_STORE_U32(pBuf, ReturnCode);
 
8179                 *pLen = *pLen + sizeof(SK_I32);
 
8181         case SK_PRESET_SINGLE_VAR:
 
8182                 ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid, 
 
8183                                 (char *) pBuf + sizeof(SK_I32), pLen,
 
8184                                 ((SK_U32) (-1)), NetIndex);
 
8185                 SK_PNMI_STORE_U32(pBuf, ReturnCode);
 
8186                 *pLen = *pLen + sizeof(SK_I32);
 
8188         case SK_SET_SINGLE_VAR:
 
8189                 ReturnCode = SkPnmiSetVar(pAC, IoC, Oid, 
 
8190                                 (char *) pBuf + sizeof(SK_I32), pLen,
 
8191                                 ((SK_U32) (-1)), NetIndex);
 
8192                 SK_PNMI_STORE_U32(pBuf, ReturnCode);
 
8193                 *pLen = *pLen + sizeof(SK_I32);
 
8195         case SK_GET_FULL_MIB:
 
8196                 ReturnCode = SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex);
 
8198         case SK_PRESET_FULL_MIB:
 
8199                 ReturnCode = SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
 
8201         case SK_SET_FULL_MIB:
 
8202                 ReturnCode = SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
 
8208         return (ReturnCode);