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 #endif /* SK_PNMI_CHECK */
 
 398                 PortMax = pAC->GIni.GIMacsFound;
 
 400                 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
 
 402                         pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
 
 405                 /* Initialize DSP variables for Vct() to 0xff => Never written! */              
 
 406                 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
 
 407                         pAC->GIni.GP[PortIndex].PCableLen = 0xff;
 
 408                         pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
 
 409                         pVctBackupData->PCableLen = 0xff;
 
 415                 SK_IN16(IoC, B0_CTST, &Val16);
 
 416                 if ((Val16 & CS_BUS_CLOCK) == 0) {
 
 418                         pAC->Pnmi.PciBusSpeed = 33;
 
 421                         pAC->Pnmi.PciBusSpeed = 66;
 
 427                 SK_IN16(IoC, B0_CTST, &Val16);
 
 428                 if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
 
 430                         pAC->Pnmi.PciBusWidth = 32;
 
 433                         pAC->Pnmi.PciBusWidth = 64;
 
 439                 switch (pAC->GIni.GIChipId) {
 
 440                 case CHIP_ID_GENESIS:
 
 441                         pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
 
 445                         pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
 
 453                  * Get PMD and DeviceType
 
 455                 SK_IN8(IoC, B2_PMD_TYP, &Val8);
 
 459                         if (pAC->GIni.GIMacsFound > 1) {
 
 461                                 pAC->Pnmi.DeviceType = 0x00020002;
 
 464                                 pAC->Pnmi.DeviceType = 0x00020001;
 
 470                         if (pAC->GIni.GIMacsFound > 1) {
 
 472                                 pAC->Pnmi.DeviceType = 0x00020004;
 
 475                                 pAC->Pnmi.DeviceType = 0x00020003;
 
 481                         if (pAC->GIni.GIMacsFound > 1) {
 
 483                                 pAC->Pnmi.DeviceType = 0x00020006;
 
 486                                 pAC->Pnmi.DeviceType = 0x00020005;
 
 492                         if (pAC->GIni.GIMacsFound > 1) {
 
 494                                 pAC->Pnmi.DeviceType = 0x00020008;
 
 497                                 pAC->Pnmi.DeviceType = 0x00020007;
 
 503                         pAC->Pnmi.DeviceType = 0;
 
 510                 SK_IN8(IoC, B2_CONN_TYP, &Val8);
 
 513                         pAC->Pnmi.Connector = 2;
 
 517                         pAC->Pnmi.Connector = 3;
 
 521                         pAC->Pnmi.Connector = 4;
 
 525                         pAC->Pnmi.Connector = 5;
 
 529                         pAC->Pnmi.Connector = 6;
 
 533                         pAC->Pnmi.Connector = 1;
 
 540                  * Start timer for RLMT change counter
 
 542                 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
 
 543                 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
 
 544                         28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
 
 549                 break; /* Nothing todo */
 
 555 /*****************************************************************************
 
 557  * SkPnmiGetVar - Retrieves the value of a single OID
 
 560  *      Calls a general sub-function for all this stuff. If the instance
 
 561  *      -1 is passed, the values of all instances are returned in an
 
 565  *      SK_PNMI_ERR_OK           The request was successfully performed
 
 566  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured
 
 567  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to take
 
 569  *      SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown
 
 570  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
 571  *                           exist (e.g. port instance 3 on a two port
 
 574 static int SkPnmiGetVar(
 
 575 SK_AC *pAC,             /* Pointer to adapter context */
 
 576 SK_IOC IoC,             /* IO context handle */
 
 577 SK_U32 Id,              /* Object ID that is to be processed */
 
 578 void *pBuf,             /* Buffer to which the management data will be copied */
 
 579 unsigned int *pLen,     /* On call: buffer length. On return: used buffer */
 
 580 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
 581 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
 583         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
 584                 ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
 
 585                         Id, *pLen, Instance, NetIndex));
 
 587         return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
 
 588                 Instance, NetIndex));
 
 591 /*****************************************************************************
 
 593  * SkPnmiPreSetVar - Presets the value of a single OID
 
 596  *      Calls a general sub-function for all this stuff. The preset does
 
 597  *      the same as a set, but returns just before finally setting the
 
 598  *      new value. This is useful to check if a set might be successfull.
 
 599  *      If the instance -1 is passed, an array of values is supposed and
 
 600  *      all instances of the OID will be set.
 
 603  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
 604  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
 605  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
 606  *                               the correct data (e.g. a 32bit value is
 
 607  *                               needed, but a 16 bit value was passed).
 
 608  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 
 610  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 
 611  *      SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown.
 
 612  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
 613  *                           exist (e.g. port instance 3 on a two port
 
 616 static int SkPnmiPreSetVar(
 
 617 SK_AC *pAC,             /* Pointer to adapter context */
 
 618 SK_IOC IoC,             /* IO context handle */
 
 619 SK_U32 Id,              /* Object ID that is to be processed */
 
 620 void *pBuf,             /* Buffer to which the management data will be copied */
 
 621 unsigned int *pLen,     /* Total length of management data */
 
 622 SK_U32 Instance,        /* Instance (1..n) that is to be set or -1 */
 
 623 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
 625         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
 626                 ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
 
 627                         Id, *pLen, Instance, NetIndex));
 
 630         return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
 
 631                 Instance, NetIndex));
 
 634 /*****************************************************************************
 
 636  * SkPnmiSetVar - Sets the value of a single OID
 
 639  *      Calls a general sub-function for all this stuff. The preset does
 
 640  *      the same as a set, but returns just before finally setting the
 
 641  *      new value. This is useful to check if a set might be successfull.
 
 642  *      If the instance -1 is passed, an array of values is supposed and
 
 643  *      all instances of the OID will be set.
 
 646  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
 647  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
 648  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
 649  *                               the correct data (e.g. a 32bit value is
 
 650  *                               needed, but a 16 bit value was passed).
 
 651  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 
 653  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 
 654  *      SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown.
 
 655  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
 656  *                           exist (e.g. port instance 3 on a two port
 
 660 SK_AC *pAC,             /* Pointer to adapter context */
 
 661 SK_IOC IoC,             /* IO context handle */
 
 662 SK_U32 Id,              /* Object ID that is to be processed */
 
 663 void *pBuf,             /* Buffer to which the management data will be copied */
 
 664 unsigned int *pLen,     /* Total length of management data */
 
 665 SK_U32 Instance,        /* Instance (1..n) that is to be set or -1 */
 
 666 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
 668         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
 669                 ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
 
 670                         Id, *pLen, Instance, NetIndex));
 
 672         return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
 
 673                 Instance, NetIndex));
 
 676 /*****************************************************************************
 
 678  * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA
 
 681  *      Runs through the IdTable, queries the single OIDs and stores the
 
 682  *      returned data into the management database structure
 
 683  *      SK_PNMI_STRUCT_DATA. The offset of the OID in the structure
 
 684  *      is stored in the IdTable. The return value of the function will also
 
 685  *      be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
 
 686  *      minimum size of SK_PNMI_MIN_STRUCT_SIZE.
 
 689  *      SK_PNMI_ERR_OK           The request was successfully performed
 
 690  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured
 
 691  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to take
 
 693  *      SK_PNMI_ERR_UNKNOWN_NET  The requested NetIndex doesn't exist
 
 696 SK_AC *pAC,             /* Pointer to adapter context */
 
 697 SK_IOC IoC,             /* IO context handle */
 
 698 void *pBuf,             /* Buffer to which the management data will be copied. */
 
 699 unsigned int *pLen,     /* Length of buffer */
 
 700 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
 703         unsigned int    TableIndex;
 
 704         unsigned int    DstOffset;
 
 705         unsigned int    InstanceNo;
 
 706         unsigned int    InstanceCnt;
 
 709         char            KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
 
 712         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
 713                 ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
 
 716         if (*pLen < SK_PNMI_STRUCT_SIZE) {
 
 718                 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
 
 720                         SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
 
 724                 *pLen = SK_PNMI_STRUCT_SIZE;
 
 725                 return (SK_PNMI_ERR_TOO_SHORT);
 
 731         if (NetIndex >= pAC->Rlmt.NumNets) {
 
 732                 return (SK_PNMI_ERR_UNKNOWN_NET);
 
 735         /* Update statistic */
 
 736         SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
 
 738         if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
 
 741                 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
 
 742                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
 
 746         if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
 
 748                 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
 
 749                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
 
 753         if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
 
 755                 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
 
 756                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
 
 761          * Increment semaphores to indicate that an update was
 
 764         pAC->Pnmi.MacUpdatedFlag ++;
 
 765         pAC->Pnmi.RlmtUpdatedFlag ++;
 
 766         pAC->Pnmi.SirqUpdatedFlag ++;
 
 768         /* Get vpd keys for instance calculation */
 
 769         Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
 
 770         if (Ret != SK_PNMI_ERR_OK) {
 
 772                 pAC->Pnmi.MacUpdatedFlag --;
 
 773                 pAC->Pnmi.RlmtUpdatedFlag --;
 
 774                 pAC->Pnmi.SirqUpdatedFlag --;
 
 776                 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
 
 777                 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
 
 778                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
 
 779                 return (SK_PNMI_ERR_GENERAL);
 
 782         /* Retrieve values */
 
 783         SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
 
 784         for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
 
 786                 InstanceNo = IdTable[TableIndex].InstanceNo;
 
 787                 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
 
 790                         DstOffset = IdTable[TableIndex].Offset +
 
 792                                 IdTable[TableIndex].StructSize;
 
 795                          * For the VPD the instance is not an index number
 
 796                          * but the key itself. Determin with the instance
 
 797                          * counter the VPD key to be used.
 
 799                         if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
 
 800                                 IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
 
 801                                 IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
 
 802                                 IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
 
 804                                 SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
 
 807                                 Instance = (SK_U32)InstanceCnt;
 
 810                         TmpLen = *pLen - DstOffset;
 
 811                         Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
 
 812                                 IdTable[TableIndex].Id, (char *)pBuf +
 
 813                                 DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
 
 816                          * An unknown instance error means that we reached
 
 817                          * the last instance of that variable. Proceed with
 
 818                          * the next OID in the table and ignore the return
 
 821                         if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
 
 826                         if (Ret != SK_PNMI_ERR_OK) {
 
 828                                 pAC->Pnmi.MacUpdatedFlag --;
 
 829                                 pAC->Pnmi.RlmtUpdatedFlag --;
 
 830                                 pAC->Pnmi.SirqUpdatedFlag --;
 
 832                                 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
 
 833                                 SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
 
 834                                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
 
 840         pAC->Pnmi.MacUpdatedFlag --;
 
 841         pAC->Pnmi.RlmtUpdatedFlag --;
 
 842         pAC->Pnmi.SirqUpdatedFlag --;
 
 844         *pLen = SK_PNMI_STRUCT_SIZE;
 
 845         SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
 
 846         SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
 
 847         return (SK_PNMI_ERR_OK);
 
 850 /*****************************************************************************
 
 852  * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
 
 855  *      Calls a general sub-function for all this set stuff. The preset does
 
 856  *      the same as a set, but returns just before finally setting the
 
 857  *      new value. This is useful to check if a set might be successfull.
 
 858  *      The sub-function runs through the IdTable, checks which OIDs are able
 
 859  *      to set, and calls the handler function of the OID to perform the
 
 860  *      preset. The return value of the function will also be stored in
 
 861  *      SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
 
 862  *      SK_PNMI_MIN_STRUCT_SIZE.
 
 865  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
 866  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
 867  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
 868  *                               the correct data (e.g. a 32bit value is
 
 869  *                               needed, but a 16 bit value was passed).
 
 870  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 
 873 int SkPnmiPreSetStruct(
 
 874 SK_AC *pAC,             /* Pointer to adapter context */
 
 875 SK_IOC IoC,             /* IO context handle */
 
 876 void *pBuf,             /* Buffer which contains the data to be set */
 
 877 unsigned int *pLen,     /* Length of buffer */
 
 878 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
 880         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
 881                 ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
 
 884         return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf,
 
 888 /*****************************************************************************
 
 890  * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA
 
 893  *      Calls a general sub-function for all this set stuff. The return value
 
 894  *      of the function will also be stored in SK_PNMI_STRUCT_DATA if the
 
 895  *      passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE.
 
 896  *      The sub-function runs through the IdTable, checks which OIDs are able
 
 897  *      to set, and calls the handler function of the OID to perform the
 
 898  *      set. The return value of the function will also be stored in
 
 899  *      SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
 
 900  *      SK_PNMI_MIN_STRUCT_SIZE.
 
 903  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
 904  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
 905  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
 906  *                               the correct data (e.g. a 32bit value is
 
 907  *                               needed, but a 16 bit value was passed).
 
 908  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 
 912 SK_AC *pAC,             /* Pointer to adapter context */
 
 913 SK_IOC IoC,             /* IO context handle */
 
 914 void *pBuf,             /* Buffer which contains the data to be set */
 
 915 unsigned int *pLen,     /* Length of buffer */
 
 916 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
 918         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
 919                 ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
 
 922         return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf,
 
 926 /*****************************************************************************
 
 928  * SkPnmiEvent - Event handler
 
 931  *      Handles the following events:
 
 932  *      SK_PNMI_EVT_SIRQ_OVERFLOW     When a hardware counter overflows an
 
 933  *                                    interrupt will be generated which is
 
 934  *                                    first handled by SIRQ which generates a
 
 935  *                                    this event. The event increments the
 
 936  *                                    upper 32 bit of the 64 bit counter.
 
 937  *      SK_PNMI_EVT_SEN_XXX           The event is generated by the I2C module
 
 938  *                                    when a sensor reports a warning or
 
 939  *                                    error. The event will store a trap
 
 940  *                                    message in the trap buffer.
 
 941  *      SK_PNMI_EVT_CHG_EST_TIMER     The timer event was initiated by this
 
 942  *                                    module and is used to calculate the
 
 943  *                                    port switches per hour.
 
 944  *      SK_PNMI_EVT_CLEAR_COUNTER     The event clears all counters and
 
 946  *      SK_PNMI_EVT_XMAC_RESET        The event is generated by the driver
 
 947  *                                    before a hard reset of the XMAC is
 
 948  *                                    performed. All counters will be saved
 
 949  *                                    and added to the hardware counter
 
 950  *                                    values after reset to grant continuous
 
 952  *      SK_PNMI_EVT_RLMT_PORT_UP      Generated by RLMT to notify that a port
 
 953  *                                    went logically up. A trap message will
 
 954  *                                    be stored to the trap buffer.
 
 955  *      SK_PNMI_EVT_RLMT_PORT_DOWN    Generated by RLMT to notify that a port
 
 956  *                                    went logically down. A trap message will
 
 957  *                                    be stored to the trap buffer.
 
 958  *      SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
 
 959  *                                    spanning tree root bridges were
 
 960  *                                    detected. A trap message will be stored
 
 961  *                                    to the trap buffer.
 
 962  *      SK_PNMI_EVT_RLMT_ACTIVE_DOWN  Notifies PNMI that an active port went
 
 963  *                                    down. PNMI will not further add the
 
 964  *                                    statistic values to the virtual port.
 
 965  *      SK_PNMI_EVT_RLMT_ACTIVE_UP    Notifies PNMI that a port went up and
 
 966  *                                    is now an active port. PNMI will now
 
 967  *                                    add the statistic data of this port to
 
 969  *      SK_PNMI_EVT_RLMT_SET_NETS     Notifies PNMI about the net mode. The first parameter
 
 970  *                                    contains the number of nets. 1 means single net, 2 means
 
 971  *                                    dual net. The second parameter is -1
 
 977 SK_AC *pAC,             /* Pointer to adapter context */
 
 978 SK_IOC IoC,             /* IO context handle */
 
 979 SK_U32 Event,           /* Event-Id */
 
 980 SK_EVPARA Param)        /* Event dependent parameter */
 
 982         unsigned int    PhysPortIndex;
 
 983     unsigned int        MaxNetNumber;
 
 987         SK_U64          OverflowStatus;
 
 993         SK_EVPARA       EventParam;
 
 997         SK_PNMI_ESTIMATE *pEst;
 
1000         SK_PNMI_VCT     *pVctBackupData;
 
1007         if (Event != SK_PNMI_EVT_XMAC_RESET) {
 
1009                 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1010                         ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n",
 
1011                         (unsigned int)Event, (unsigned int)Param.Para64));
 
1014         SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call");
 
1016         MacType = pAC->GIni.GIMacType;
 
1020         case SK_PNMI_EVT_SIRQ_OVERFLOW:
 
1021                 PhysPortIndex = (int)Param.Para32[0];
 
1022                 MacStatus = (SK_U16)Param.Para32[1];
 
1024                 if (PhysPortIndex >= SK_MAX_MACS) {
 
1026                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1027                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter"
 
1028                                  " wrong, PhysPortIndex=0x%x\n",
 
1036                  * Check which source caused an overflow interrupt.
 
1038                 if ((pAC->GIni.GIFunc.pFnMacOverflow(pAC, IoC, PhysPortIndex,
 
1039                                 MacStatus, &OverflowStatus) != 0) ||
 
1040                         (OverflowStatus == 0)) {
 
1042                         SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
 
1047                  * Check the overflow status register and increment
 
1048                  * the upper dword of corresponding counter.
 
1050                 for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8;
 
1053                         Mask = (SK_U64)1 << CounterIndex;
 
1054                         if ((OverflowStatus & Mask) == 0) {
 
1059                         switch (StatOvrflwBit[CounterIndex][MacType]) {
 
1061                         case SK_PNMI_HTX_UTILUNDER:
 
1062                         case SK_PNMI_HTX_UTILOVER:
 
1063                                 if (MacType == SK_MAC_XMAC) {
 
1064                                         XM_IN16(IoC, PhysPortIndex, XM_TX_CMD, &Register);
 
1065                                         Register |= XM_TX_SAM_LINE;
 
1066                                         XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD, Register);
 
1070                         case SK_PNMI_HRX_UTILUNDER:
 
1071                         case SK_PNMI_HRX_UTILOVER:
 
1072                                 if (MacType == SK_MAC_XMAC) {
 
1073                                         XM_IN16(IoC, PhysPortIndex, XM_RX_CMD, &Register);
 
1074                                         Register |= XM_RX_SAM_LINE;
 
1075                                         XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD, Register);
 
1079                         case SK_PNMI_HTX_OCTETHIGH:
 
1080                         case SK_PNMI_HTX_OCTETLOW:
 
1081                         case SK_PNMI_HTX_RESERVED:
 
1082                         case SK_PNMI_HRX_OCTETHIGH:
 
1083                         case SK_PNMI_HRX_OCTETLOW:
 
1084                         case SK_PNMI_HRX_IRLENGTH:
 
1085                         case SK_PNMI_HRX_RESERVED:
 
1088                          * the following counters aren't be handled (id > 63)
 
1090                         case SK_PNMI_HTX_SYNC:
 
1091                         case SK_PNMI_HTX_SYNC_OCTET:
 
1094                         case SK_PNMI_HRX_LONGFRAMES:
 
1095                                 if (MacType == SK_MAC_GMAC) {
 
1096                                         pAC->Pnmi.Port[PhysPortIndex].
 
1097                                                 CounterHigh[CounterIndex] ++;
 
1102                                 pAC->Pnmi.Port[PhysPortIndex].
 
1103                                         CounterHigh[CounterIndex] ++;
 
1108         case SK_PNMI_EVT_SEN_WAR_LOW:
 
1110                 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
 
1112                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1113                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n",
 
1114                                 (unsigned int)Param.Para64));
 
1120                  * Store a trap message in the trap buffer and generate
 
1121                  * an event for user space applications with the
 
1122                  * SK_DRIVER_SENDEVENT macro.
 
1124                 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW,
 
1125                         (unsigned int)Param.Para64);
 
1126                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
 
1129         case SK_PNMI_EVT_SEN_WAR_UPP:
 
1131                 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
 
1133                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1134                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n",
 
1135                                 (unsigned int)Param.Para64));
 
1141                  * Store a trap message in the trap buffer and generate
 
1142                  * an event for user space applications with the
 
1143                  * SK_DRIVER_SENDEVENT macro.
 
1145                 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP,
 
1146                         (unsigned int)Param.Para64);
 
1147                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
 
1150         case SK_PNMI_EVT_SEN_ERR_LOW:
 
1152                 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
 
1154                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1155                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n",
 
1156                                 (unsigned int)Param.Para64));
 
1162                  * Store a trap message in the trap buffer and generate
 
1163                  * an event for user space applications with the
 
1164                  * SK_DRIVER_SENDEVENT macro.
 
1166                 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW,
 
1167                         (unsigned int)Param.Para64);
 
1168                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
 
1171         case SK_PNMI_EVT_SEN_ERR_UPP:
 
1173                 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
 
1175                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1176                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
 
1177                                 (unsigned int)Param.Para64));
 
1183                  * Store a trap message in the trap buffer and generate
 
1184                  * an event for user space applications with the
 
1185                  * SK_DRIVER_SENDEVENT macro.
 
1187                 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP,
 
1188                         (unsigned int)Param.Para64);
 
1189                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
 
1192         case SK_PNMI_EVT_CHG_EST_TIMER:
 
1194                  * Calculate port switch average on a per hour basis
 
1195                  *   Time interval for check       : 28125 ms
 
1196                  *   Number of values for average  : 8
 
1198                  * Be careful in changing these values, on change check
 
1199                  *   - typedef of SK_PNMI_ESTIMATE (Size of EstValue
 
1200                  *     array one less than value number)
 
1201                  *   - Timer initialization SkTimerStart() in SkPnmiInit
 
1202                  *   - Delta value below must be multiplicated with
 
1206                 pEst = &pAC->Pnmi.RlmtChangeEstimate;
 
1207                 CounterIndex = pEst->EstValueIndex + 1;
 
1208                 if (CounterIndex == 7) {
 
1212                 pEst->EstValueIndex = CounterIndex;
 
1214                 NewestValue = pAC->Pnmi.RlmtChangeCts;
 
1215                 OldestValue = pEst->EstValue[CounterIndex];
 
1216                 pEst->EstValue[CounterIndex] = NewestValue;
 
1219                  * Calculate average. Delta stores the number of
 
1220                  * port switches per 28125 * 8 = 225000 ms
 
1222                 if (NewestValue >= OldestValue) {
 
1224                         Delta = NewestValue - OldestValue;
 
1227                         /* Overflow situation */
 
1228                         Delta = (SK_U64)(0 - OldestValue) + NewestValue;
 
1232                  * Extrapolate delta to port switches per hour.
 
1233                  *     Estimate = Delta * (3600000 / 225000)
 
1237                 pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4;
 
1240                  * Check if threshold is exceeded. If the threshold is
 
1241                  * permanently exceeded every 28125 ms an event will be
 
1242                  * generated to remind the user of this condition.
 
1244                 if ((pAC->Pnmi.RlmtChangeThreshold != 0) &&
 
1245                         (pAC->Pnmi.RlmtChangeEstimate.Estimate >=
 
1246                         pAC->Pnmi.RlmtChangeThreshold)) {
 
1248                         QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES);
 
1249                         (void)SK_DRIVER_SENDEVENT(pAC, IoC);
 
1252                 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
 
1253                 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
 
1254                         28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
 
1258         case SK_PNMI_EVT_CLEAR_COUNTER:
 
1260                  *  Param.Para32[0] contains the NetIndex (0 ..1).
 
1261                  *  Param.Para32[1] is reserved, contains -1.
 
1263                 NetIndex = (SK_U32)Param.Para32[0];
 
1266                 if (NetIndex >= pAC->Rlmt.NumNets) {
 
1268                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1269                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
 
1277                  * Set all counters and timestamps to zero.
 
1278                  * The according NetIndex is required as a
 
1279                  * parameter of the event.
 
1281                 ResetCounter(pAC, IoC, NetIndex);
 
1284         case SK_PNMI_EVT_XMAC_RESET:
 
1286                  * To grant continuous counter values store the current
 
1287                  * XMAC statistic values to the entries 1..n of the
 
1288                  * CounterOffset array. XMAC Errata #2
 
1291                 if ((unsigned int)Param.Para64 >= SK_MAX_MACS) {
 
1293                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1294                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n",
 
1295                                 (unsigned int)Param.Para64));
 
1299                 PhysPortIndex = (unsigned int)Param.Para64;
 
1302                  * Update XMAC statistic to get fresh values
 
1304                 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
 
1305                 if (Ret != SK_PNMI_ERR_OK) {
 
1307                         SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
 
1311                  * Increment semaphore to indicate that an update was
 
1314                 pAC->Pnmi.MacUpdatedFlag ++;
 
1316                 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
 
1319                         if (!StatAddr[CounterIndex][MacType].GetOffset) {
 
1324                         pAC->Pnmi.Port[PhysPortIndex].CounterOffset[CounterIndex] =
 
1325                                 GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
 
1327                         pAC->Pnmi.Port[PhysPortIndex].CounterHigh[CounterIndex] = 0;
 
1330                 pAC->Pnmi.MacUpdatedFlag --;
 
1333         case SK_PNMI_EVT_RLMT_PORT_UP:
 
1334                 PhysPortIndex = (unsigned int)Param.Para32[0];
 
1336                 if (PhysPortIndex >= SK_MAX_MACS) {
 
1338                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1339                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter"
 
1340                  " wrong, PhysPortIndex=%d\n", PhysPortIndex));
 
1347                  * Store a trap message in the trap buffer and generate an event for
 
1348                  * user space applications with the SK_DRIVER_SENDEVENT macro.
 
1350                 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
 
1351                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
 
1353                 /* Bugfix for XMAC errata (#10620)*/
 
1354                 if (MacType == SK_MAC_XMAC) {
 
1355                         /* Add incremental difference to offset (#10620)*/
 
1356                         (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
1357                                 XM_RXE_SHT_ERR, &Val32);
 
1359                         Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
 
1360                                  CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
 
1361                         pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
 
1362                                 Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
 
1365                 /* Tell VctStatus() that a link was up meanwhile. */
 
1366                 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK;         
 
1369     case SK_PNMI_EVT_RLMT_PORT_DOWN:
 
1370                 PhysPortIndex = (unsigned int)Param.Para32[0];
 
1373                 if (PhysPortIndex >= SK_MAX_MACS) {
 
1375                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1376                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter"
 
1377                  " wrong, PhysPortIndex=%d\n", PhysPortIndex));
 
1384                  * Store a trap message in the trap buffer and generate an event for
 
1385                  * user space applications with the SK_DRIVER_SENDEVENT macro.
 
1387                 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
 
1388                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
 
1390                 /* Bugfix #10620 - get zero level for incremental difference */
 
1391                 if (MacType == SK_MAC_XMAC) {
 
1393                         (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
1394                                 XM_RXE_SHT_ERR, &Val32);
 
1396                         pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark =
 
1397                                 (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
 
1398                                  CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
 
1402         case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
 
1403                 PhysPortIndex = (unsigned int)Param.Para32[0];
 
1404                 NetIndex = (SK_U32)Param.Para32[1];
 
1407                 if (PhysPortIndex >= SK_MAX_MACS) {
 
1409                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1410                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
 
1414                 if (NetIndex >= pAC->Rlmt.NumNets) {
 
1416                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1417                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
 
1423                  * For now, ignore event if NetIndex != 0.
 
1425                 if (Param.Para32[1] != 0) {
 
1431                  * Nothing to do if port is already inactive
 
1433                 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
 
1439                  * Update statistic counters to calculate new offset for the virtual
 
1440                  * port and increment semaphore to indicate that an update was already
 
1443                 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
 
1446                         SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
 
1449                 pAC->Pnmi.MacUpdatedFlag ++;
 
1452                  * Calculate new counter offset for virtual port to grant continous
 
1453                  * counting on port switches. The virtual port consists of all currently
 
1454                  * active ports. The port down event indicates that a port is removed
 
1455                  * from the virtual port. Therefore add the counter value of the removed
 
1456                  * port to the CounterOffset for the virtual port to grant the same
 
1459                 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
 
1462                         if (!StatAddr[CounterIndex][MacType].GetOffset) {
 
1467                         Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
 
1469                         pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
 
1473                  * Set port to inactive
 
1475                 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
 
1477                 pAC->Pnmi.MacUpdatedFlag --;
 
1480         case SK_PNMI_EVT_RLMT_ACTIVE_UP:
 
1481                 PhysPortIndex = (unsigned int)Param.Para32[0];
 
1482                 NetIndex = (SK_U32)Param.Para32[1];
 
1485                 if (PhysPortIndex >= SK_MAX_MACS) {
 
1487                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1488                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
 
1492                 if (NetIndex >= pAC->Rlmt.NumNets) {
 
1494                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 
1495                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
 
1501                  * For now, ignore event if NetIndex != 0.
 
1503                 if (Param.Para32[1] != 0) {
 
1509                  * Nothing to do if port is already active
 
1511                 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
 
1517                  * Statistic maintenance
 
1519                 pAC->Pnmi.RlmtChangeCts ++;
 
1520                 pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
 
1523                  * Store a trap message in the trap buffer and generate an event for
 
1524                  * user space applications with the SK_DRIVER_SENDEVENT macro.
 
1526                 QueueRlmtNewMacTrap(pAC, PhysPortIndex);
 
1527                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
 
1530                  * Update statistic counters to calculate new offset for the virtual
 
1531                  * port and increment semaphore to indicate that an update was
 
1534                 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
 
1537                         SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
 
1540                 pAC->Pnmi.MacUpdatedFlag ++;
 
1543                  * Calculate new counter offset for virtual port to grant continous
 
1544                  * counting on port switches. A new port is added to the virtual port.
 
1545                  * Therefore substract the counter value of the new port from the
 
1546                  * CounterOffset for the virtual port to grant the same value.
 
1548                 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
 
1551                         if (!StatAddr[CounterIndex][MacType].GetOffset) {
 
1556                         Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
 
1558                         pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
 
1561                 /* Set port to active */
 
1562                 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
 
1564                 pAC->Pnmi.MacUpdatedFlag --;
 
1567         case SK_PNMI_EVT_RLMT_SEGMENTATION:
 
1569                  * Para.Para32[0] contains the NetIndex.
 
1573                  * Store a trap message in the trap buffer and generate an event for
 
1574                  * user space applications with the SK_DRIVER_SENDEVENT macro.
 
1576                 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
 
1577                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
 
1580     case SK_PNMI_EVT_RLMT_SET_NETS:
 
1582                  *  Param.Para32[0] contains the number of Nets.
 
1583                  *  Param.Para32[1] is reserved, contains -1.
 
1586          * Check number of nets
 
1588                 MaxNetNumber = pAC->GIni.GIMacsFound;
 
1589                 if (((unsigned int)Param.Para32[0] < 1)
 
1590                         || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
 
1591                         return (SK_PNMI_ERR_UNKNOWN_NET);
 
1594         if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
 
1595                 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
 
1597         else { /* dual net mode */
 
1598                 pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
 
1602     case SK_PNMI_EVT_VCT_RESET:
 
1603                 PhysPortIndex = Param.Para32[0];
 
1604                 pPrt = &pAC->GIni.GP[PhysPortIndex];
 
1605                 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
 
1607                 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
 
1608                         RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
 
1611                                  * VCT test is still running.
 
1612                                  * Start VCT timer counter again.
 
1614                                 SK_MEMSET((char *) &Param, 0, sizeof(Param));
 
1615                                 Param.Para32[0] = PhysPortIndex;
 
1616                                 Param.Para32[1] = -1;
 
1617                                 SkTimerStart(pAC, IoC,
 
1618                                         &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
 
1619                                 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
 
1622                         pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
 
1623                         pAC->Pnmi.VctStatus[PhysPortIndex] |=
 
1624                                 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
 
1626                         /* Copy results for later use to PNMI struct. */
 
1627                         for (i = 0; i < 4; i++)  {
 
1628                                 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
 
1629                                         if ((pPrt->PMdiPairLen[i] > 35) &&
 
1630                                                 (pPrt->PMdiPairLen[i] < 0xff)) {
 
1631                                                 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
 
1634                                 if ((pPrt->PMdiPairLen[i] > 35) &&
 
1635                                         (pPrt->PMdiPairLen[i] != 0xff)) {
 
1636                                         CableLength = 1000 *
 
1637                                                 (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
 
1642                                 pVctBackupData->PMdiPairLen[i] = CableLength;
 
1643                                 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
 
1646                         Param.Para32[0] = PhysPortIndex;
 
1647                         Param.Para32[1] = -1;
 
1648                         SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
 
1649                         SkEventDispatcher(pAC, IoC);
 
1658         SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
 
1663 /******************************************************************************
 
1669 /*****************************************************************************
 
1671  * PnmiVar - Gets, presets, and sets single OIDs
 
1674  *      Looks up the requested OID, calls the corresponding handler
 
1675  *      function, and passes the parameters with the get, preset, or
 
1676  *      set command. The function is called by SkGePnmiGetVar,
 
1677  *      SkGePnmiPreSetVar, or SkGePnmiSetVar.
 
1680  *      SK_PNMI_ERR_XXX. For details have a look at the description of the
 
1681  *      calling functions.
 
1682  *      SK_PNMI_ERR_UNKNOWN_NET  The requested NetIndex doesn't exist
 
1684 PNMI_STATIC int PnmiVar(
 
1685 SK_AC *pAC,             /* Pointer to adapter context */
 
1686 SK_IOC IoC,             /* IO context handle */
 
1687 int Action,             /* GET/PRESET/SET action */
 
1688 SK_U32 Id,              /* Object ID that is to be processed */
 
1689 char *pBuf,             /* Buffer used for the management data transfer */
 
1690 unsigned int *pLen,     /* Total length of pBuf management data  */
 
1691 SK_U32 Instance,        /* Instance (1..n) that is to be set or -1 */
 
1692 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
1694         unsigned int    TableIndex;
 
1698         if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
 
1701                 return (SK_PNMI_ERR_UNKNOWN_OID);
 
1704     /* Check NetIndex */
 
1705         if (NetIndex >= pAC->Rlmt.NumNets) {
 
1706                 return (SK_PNMI_ERR_UNKNOWN_NET);
 
1709         SK_PNMI_CHECKFLAGS("PnmiVar: On call");
 
1711         Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
 
1712                 Instance, TableIndex, NetIndex);
 
1714         SK_PNMI_CHECKFLAGS("PnmiVar: On return");
 
1719 /*****************************************************************************
 
1721  * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA
 
1724  *      The return value of the function will also be stored in
 
1725  *      SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
 
1726  *      SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable,
 
1727  *      checks which OIDs are able to set, and calls the handler function of
 
1728  *      the OID to perform the set. The return value of the function will
 
1729  *      also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
 
1730  *      minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called
 
1731  *      by SkGePnmiPreSetStruct and SkGePnmiSetStruct.
 
1734  *      SK_PNMI_ERR_XXX. The codes are described in the calling functions.
 
1735  *      SK_PNMI_ERR_UNKNOWN_NET  The requested NetIndex doesn't exist
 
1737 PNMI_STATIC int PnmiStruct(
 
1738 SK_AC *pAC,             /* Pointer to adapter context */
 
1739 SK_IOC IoC,             /* IO context handle */
 
1740 int  Action,    /* PRESET/SET action to be performed */
 
1741 char *pBuf,             /* Buffer used for the management data transfer */
 
1742 unsigned int *pLen,     /* Length of pBuf management data buffer */
 
1743 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
1746         unsigned int    TableIndex;
 
1747         unsigned int    DstOffset;
 
1749         unsigned int    InstanceNo;
 
1750         unsigned int    InstanceCnt;
 
1755         /* Check if the passed buffer has the right size */
 
1756         if (*pLen < SK_PNMI_STRUCT_SIZE) {
 
1758                 /* Check if we can return the error within the buffer */
 
1759                 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
 
1761                         SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
 
1765                 *pLen = SK_PNMI_STRUCT_SIZE;
 
1766                 return (SK_PNMI_ERR_TOO_SHORT);
 
1769     /* Check NetIndex */
 
1770         if (NetIndex >= pAC->Rlmt.NumNets) {
 
1771                 return (SK_PNMI_ERR_UNKNOWN_NET);
 
1774         SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
 
1777          * Update the values of RLMT and SIRQ and increment semaphores to
 
1778          * indicate that an update was already done.
 
1780         if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
 
1782                 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
 
1783                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
 
1787         if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
 
1789                 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
 
1790                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
 
1794         pAC->Pnmi.RlmtUpdatedFlag ++;
 
1795         pAC->Pnmi.SirqUpdatedFlag ++;
 
1797         /* Preset/Set values */
 
1798         for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
 
1800                 if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
 
1801                         (IdTable[TableIndex].Access != SK_PNMI_WO)) {
 
1806                 InstanceNo = IdTable[TableIndex].InstanceNo;
 
1807                 Id = IdTable[TableIndex].Id;
 
1809                 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
 
1812                         DstOffset = IdTable[TableIndex].Offset +
 
1814                                 IdTable[TableIndex].StructSize;
 
1817                          * Because VPD multiple instance variables are
 
1818                          * not setable we do not need to evaluate VPD
 
1819                          * instances. Have a look to VPD instance
 
1820                          * calculation in SkPnmiGetStruct().
 
1822                         Instance = (SK_U32)InstanceCnt;
 
1825                          * Evaluate needed buffer length
 
1828                         Ret = IdTable[TableIndex].Func(pAC, IoC,
 
1829                                 SK_PNMI_GET, IdTable[TableIndex].Id,
 
1830                                 NULL, &Len, Instance, TableIndex, NetIndex);
 
1832                         if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
 
1836                         if (Ret != SK_PNMI_ERR_TOO_SHORT) {
 
1838                                 pAC->Pnmi.RlmtUpdatedFlag --;
 
1839                                 pAC->Pnmi.SirqUpdatedFlag --;
 
1841                                 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
 
1842                                 SK_PNMI_SET_STAT(pBuf,
 
1843                                         SK_PNMI_ERR_GENERAL, DstOffset);
 
1844                                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
 
1845                                 return (SK_PNMI_ERR_GENERAL);
 
1847                         if (Id == OID_SKGE_VPD_ACTION) {
 
1849                                 switch (*(pBuf + DstOffset)) {
 
1851                                 case SK_PNMI_VPD_CREATE:
 
1852                                         Len = 3 + *(pBuf + DstOffset + 3);
 
1855                                 case SK_PNMI_VPD_DELETE:
 
1865                         /* Call the OID handler function */
 
1866                         Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
 
1867                                 IdTable[TableIndex].Id, pBuf + DstOffset,
 
1868                                 &Len, Instance, TableIndex, NetIndex);
 
1870                         if (Ret != SK_PNMI_ERR_OK) {
 
1872                                 pAC->Pnmi.RlmtUpdatedFlag --;
 
1873                                 pAC->Pnmi.SirqUpdatedFlag --;
 
1875                                 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
 
1876                                 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
 
1878                                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
 
1879                                 return (SK_PNMI_ERR_BAD_VALUE);
 
1884         pAC->Pnmi.RlmtUpdatedFlag --;
 
1885         pAC->Pnmi.SirqUpdatedFlag --;
 
1887         SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
 
1888         SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
 
1889         return (SK_PNMI_ERR_OK);
 
1892 /*****************************************************************************
 
1894  * LookupId - Lookup an OID in the IdTable
 
1897  *      Scans the IdTable to find the table entry of an OID.
 
1900  *      The table index or -1 if not found.
 
1902 PNMI_STATIC int LookupId(
 
1903 SK_U32 Id)              /* Object identifier to be searched */
 
1907         for (i = 0; i < ID_TABLE_SIZE; i++) {
 
1909                 if (IdTable[i].Id == Id) {
 
1918 /*****************************************************************************
 
1920  * OidStruct - Handler of OID_SKGE_ALL_DATA
 
1923  *      This OID performs a Get/Preset/SetStruct call and returns all data
 
1924  *      in a SK_PNMI_STRUCT_DATA structure.
 
1927  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
1928  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
1929  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
1930  *                               the correct data (e.g. a 32bit value is
 
1931  *                               needed, but a 16 bit value was passed).
 
1932  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 
1934  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 
1935  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
1936  *                           exist (e.g. port instance 3 on a two port
 
1939 PNMI_STATIC int OidStruct(
 
1940 SK_AC *pAC,             /* Pointer to adapter context */
 
1941 SK_IOC IoC,             /* IO context handle */
 
1942 int Action,             /* GET/PRESET/SET action */
 
1943 SK_U32 Id,              /* Object ID that is to be processed */
 
1944 char *pBuf,             /* Buffer used for the management data transfer */
 
1945 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
1946 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
1947 unsigned int TableIndex, /* Index to the Id table */
 
1948 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
1950         if (Id != OID_SKGE_ALL_DATA) {
 
1952                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
 
1956                 return (SK_PNMI_ERR_GENERAL);
 
1960          * Check instance. We only handle single instance variables
 
1962         if (Instance != (SK_U32)(-1) && Instance != 1) {
 
1965                 return (SK_PNMI_ERR_UNKNOWN_INST);
 
1971                 return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
 
1973         case SK_PNMI_PRESET:
 
1974                 return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
 
1977                 return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
 
1980         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
 
1983         return (SK_PNMI_ERR_GENERAL);
 
1986 /*****************************************************************************
 
1988  * Perform - OID handler of OID_SKGE_ACTION
 
1994  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
1995  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
1996  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
1997  *                               the correct data (e.g. a 32bit value is
 
1998  *                               needed, but a 16 bit value was passed).
 
1999  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 
2001  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 
2002  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
2003  *                           exist (e.g. port instance 3 on a two port
 
2006 PNMI_STATIC int Perform(
 
2007 SK_AC *pAC,             /* Pointer to adapter context */
 
2008 SK_IOC IoC,             /* IO context handle */
 
2009 int Action,             /* GET/PRESET/SET action */
 
2010 SK_U32 Id,              /* Object ID that is to be processed */
 
2011 char *pBuf,             /* Buffer used for the management data transfer */
 
2012 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
2013 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
2014 unsigned int TableIndex, /* Index to the Id table */
 
2015 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
2022          * Check instance. We only handle single instance variables
 
2024         if (Instance != (SK_U32)(-1) && Instance != 1) {
 
2027                 return (SK_PNMI_ERR_UNKNOWN_INST);
 
2030         if (*pLen < sizeof(SK_U32)) {
 
2032                 *pLen = sizeof(SK_U32);
 
2033                 return (SK_PNMI_ERR_TOO_SHORT);
 
2036         /* Check if a get should be performed */
 
2037         if (Action == SK_PNMI_GET) {
 
2039                 /* A get is easy. We always return the same value */
 
2040                 ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
 
2041                 SK_PNMI_STORE_U32(pBuf, ActionOp);
 
2042                 *pLen = sizeof(SK_U32);
 
2044                 return (SK_PNMI_ERR_OK);
 
2047         /* Continue with PRESET/SET action */
 
2048         if (*pLen > sizeof(SK_U32)) {
 
2050                 return (SK_PNMI_ERR_BAD_VALUE);
 
2053         /* Check if the command is a known one */
 
2054         SK_PNMI_READ_U32(pBuf, ActionOp);
 
2055         if (*pLen > sizeof(SK_U32) ||
 
2056                 (ActionOp != SK_PNMI_ACT_IDLE &&
 
2057                 ActionOp != SK_PNMI_ACT_RESET &&
 
2058                 ActionOp != SK_PNMI_ACT_SELFTEST &&
 
2059                 ActionOp != SK_PNMI_ACT_RESETCNT)) {
 
2062                 return (SK_PNMI_ERR_BAD_VALUE);
 
2065         /* A preset ends here */
 
2066         if (Action == SK_PNMI_PRESET) {
 
2068                 return (SK_PNMI_ERR_OK);
 
2073         case SK_PNMI_ACT_IDLE:
 
2077         case SK_PNMI_ACT_RESET:
 
2079                  * Perform a driver reset or something that comes near
 
2082                 Ret = SK_DRIVER_RESET(pAC, IoC);
 
2085                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
 
2088                         return (SK_PNMI_ERR_GENERAL);
 
2092         case SK_PNMI_ACT_SELFTEST:
 
2094                  * Perform a driver selftest or something similar to this.
 
2095                  * Currently this feature is not used and will probably
 
2096                  * implemented in another way.
 
2098                 Ret = SK_DRIVER_SELFTEST(pAC, IoC);
 
2099                 pAC->Pnmi.TestResult = Ret;
 
2102         case SK_PNMI_ACT_RESETCNT:
 
2103                 /* Set all counters and timestamps to zero */
 
2104                 ResetCounter(pAC, IoC, NetIndex);
 
2108                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
 
2111                 return (SK_PNMI_ERR_GENERAL);
 
2114         return (SK_PNMI_ERR_OK);
 
2117 /*****************************************************************************
 
2119  * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX
 
2122  *      Retrieves the statistic values of the virtual port (logical
 
2123  *      index 0). Only special OIDs of NDIS are handled which consist
 
2124  *      of a 32 bit instead of a 64 bit value. The OIDs are public
 
2125  *      because perhaps some other platform can use them too.
 
2128  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
2129  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
2130  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
2131  *                               the correct data (e.g. a 32bit value is
 
2132  *                               needed, but a 16 bit value was passed).
 
2133  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
2134  *                           exist (e.g. port instance 3 on a two port
 
2137 PNMI_STATIC int Mac8023Stat(
 
2138 SK_AC *pAC,             /* Pointer to adapter context */
 
2139 SK_IOC IoC,             /* IO context handle */
 
2140 int Action,             /* GET/PRESET/SET action */
 
2141 SK_U32 Id,              /* Object ID that is to be processed */
 
2142 char *pBuf,             /* Buffer used for the management data transfer */
 
2143 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
2144 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
2145 unsigned int TableIndex,        /* Index to the Id table */
 
2146 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
2151         SK_BOOL Is64BitReq = SK_FALSE;
 
2154          * Only the active Mac is returned
 
2156         if (Instance != (SK_U32)(-1) && Instance != 1) {
 
2159                 return (SK_PNMI_ERR_UNKNOWN_INST);
 
2165         if (Action != SK_PNMI_GET) {
 
2168                 return (SK_PNMI_ERR_READ_ONLY);
 
2174         case OID_802_3_PERMANENT_ADDRESS:
 
2175         case OID_802_3_CURRENT_ADDRESS:
 
2176                 if (*pLen < sizeof(SK_MAC_ADDR)) {
 
2178                         *pLen = sizeof(SK_MAC_ADDR);
 
2179                         return (SK_PNMI_ERR_TOO_SHORT);
 
2184 #ifndef SK_NDIS_64BIT_CTR
 
2185                 if (*pLen < sizeof(SK_U32)) {
 
2186                         *pLen = sizeof(SK_U32);
 
2187                         return (SK_PNMI_ERR_TOO_SHORT);
 
2190 #else /* SK_NDIS_64BIT_CTR */
 
2192                 /* for compatibility, at least 32bit are required for OID */
 
2193                 if (*pLen < sizeof(SK_U32)) {
 
2195                         * but indicate handling for 64bit values,
 
2196                         * if insufficient space is provided
 
2198                         *pLen = sizeof(SK_U64);
 
2199                         return (SK_PNMI_ERR_TOO_SHORT);
 
2202                 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
 
2203 #endif /* SK_NDIS_64BIT_CTR */
 
2208          * Update all statistics, because we retrieve virtual MAC, which
 
2209          * consists of multiple physical statistics and increment semaphore
 
2210          * to indicate that an update was already done.
 
2212         Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
 
2213         if ( Ret != SK_PNMI_ERR_OK) {
 
2218         pAC->Pnmi.MacUpdatedFlag ++;
 
2221          * Get value (MAC Index 0 identifies the virtual MAC)
 
2225         case OID_802_3_PERMANENT_ADDRESS:
 
2226                 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
 
2227                 *pLen = sizeof(SK_MAC_ADDR);
 
2230         case OID_802_3_CURRENT_ADDRESS:
 
2231                 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
 
2232                 *pLen = sizeof(SK_MAC_ADDR);
 
2236                 StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
 
2238                 /* by default 32bit values are evaluated */
 
2240                         StatVal32 = (SK_U32)StatVal;
 
2241                         SK_PNMI_STORE_U32(pBuf, StatVal32);
 
2242                         *pLen = sizeof(SK_U32);
 
2245                         SK_PNMI_STORE_U64(pBuf, StatVal);
 
2246                         *pLen = sizeof(SK_U64);
 
2251         pAC->Pnmi.MacUpdatedFlag --;
 
2253         return (SK_PNMI_ERR_OK);
 
2256 /*****************************************************************************
 
2258  * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX
 
2261  *      Retrieves the MAC statistic data.
 
2264  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
2265  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
2266  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
2267  *                               the correct data (e.g. a 32bit value is
 
2268  *                               needed, but a 16 bit value was passed).
 
2269  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
2270  *                           exist (e.g. port instance 3 on a two port
 
2273 PNMI_STATIC int MacPrivateStat(
 
2274 SK_AC *pAC,             /* Pointer to adapter context */
 
2275 SK_IOC IoC,             /* IO context handle */
 
2276 int Action,             /* GET/PRESET/SET action */
 
2277 SK_U32 Id,              /* Object ID that is to be processed */
 
2278 char *pBuf,             /* Buffer used for the management data transfer */
 
2279 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
2280 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
2281 unsigned int TableIndex, /* Index to the Id table */
 
2282 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
2284         unsigned int    LogPortMax;
 
2285         unsigned int    LogPortIndex;
 
2286         unsigned int    PhysPortMax;
 
2288         unsigned int    Offset;
 
2295         /* Calculate instance if wished. MAC index 0 is the virtual MAC */
 
2296         PhysPortMax = pAC->GIni.GIMacsFound;
 
2297         LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
 
2299         MacType = pAC->GIni.GIMacType;
 
2301         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
 
2305         if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
 
2306                 /* Check instance range */
 
2307                 if ((Instance < 1) || (Instance > LogPortMax)) {
 
2310                         return (SK_PNMI_ERR_UNKNOWN_INST);
 
2312                 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
 
2313                 Limit = LogPortIndex + 1;
 
2316         else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
 
2323         if (Action != SK_PNMI_GET) {
 
2326                 return (SK_PNMI_ERR_READ_ONLY);
 
2330         if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
 
2332                 *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
 
2333                 return (SK_PNMI_ERR_TOO_SHORT);
 
2337          * Update MAC statistic and increment semaphore to indicate that
 
2338          * an update was already done.
 
2340         Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
 
2341         if (Ret != SK_PNMI_ERR_OK) {
 
2346         pAC->Pnmi.MacUpdatedFlag ++;
 
2350         for (; LogPortIndex < Limit; LogPortIndex ++) {
 
2354 /* XXX not yet implemented due to XMAC problems
 
2355                 case OID_SKGE_STAT_TX_UTIL:
 
2356                         return (SK_PNMI_ERR_GENERAL);
 
2358 /* XXX not yet implemented due to XMAC problems
 
2359                 case OID_SKGE_STAT_RX_UTIL:
 
2360                         return (SK_PNMI_ERR_GENERAL);
 
2362                 case OID_SKGE_STAT_RX:
 
2363                         if (MacType == SK_MAC_GMAC) {
 
2365                                         GetStatVal(pAC, IoC, LogPortIndex,
 
2366                                                            SK_PNMI_HRX_BROADCAST, NetIndex) +
 
2367                                         GetStatVal(pAC, IoC, LogPortIndex,
 
2368                                                            SK_PNMI_HRX_MULTICAST, NetIndex) +
 
2369                                         GetStatVal(pAC, IoC, LogPortIndex,
 
2370                                                            SK_PNMI_HRX_UNICAST, NetIndex) +
 
2371                                         GetStatVal(pAC, IoC, LogPortIndex,
 
2372                                                            SK_PNMI_HRX_UNDERSIZE, NetIndex);
 
2375                                 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
 
2376                                         IdTable[TableIndex].Param, NetIndex);
 
2380                 case OID_SKGE_STAT_TX:
 
2381                         if (MacType == SK_MAC_GMAC) {
 
2383                                         GetStatVal(pAC, IoC, LogPortIndex,
 
2384                                                            SK_PNMI_HTX_BROADCAST, NetIndex) +
 
2385                                         GetStatVal(pAC, IoC, LogPortIndex,
 
2386                                                            SK_PNMI_HTX_MULTICAST, NetIndex) +
 
2387                                         GetStatVal(pAC, IoC, LogPortIndex,
 
2388                                                            SK_PNMI_HTX_UNICAST, NetIndex);
 
2391                                 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
 
2392                                         IdTable[TableIndex].Param, NetIndex);
 
2397                         StatVal = GetStatVal(pAC, IoC, LogPortIndex,
 
2398                                 IdTable[TableIndex].Param, NetIndex);
 
2400                 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
 
2402                 Offset += sizeof(SK_U64);
 
2406         pAC->Pnmi.MacUpdatedFlag --;
 
2408         return (SK_PNMI_ERR_OK);
 
2411 /*****************************************************************************
 
2413  * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR
 
2416  *      Get/Presets/Sets the current and factory MAC address. The MAC
 
2417  *      address of the virtual port, which is reported to the OS, may
 
2418  *      not be changed, but the physical ones. A set to the virtual port
 
2419  *      will be ignored. No error should be reported because otherwise
 
2420  *      a multiple instance set (-1) would always fail.
 
2423  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
2424  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
2425  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
2426  *                               the correct data (e.g. a 32bit value is
 
2427  *                               needed, but a 16 bit value was passed).
 
2428  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 
2430  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 
2431  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
2432  *                           exist (e.g. port instance 3 on a two port
 
2435 PNMI_STATIC int Addr(
 
2436 SK_AC *pAC,             /* Pointer to adapter context */
 
2437 SK_IOC IoC,             /* IO context handle */
 
2438 int Action,             /* GET/PRESET/SET action */
 
2439 SK_U32 Id,              /* Object ID that is to be processed */
 
2440 char *pBuf,             /* Buffer used for the management data transfer */
 
2441 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
2442 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
2443 unsigned int TableIndex, /* Index to the Id table */
 
2444 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
2447         unsigned int    LogPortMax;
 
2448         unsigned int    PhysPortMax;
 
2449         unsigned int    LogPortIndex;
 
2450         unsigned int    PhysPortIndex;
 
2452         unsigned int    Offset = 0;
 
2455          * Calculate instance if wished. MAC index 0 is the virtual
 
2458         PhysPortMax = pAC->GIni.GIMacsFound;
 
2459         LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
 
2461         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
 
2465         if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
 
2466                 /* Check instance range */
 
2467                 if ((Instance < 1) || (Instance > LogPortMax)) {
 
2470                         return (SK_PNMI_ERR_UNKNOWN_INST);
 
2472                 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
 
2473                 Limit = LogPortIndex + 1;
 
2475         else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
 
2484         if (Action == SK_PNMI_GET) {
 
2487                 if (*pLen < (Limit - LogPortIndex) * 6) {
 
2489                         *pLen = (Limit - LogPortIndex) * 6;
 
2490                         return (SK_PNMI_ERR_TOO_SHORT);
 
2496                 for (; LogPortIndex < Limit; LogPortIndex ++) {
 
2500                         case OID_SKGE_PHYS_CUR_ADDR:
 
2501                                 if (LogPortIndex == 0) {
 
2502                                         CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
 
2505                                         PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
 
2507                                         CopyMac(pBuf + Offset,
 
2508                                                 &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
 
2513                         case OID_SKGE_PHYS_FAC_ADDR:
 
2514                                 if (LogPortIndex == 0) {
 
2515                                         CopyMac(pBuf + Offset,
 
2516                                                 &pAC->Addr.Net[NetIndex].PermanentMacAddress);
 
2519                                         PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
2522                                         CopyMac(pBuf + Offset,
 
2523                                                 &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
 
2529                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
 
2533                                 return (SK_PNMI_ERR_GENERAL);
 
2541                  * The logical MAC address may not be changed only
 
2544                 if (Id == OID_SKGE_PHYS_FAC_ADDR) {
 
2547                         return (SK_PNMI_ERR_READ_ONLY);
 
2551                  * Only the current address may be changed
 
2553                 if (Id != OID_SKGE_PHYS_CUR_ADDR) {
 
2555                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
 
2559                         return (SK_PNMI_ERR_GENERAL);
 
2563                 if (*pLen < (Limit - LogPortIndex) * 6) {
 
2565                         *pLen = (Limit - LogPortIndex) * 6;
 
2566                         return (SK_PNMI_ERR_TOO_SHORT);
 
2568                 if (*pLen > (Limit - LogPortIndex) * 6) {
 
2571                         return (SK_PNMI_ERR_BAD_VALUE);
 
2577                 if (Action == SK_PNMI_PRESET) {
 
2580                         return (SK_PNMI_ERR_OK);
 
2584                  * Set OID_SKGE_MAC_CUR_ADDR
 
2586                 for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
 
2589                          * A set to virtual port and set of broadcast
 
2590                          * address will be ignored
 
2592                         if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
 
2593                                 "\xff\xff\xff\xff\xff\xff", 6) == 0) {
 
2598                         PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
 
2601                         Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
 
2602                                 (SK_MAC_ADDR *)(pBuf + Offset),
 
2603                                 (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
 
2604                                 SK_ADDR_PHYSICAL_ADDRESS));
 
2605                         if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {
 
2607                                 return (SK_PNMI_ERR_GENERAL);
 
2613         return (SK_PNMI_ERR_OK);
 
2616 /*****************************************************************************
 
2618  * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
 
2621  *      Retrieves the statistic values of the CSUM module. The CSUM data
 
2622  *      structure must be available in the SK_AC even if the CSUM module
 
2623  *      is not included, because PNMI reads the statistic data from the
 
2624  *      CSUM part of SK_AC directly.
 
2627  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
2628  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
2629  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
2630  *                               the correct data (e.g. a 32bit value is
 
2631  *                               needed, but a 16 bit value was passed).
 
2632  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
2633  *                           exist (e.g. port instance 3 on a two port
 
2636 PNMI_STATIC int CsumStat(
 
2637 SK_AC *pAC,             /* Pointer to adapter context */
 
2638 SK_IOC IoC,             /* IO context handle */
 
2639 int Action,             /* GET/PRESET/SET action */
 
2640 SK_U32 Id,              /* Object ID that is to be processed */
 
2641 char *pBuf,             /* Buffer used for the management data transfer */
 
2642 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
2643 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
2644 unsigned int TableIndex, /* Index to the Id table */
 
2645 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
2649         unsigned int    Offset = 0;
 
2654          * Calculate instance if wished
 
2656         if (Instance != (SK_U32)(-1)) {
 
2658                 if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
 
2661                         return (SK_PNMI_ERR_UNKNOWN_INST);
 
2663                 Index = (unsigned int)Instance - 1;
 
2668                 Limit = SKCS_NUM_PROTOCOLS;
 
2674         if (Action != SK_PNMI_GET) {
 
2677                 return (SK_PNMI_ERR_READ_ONLY);
 
2681         if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
 
2683                 *pLen = (Limit - Index) * sizeof(SK_U64);
 
2684                 return (SK_PNMI_ERR_TOO_SHORT);
 
2690         for (; Index < Limit; Index ++) {
 
2694                 case OID_SKGE_CHKSM_RX_OK_CTS:
 
2695                         StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
 
2698                 case OID_SKGE_CHKSM_RX_UNABLE_CTS:
 
2699                         StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
 
2702                 case OID_SKGE_CHKSM_RX_ERR_CTS:
 
2703                         StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
 
2706                 case OID_SKGE_CHKSM_TX_OK_CTS:
 
2707                         StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
 
2710                 case OID_SKGE_CHKSM_TX_UNABLE_CTS:
 
2711                         StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
 
2715                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
 
2719                         return (SK_PNMI_ERR_GENERAL);
 
2722                 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
 
2723                 Offset += sizeof(SK_U64);
 
2727          * Store used buffer space
 
2731         return (SK_PNMI_ERR_OK);
 
2734 /*****************************************************************************
 
2736  * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
 
2739  *      Retrieves the statistic values of the I2C module, which handles
 
2740  *      the temperature and voltage sensors.
 
2743  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
2744  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
2745  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
2746  *                               the correct data (e.g. a 32bit value is
 
2747  *                               needed, but a 16 bit value was passed).
 
2748  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
2749  *                           exist (e.g. port instance 3 on a two port
 
2752 PNMI_STATIC int SensorStat(
 
2753 SK_AC *pAC,             /* Pointer to adapter context */
 
2754 SK_IOC IoC,             /* IO context handle */
 
2755 int Action,             /* GET/PRESET/SET action */
 
2756 SK_U32 Id,              /* Object ID that is to be processed */
 
2757 char *pBuf,             /* Buffer used for the management data transfer */
 
2758 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
2759 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
2760 unsigned int TableIndex, /* Index to the Id table */
 
2761 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
2766         unsigned int    Offset;
 
2773          * Calculate instance if wished
 
2775         if ((Instance != (SK_U32)(-1))) {
 
2777                 if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
 
2780                         return (SK_PNMI_ERR_UNKNOWN_INST);
 
2783                 Index = (unsigned int)Instance -1;
 
2784                 Limit = (unsigned int)Instance;
 
2788                 Limit = (unsigned int) pAC->I2c.MaxSens;
 
2794         if (Action != SK_PNMI_GET) {
 
2797                 return (SK_PNMI_ERR_READ_ONLY);
 
2803         case OID_SKGE_SENSOR_VALUE:
 
2804         case OID_SKGE_SENSOR_WAR_THRES_LOW:
 
2805         case OID_SKGE_SENSOR_WAR_THRES_UPP:
 
2806         case OID_SKGE_SENSOR_ERR_THRES_LOW:
 
2807         case OID_SKGE_SENSOR_ERR_THRES_UPP:
 
2808                 if (*pLen < (Limit - Index) * sizeof(SK_U32)) {
 
2810                         *pLen = (Limit - Index) * sizeof(SK_U32);
 
2811                         return (SK_PNMI_ERR_TOO_SHORT);
 
2815         case OID_SKGE_SENSOR_DESCR:
 
2816                 for (Offset = 0, i = Index; i < Limit; i ++) {
 
2818                         Len = (unsigned int)
 
2819                                 SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1;
 
2820                         if (Len >= SK_PNMI_STRINGLEN2) {
 
2822                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011,
 
2826                                 return (SK_PNMI_ERR_GENERAL);
 
2830                 if (*pLen < Offset) {
 
2833                         return (SK_PNMI_ERR_TOO_SHORT);
 
2837         case OID_SKGE_SENSOR_INDEX:
 
2838         case OID_SKGE_SENSOR_TYPE:
 
2839         case OID_SKGE_SENSOR_STATUS:
 
2840                 if (*pLen < Limit - Index) {
 
2842                         *pLen = Limit - Index;
 
2843                         return (SK_PNMI_ERR_TOO_SHORT);
 
2847         case OID_SKGE_SENSOR_WAR_CTS:
 
2848         case OID_SKGE_SENSOR_WAR_TIME:
 
2849         case OID_SKGE_SENSOR_ERR_CTS:
 
2850         case OID_SKGE_SENSOR_ERR_TIME:
 
2851                 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
 
2853                         *pLen = (Limit - Index) * sizeof(SK_U64);
 
2854                         return (SK_PNMI_ERR_TOO_SHORT);
 
2859                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
 
2863                 return (SK_PNMI_ERR_GENERAL);
 
2870         for (Offset = 0; Index < Limit; Index ++) {
 
2874                 case OID_SKGE_SENSOR_INDEX:
 
2875                         *(pBuf + Offset) = (char)Index;
 
2876                         Offset += sizeof(char);
 
2879                 case OID_SKGE_SENSOR_DESCR:
 
2880                         Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
 
2881                         SK_MEMCPY(pBuf + Offset + 1,
 
2882                                 pAC->I2c.SenTable[Index].SenDesc, Len);
 
2883                         *(pBuf + Offset) = (char)Len;
 
2887                 case OID_SKGE_SENSOR_TYPE:
 
2889                                 (char)pAC->I2c.SenTable[Index].SenType;
 
2890                         Offset += sizeof(char);
 
2893                 case OID_SKGE_SENSOR_VALUE:
 
2894                         Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
 
2895                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
2896                         Offset += sizeof(SK_U32);
 
2899                 case OID_SKGE_SENSOR_WAR_THRES_LOW:
 
2900                         Val32 = (SK_U32)pAC->I2c.SenTable[Index].
 
2902                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
2903                         Offset += sizeof(SK_U32);
 
2906                 case OID_SKGE_SENSOR_WAR_THRES_UPP:
 
2907                         Val32 = (SK_U32)pAC->I2c.SenTable[Index].
 
2909                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
2910                         Offset += sizeof(SK_U32);
 
2913                 case OID_SKGE_SENSOR_ERR_THRES_LOW:
 
2914                         Val32 = (SK_U32)pAC->I2c.SenTable[Index].
 
2916                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
2917                         Offset += sizeof(SK_U32);
 
2920                 case OID_SKGE_SENSOR_ERR_THRES_UPP:
 
2921                         Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
 
2922                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
2923                         Offset += sizeof(SK_U32);
 
2926                 case OID_SKGE_SENSOR_STATUS:
 
2928                                 (char)pAC->I2c.SenTable[Index].SenErrFlag;
 
2929                         Offset += sizeof(char);
 
2932                 case OID_SKGE_SENSOR_WAR_CTS:
 
2933                         Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
 
2934                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
 
2935                         Offset += sizeof(SK_U64);
 
2938                 case OID_SKGE_SENSOR_ERR_CTS:
 
2939                         Val64 = pAC->I2c.SenTable[Index].SenErrCts;
 
2940                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
 
2941                         Offset += sizeof(SK_U64);
 
2944                 case OID_SKGE_SENSOR_WAR_TIME:
 
2945                         Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
 
2947                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
 
2948                         Offset += sizeof(SK_U64);
 
2951                 case OID_SKGE_SENSOR_ERR_TIME:
 
2952                         Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
 
2954                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
 
2955                         Offset += sizeof(SK_U64);
 
2959                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
 
2960                                 ("SensorStat: Unknown OID should be handled before"));
 
2962                         return (SK_PNMI_ERR_GENERAL);
 
2967          * Store used buffer space
 
2971         return (SK_PNMI_ERR_OK);
 
2974 /*****************************************************************************
 
2976  * Vpd - OID handler function of OID_SKGE_VPD_XXX
 
2979  *      Get/preset/set of VPD data. As instance the name of a VPD key
 
2980  *      can be passed. The Instance parameter is a SK_U32 and can be
 
2981  *      used as a string buffer for the VPD key, because their maximum
 
2985  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
2986  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
2987  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
2988  *                               the correct data (e.g. a 32bit value is
 
2989  *                               needed, but a 16 bit value was passed).
 
2990  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 
2992  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 
2993  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
2994  *                           exist (e.g. port instance 3 on a two port
 
2997 PNMI_STATIC int Vpd(
 
2998 SK_AC *pAC,             /* Pointer to adapter context */
 
2999 SK_IOC IoC,             /* IO context handle */
 
3000 int Action,             /* GET/PRESET/SET action */
 
3001 SK_U32 Id,              /* Object ID that is to be processed */
 
3002 char *pBuf,             /* Buffer used for the management data transfer */
 
3003 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
3004 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
3005 unsigned int TableIndex, /* Index to the Id table */
 
3006 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
3008         SK_VPD_STATUS   *pVpdStatus;
 
3009         unsigned int    BufLen;
 
3011         char            KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
 
3012         char            KeyStr[SK_PNMI_VPD_KEY_SIZE];
 
3014         unsigned int    Offset;
 
3016         unsigned int    FirstIndex;
 
3017         unsigned int    LastIndex;
 
3023          * Get array of all currently stored VPD keys
 
3025         Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &KeyNo);
 
3026         if (Ret != SK_PNMI_ERR_OK) {
 
3032          * If instance is not -1, try to find the requested VPD key for
 
3033          * the multiple instance variables. The other OIDs as for example
 
3034          * OID VPD_ACTION are single instance variables and must be
 
3035          * handled separatly.
 
3040         if ((Instance != (SK_U32)(-1))) {
 
3042                 if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
 
3043                         Id == OID_SKGE_VPD_ACCESS) {
 
3045                         SK_STRNCPY(KeyStr, (char *)&Instance, 4);
 
3048                         for (Index = 0; Index < KeyNo; Index ++) {
 
3050                                 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
 
3052                                         LastIndex = Index+1;
 
3056                         if (Index == KeyNo) {
 
3059                                 return (SK_PNMI_ERR_UNKNOWN_INST);
 
3062                 else if (Instance != 1) {
 
3065                         return (SK_PNMI_ERR_UNKNOWN_INST);
 
3070          * Get value, if a query should be performed
 
3072         if (Action == SK_PNMI_GET) {
 
3076                 case OID_SKGE_VPD_FREE_BYTES:
 
3077                         /* Check length of buffer */
 
3078                         if (*pLen < sizeof(SK_U32)) {
 
3080                                 *pLen = sizeof(SK_U32);
 
3081                                 return (SK_PNMI_ERR_TOO_SHORT);
 
3083                         /* Get number of free bytes */
 
3084                         pVpdStatus = VpdStat(pAC, IoC);
 
3085                         if (pVpdStatus == NULL) {
 
3087                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
 
3091                                 return (SK_PNMI_ERR_GENERAL);
 
3093                         if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
 
3095                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
 
3099                                 return (SK_PNMI_ERR_GENERAL);
 
3102                         Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
 
3103                         SK_PNMI_STORE_U32(pBuf, Val32);
 
3104                         *pLen = sizeof(SK_U32);
 
3107                 case OID_SKGE_VPD_ENTRIES_LIST:
 
3109                         for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
 
3111                                 Len += SK_STRLEN(KeyArr[Index]) + 1;
 
3116                                 return (SK_PNMI_ERR_TOO_SHORT);
 
3120                         *(pBuf) = (char)Len - 1;
 
3121                         for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
 
3123                                 Len = SK_STRLEN(KeyArr[Index]);
 
3124                                 SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
 
3128                                 if (Index < KeyNo - 1) {
 
3130                                         *(pBuf + Offset) = ' ';
 
3137                 case OID_SKGE_VPD_ENTRIES_NUMBER:
 
3139                         if (*pLen < sizeof(SK_U32)) {
 
3141                                 *pLen = sizeof(SK_U32);
 
3142                                 return (SK_PNMI_ERR_TOO_SHORT);
 
3145                         Val32 = (SK_U32)KeyNo;
 
3146                         SK_PNMI_STORE_U32(pBuf, Val32);
 
3147                         *pLen = sizeof(SK_U32);
 
3150                 case OID_SKGE_VPD_KEY:
 
3151                         /* Check buffer length, if it is large enough */
 
3152                         for (Len = 0, Index = FirstIndex;
 
3153                                 Index < LastIndex; Index ++) {
 
3155                                 Len += SK_STRLEN(KeyArr[Index]) + 1;
 
3160                                 return (SK_PNMI_ERR_TOO_SHORT);
 
3164                          * Get the key to an intermediate buffer, because
 
3165                          * we have to prepend a length byte.
 
3167                         for (Offset = 0, Index = FirstIndex;
 
3168                                 Index < LastIndex; Index ++) {
 
3170                                 Len = SK_STRLEN(KeyArr[Index]);
 
3172                                 *(pBuf + Offset) = (char)Len;
 
3173                                 SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
 
3180                 case OID_SKGE_VPD_VALUE:
 
3181                         /* Check the buffer length if it is large enough */
 
3182                         for (Offset = 0, Index = FirstIndex;
 
3183                                 Index < LastIndex; Index ++) {
 
3186                                 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
 
3187                                         (int *)&BufLen) > 0 ||
 
3188                                         BufLen >= SK_PNMI_VPD_DATALEN) {
 
3190                                         SK_ERR_LOG(pAC, SK_ERRCL_SW,
 
3194                                         return (SK_PNMI_ERR_GENERAL);
 
3196                                 Offset += BufLen + 1;
 
3198                         if (*pLen < Offset) {
 
3201                                 return (SK_PNMI_ERR_TOO_SHORT);
 
3205                          * Get the value to an intermediate buffer, because
 
3206                          * we have to prepend a length byte.
 
3208                         for (Offset = 0, Index = FirstIndex;
 
3209                                 Index < LastIndex; Index ++) {
 
3212                                 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
 
3213                                         (int *)&BufLen) > 0 ||
 
3214                                         BufLen >= SK_PNMI_VPD_DATALEN) {
 
3216                                         SK_ERR_LOG(pAC, SK_ERRCL_SW,
 
3221                                         return (SK_PNMI_ERR_GENERAL);
 
3224                                 *(pBuf + Offset) = (char)BufLen;
 
3225                                 SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
 
3226                                 Offset += BufLen + 1;
 
3231                 case OID_SKGE_VPD_ACCESS:
 
3232                         if (*pLen < LastIndex - FirstIndex) {
 
3234                                 *pLen = LastIndex - FirstIndex;
 
3235                                 return (SK_PNMI_ERR_TOO_SHORT);
 
3238                         for (Offset = 0, Index = FirstIndex;
 
3239                                 Index < LastIndex; Index ++) {
 
3241                                 if (VpdMayWrite(KeyArr[Index])) {
 
3243                                         *(pBuf + Offset) = SK_PNMI_VPD_RW;
 
3246                                         *(pBuf + Offset) = SK_PNMI_VPD_RO;
 
3253                 case OID_SKGE_VPD_ACTION:
 
3254                         Offset = LastIndex - FirstIndex;
 
3255                         if (*pLen < Offset) {
 
3258                                 return (SK_PNMI_ERR_TOO_SHORT);
 
3260                         SK_MEMSET(pBuf, 0, Offset);
 
3265                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
 
3269                         return (SK_PNMI_ERR_GENERAL);
 
3273                 /* The only OID which can be set is VPD_ACTION */
 
3274                 if (Id != OID_SKGE_VPD_ACTION) {
 
3276                         if (Id == OID_SKGE_VPD_FREE_BYTES ||
 
3277                                 Id == OID_SKGE_VPD_ENTRIES_LIST ||
 
3278                                 Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
 
3279                                 Id == OID_SKGE_VPD_KEY ||
 
3280                                 Id == OID_SKGE_VPD_VALUE ||
 
3281                                 Id == OID_SKGE_VPD_ACCESS) {
 
3284                                 return (SK_PNMI_ERR_READ_ONLY);
 
3287                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
 
3291                         return (SK_PNMI_ERR_GENERAL);
 
3295                  * From this point we handle VPD_ACTION. Check the buffer
 
3296                  * length. It should at least have the size of one byte.
 
3301                         return (SK_PNMI_ERR_TOO_SHORT);
 
3305                  * The first byte contains the VPD action type we should
 
3310                 case SK_PNMI_VPD_IGNORE:
 
3314                 case SK_PNMI_VPD_CREATE:
 
3316                          * We have to create a new VPD entry or we modify
 
3317                          * an existing one. Check first the buffer length.
 
3322                                 return (SK_PNMI_ERR_TOO_SHORT);
 
3324                         KeyStr[0] = pBuf[1];
 
3325                         KeyStr[1] = pBuf[2];
 
3329                          * Is the entry writable or does it belong to the
 
3332                         if (!VpdMayWrite(KeyStr)) {
 
3335                                 return (SK_PNMI_ERR_BAD_VALUE);
 
3338                         Offset = (int)pBuf[3] & 0xFF;
 
3340                         SK_MEMCPY(Buf, pBuf + 4, Offset);
 
3343                         /* A preset ends here */
 
3344                         if (Action == SK_PNMI_PRESET) {
 
3346                                 return (SK_PNMI_ERR_OK);
 
3349                         /* Write the new entry or modify an existing one */
 
3350                         Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
 
3351                         if (Ret == SK_PNMI_VPD_NOWRITE ) {
 
3354                                 return (SK_PNMI_ERR_BAD_VALUE);
 
3356                         else if (Ret != SK_PNMI_VPD_OK) {
 
3358                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
 
3362                                 return (SK_PNMI_ERR_GENERAL);
 
3366                          * Perform an update of the VPD data. This is
 
3367                          * not mandantory, but just to be sure.
 
3369                         Ret = VpdUpdate(pAC, IoC);
 
3370                         if (Ret != SK_PNMI_VPD_OK) {
 
3372                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
 
3376                                 return (SK_PNMI_ERR_GENERAL);
 
3380                 case SK_PNMI_VPD_DELETE:
 
3381                         /* Check if the buffer size is plausible */
 
3385                                 return (SK_PNMI_ERR_TOO_SHORT);
 
3390                                 return (SK_PNMI_ERR_BAD_VALUE);
 
3392                         KeyStr[0] = pBuf[1];
 
3393                         KeyStr[1] = pBuf[2];
 
3396                         /* Find the passed key in the array */
 
3397                         for (Index = 0; Index < KeyNo; Index ++) {
 
3399                                 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
 
3405                          * If we cannot find the key it is wrong, so we
 
3406                          * return an appropriate error value.
 
3408                         if (Index == KeyNo) {
 
3411                                 return (SK_PNMI_ERR_BAD_VALUE);
 
3414                         if (Action == SK_PNMI_PRESET) {
 
3416                                 return (SK_PNMI_ERR_OK);
 
3419                         /* Ok, you wanted it and you will get it */
 
3420                         Ret = VpdDelete(pAC, IoC, KeyStr);
 
3421                         if (Ret != SK_PNMI_VPD_OK) {
 
3423                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
 
3427                                 return (SK_PNMI_ERR_GENERAL);
 
3431                          * Perform an update of the VPD data. This is
 
3432                          * not mandantory, but just to be sure.
 
3434                         Ret = VpdUpdate(pAC, IoC);
 
3435                         if (Ret != SK_PNMI_VPD_OK) {
 
3437                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
 
3441                                 return (SK_PNMI_ERR_GENERAL);
 
3447                         return (SK_PNMI_ERR_BAD_VALUE);
 
3451         return (SK_PNMI_ERR_OK);
 
3454 /*****************************************************************************
 
3456  * General - OID handler function of various single instance OIDs
 
3459  *      The code is simple. No description necessary.
 
3462  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
3463  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
3464  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
3465  *                               the correct data (e.g. a 32bit value is
 
3466  *                               needed, but a 16 bit value was passed).
 
3467  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
3468  *                           exist (e.g. port instance 3 on a two port
 
3471 PNMI_STATIC int General(
 
3472 SK_AC *pAC,             /* Pointer to adapter context */
 
3473 SK_IOC IoC,             /* IO context handle */
 
3474 int Action,             /* GET/PRESET/SET action */
 
3475 SK_U32 Id,              /* Object ID that is to be processed */
 
3476 char *pBuf,             /* Buffer used for the management data transfer */
 
3477 unsigned int *pLen,     /* On call: buffer length. On return: used buffer */
 
3478 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
3479 unsigned int TableIndex, /* Index to the Id table */
 
3480 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
3485         unsigned int    Offset;
 
3491         SK_U64          Val64RxHwErrs = 0;
 
3492         SK_U64          Val64TxHwErrs = 0;
 
3493         SK_BOOL         Is64BitReq = SK_FALSE;
 
3498          * Check instance. We only handle single instance variables.
 
3500         if (Instance != (SK_U32)(-1) && Instance != 1) {
 
3503                 return (SK_PNMI_ERR_UNKNOWN_INST);
 
3507          * Check action. We only allow get requests.
 
3509         if (Action != SK_PNMI_GET) {
 
3512                 return (SK_PNMI_ERR_READ_ONLY);
 
3515         MacType = pAC->GIni.GIMacType;
 
3518          * Check length for the various supported OIDs
 
3522         case OID_GEN_XMIT_ERROR:
 
3523         case OID_GEN_RCV_ERROR:
 
3524         case OID_GEN_RCV_NO_BUFFER:
 
3525 #ifndef SK_NDIS_64BIT_CTR
 
3526                 if (*pLen < sizeof(SK_U32)) {
 
3527                         *pLen = sizeof(SK_U32);
 
3528                         return (SK_PNMI_ERR_TOO_SHORT);
 
3531 #else /* SK_NDIS_64BIT_CTR */
 
3534                  * for compatibility, at least 32bit are required for oid
 
3536                 if (*pLen < sizeof(SK_U32)) {
 
3538                         * but indicate handling for 64bit values,
 
3539                         * if insufficient space is provided
 
3541                         *pLen = sizeof(SK_U64);
 
3542                         return (SK_PNMI_ERR_TOO_SHORT);
 
3545                 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
 
3546 #endif /* SK_NDIS_64BIT_CTR */
 
3549         case OID_SKGE_PORT_NUMBER:
 
3550         case OID_SKGE_DEVICE_TYPE:
 
3551         case OID_SKGE_RESULT:
 
3552         case OID_SKGE_RLMT_MONITOR_NUMBER:
 
3553         case OID_GEN_TRANSMIT_QUEUE_LENGTH:
 
3554         case OID_SKGE_TRAP_NUMBER:
 
3555         case OID_SKGE_MDB_VERSION:
 
3556         case OID_SKGE_BOARDLEVEL:
 
3557         case OID_SKGE_CHIPID:
 
3558         case OID_SKGE_RAMSIZE:
 
3559                 if (*pLen < sizeof(SK_U32)) {
 
3561                         *pLen = sizeof(SK_U32);
 
3562                         return (SK_PNMI_ERR_TOO_SHORT);
 
3566         case OID_SKGE_CHIPSET:
 
3567                 if (*pLen < sizeof(SK_U16)) {
 
3569                         *pLen = sizeof(SK_U16);
 
3570                         return (SK_PNMI_ERR_TOO_SHORT);
 
3574         case OID_SKGE_BUS_TYPE:
 
3575         case OID_SKGE_BUS_SPEED:
 
3576         case OID_SKGE_BUS_WIDTH:
 
3577         case OID_SKGE_SENSOR_NUMBER:
 
3578         case OID_SKGE_CHKSM_NUMBER:
 
3579         case OID_SKGE_VAUXAVAIL:
 
3580                 if (*pLen < sizeof(SK_U8)) {
 
3582                         *pLen = sizeof(SK_U8);
 
3583                         return (SK_PNMI_ERR_TOO_SHORT);
 
3587         case OID_SKGE_TX_SW_QUEUE_LEN:
 
3588         case OID_SKGE_TX_SW_QUEUE_MAX:
 
3589         case OID_SKGE_TX_RETRY:
 
3590         case OID_SKGE_RX_INTR_CTS:
 
3591         case OID_SKGE_TX_INTR_CTS:
 
3592         case OID_SKGE_RX_NO_BUF_CTS:
 
3593         case OID_SKGE_TX_NO_BUF_CTS:
 
3594         case OID_SKGE_TX_USED_DESCR_NO:
 
3595         case OID_SKGE_RX_DELIVERED_CTS:
 
3596         case OID_SKGE_RX_OCTETS_DELIV_CTS:
 
3597         case OID_SKGE_RX_HW_ERROR_CTS:
 
3598         case OID_SKGE_TX_HW_ERROR_CTS:
 
3599         case OID_SKGE_IN_ERRORS_CTS:
 
3600         case OID_SKGE_OUT_ERROR_CTS:
 
3601         case OID_SKGE_ERR_RECOVERY_CTS:
 
3602         case OID_SKGE_SYSUPTIME:
 
3603                 if (*pLen < sizeof(SK_U64)) {
 
3605                         *pLen = sizeof(SK_U64);
 
3606                         return (SK_PNMI_ERR_TOO_SHORT);
 
3615         /* Update statistic */
 
3616         if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
 
3617                 Id == OID_SKGE_TX_HW_ERROR_CTS ||
 
3618                 Id == OID_SKGE_IN_ERRORS_CTS ||
 
3619                 Id == OID_SKGE_OUT_ERROR_CTS ||
 
3620                 Id == OID_GEN_XMIT_ERROR ||
 
3621                 Id == OID_GEN_RCV_ERROR) {
 
3623                 /* Force the XMAC to update its statistic counters and
 
3624                  * Increment semaphore to indicate that an update was
 
3627                 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
 
3628                 if (Ret != SK_PNMI_ERR_OK) {
 
3633                 pAC->Pnmi.MacUpdatedFlag ++;
 
3636                  * Some OIDs consist of multiple hardware counters. Those
 
3637                  * values which are contained in all of them will be added
 
3642                 case OID_SKGE_RX_HW_ERROR_CTS:
 
3643                 case OID_SKGE_IN_ERRORS_CTS:
 
3644                 case OID_GEN_RCV_ERROR:
 
3646                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
 
3647                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
 
3648                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex) +
 
3649                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
 
3650                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
 
3651                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex) +
 
3652                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
 
3653                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
 
3654                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
 
3655                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
 
3656                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
 
3657                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
 
3660                 case OID_SKGE_TX_HW_ERROR_CTS:
 
3661                 case OID_SKGE_OUT_ERROR_CTS:
 
3662                 case OID_GEN_XMIT_ERROR:
 
3664                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
 
3665                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex) +
 
3666                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex) +
 
3667                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex);
 
3677         case OID_SKGE_SUPPORTED_LIST:
 
3678                 Len = ID_TABLE_SIZE * sizeof(SK_U32);
 
3682                         return (SK_PNMI_ERR_TOO_SHORT);
 
3684                 for (Offset = 0, Index = 0; Offset < Len;
 
3685                         Offset += sizeof(SK_U32), Index ++) {
 
3687                         Val32 = (SK_U32)IdTable[Index].Id;
 
3688                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
3693         case OID_SKGE_BOARDLEVEL:
 
3694                 Val32 = (SK_U32)pAC->GIni.GILevel;
 
3695                 SK_PNMI_STORE_U32(pBuf, Val32);
 
3696                 *pLen = sizeof(SK_U32);
 
3699         case OID_SKGE_PORT_NUMBER:
 
3700                 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
 
3701                 SK_PNMI_STORE_U32(pBuf, Val32);
 
3702                 *pLen = sizeof(SK_U32);
 
3705         case OID_SKGE_DEVICE_TYPE:
 
3706                 Val32 = (SK_U32)pAC->Pnmi.DeviceType;
 
3707                 SK_PNMI_STORE_U32(pBuf, Val32);
 
3708                 *pLen = sizeof(SK_U32);
 
3711         case OID_SKGE_DRIVER_DESCR:
 
3712                 if (pAC->Pnmi.pDriverDescription == NULL) {
 
3714                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
 
3718                         return (SK_PNMI_ERR_GENERAL);
 
3721                 Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
 
3722                 if (Len > SK_PNMI_STRINGLEN1) {
 
3724                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
 
3728                         return (SK_PNMI_ERR_GENERAL);
 
3734                         return (SK_PNMI_ERR_TOO_SHORT);
 
3736                 *pBuf = (char)(Len - 1);
 
3737                 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
 
3741         case OID_SKGE_DRIVER_VERSION:
 
3742                 if (pAC->Pnmi.pDriverVersion == NULL) {
 
3744                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
 
3748                         return (SK_PNMI_ERR_GENERAL);
 
3751                 Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
 
3752                 if (Len > SK_PNMI_STRINGLEN1) {
 
3754                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
 
3758                         return (SK_PNMI_ERR_GENERAL);
 
3764                         return (SK_PNMI_ERR_TOO_SHORT);
 
3766                 *pBuf = (char)(Len - 1);
 
3767                 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
 
3771         case OID_SKGE_DRIVER_RELDATE:
 
3772                 if (pAC->Pnmi.pDriverReleaseDate == NULL) {
 
3774                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
 
3778                         return (SK_PNMI_ERR_GENERAL);
 
3781                 Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1;
 
3782                 if (Len > SK_PNMI_STRINGLEN1) {
 
3784                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
 
3788                         return (SK_PNMI_ERR_GENERAL);
 
3794                         return (SK_PNMI_ERR_TOO_SHORT);
 
3796                 *pBuf = (char)(Len - 1);
 
3797                 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverReleaseDate, Len - 1);
 
3801         case OID_SKGE_DRIVER_FILENAME:
 
3802                 if (pAC->Pnmi.pDriverFileName == NULL) {
 
3804                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
 
3808                         return (SK_PNMI_ERR_GENERAL);
 
3811                 Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1;
 
3812                 if (Len > SK_PNMI_STRINGLEN1) {
 
3814                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
 
3818                         return (SK_PNMI_ERR_GENERAL);
 
3824                         return (SK_PNMI_ERR_TOO_SHORT);
 
3826                 *pBuf = (char)(Len - 1);
 
3827                 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverFileName, Len - 1);
 
3831         case OID_SKGE_HW_DESCR:
 
3833                  * The hardware description is located in the VPD. This
 
3834                  * query may move to the initialisation routine. But
 
3835                  * the VPD data is cached and therefore a call here
 
3836                  * will not make much difference.
 
3839                 if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
 
3841                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
 
3845                         return (SK_PNMI_ERR_GENERAL);
 
3848                 if (Len > SK_PNMI_STRINGLEN1) {
 
3850                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
 
3854                         return (SK_PNMI_ERR_GENERAL);
 
3859                         return (SK_PNMI_ERR_TOO_SHORT);
 
3861                 *pBuf = (char)(Len - 1);
 
3862                 SK_MEMCPY(pBuf + 1, Buf, Len - 1);
 
3866         case OID_SKGE_HW_VERSION:
 
3867                 /* Oh, I love to do some string manipulation */
 
3871                         return (SK_PNMI_ERR_TOO_SHORT);
 
3873                 Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
 
3876                 pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
 
3878                 pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
 
3882         case OID_SKGE_CHIPSET:
 
3883                 Val16 = pAC->Pnmi.Chipset;
 
3884                 SK_PNMI_STORE_U16(pBuf, Val16);
 
3885                 *pLen = sizeof(SK_U16);
 
3888         case OID_SKGE_CHIPID:
 
3889                 Val32 = pAC->GIni.GIChipId;
 
3890                 SK_PNMI_STORE_U32(pBuf, Val32);
 
3891                 *pLen = sizeof(SK_U32);
 
3894         case OID_SKGE_RAMSIZE:
 
3895                 Val32 = pAC->GIni.GIRamSize;
 
3896                 SK_PNMI_STORE_U32(pBuf, Val32);
 
3897                 *pLen = sizeof(SK_U32);
 
3900         case OID_SKGE_VAUXAVAIL:
 
3901                 *pBuf = (char) pAC->GIni.GIVauxAvail;
 
3902                 *pLen = sizeof(char);
 
3905         case OID_SKGE_BUS_TYPE:
 
3906                 *pBuf = (char) SK_PNMI_BUS_PCI;
 
3907                 *pLen = sizeof(char);
 
3910         case OID_SKGE_BUS_SPEED:
 
3911                 *pBuf = pAC->Pnmi.PciBusSpeed;
 
3912                 *pLen = sizeof(char);
 
3915         case OID_SKGE_BUS_WIDTH:
 
3916                 *pBuf = pAC->Pnmi.PciBusWidth;
 
3917                 *pLen = sizeof(char);
 
3920         case OID_SKGE_RESULT:
 
3921                 Val32 = pAC->Pnmi.TestResult;
 
3922                 SK_PNMI_STORE_U32(pBuf, Val32);
 
3923                 *pLen = sizeof(SK_U32);
 
3926         case OID_SKGE_SENSOR_NUMBER:
 
3927                 *pBuf = (char)pAC->I2c.MaxSens;
 
3928                 *pLen = sizeof(char);
 
3931         case OID_SKGE_CHKSM_NUMBER:
 
3932                 *pBuf = SKCS_NUM_PROTOCOLS;
 
3933                 *pLen = sizeof(char);
 
3936         case OID_SKGE_TRAP_NUMBER:
 
3937                 GetTrapQueueLen(pAC, &Len, &Val);
 
3938                 Val32 = (SK_U32)Val;
 
3939                 SK_PNMI_STORE_U32(pBuf, Val32);
 
3940                 *pLen = sizeof(SK_U32);
 
3944                 GetTrapQueueLen(pAC, &Len, &Val);
 
3948                         return (SK_PNMI_ERR_TOO_SHORT);
 
3950                 CopyTrapQueue(pAC, pBuf);
 
3954         case OID_SKGE_RLMT_MONITOR_NUMBER:
 
3955 /* XXX Not yet implemented by RLMT therefore we return zero elements */
 
3957                 SK_PNMI_STORE_U32(pBuf, Val32);
 
3958                 *pLen = sizeof(SK_U32);
 
3961         case OID_SKGE_TX_SW_QUEUE_LEN:
 
3962                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
3963                 if (MacType == SK_MAC_XMAC) {
 
3965                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
3966                                 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
 
3968                         /* Single net mode */
 
3970                                 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
 
3971                                         pAC->Pnmi.BufPort[1].TxSwQueueLen;
 
3976                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
3977                                 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
 
3979                         /* Single net mode */
 
3981                                 Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
 
3982                                         pAC->Pnmi.Port[1].TxSwQueueLen;
 
3985                 SK_PNMI_STORE_U64(pBuf, Val64);
 
3986                 *pLen = sizeof(SK_U64);
 
3990         case OID_SKGE_TX_SW_QUEUE_MAX:
 
3991                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
3992                 if (MacType == SK_MAC_XMAC) {
 
3994                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
3995                                 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
 
3997                         /* Single net mode */
 
3999                                 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
 
4000                                         pAC->Pnmi.BufPort[1].TxSwQueueMax;
 
4005                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4006                                 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
 
4008                         /* Single net mode */
 
4010                                 Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
 
4011                                         pAC->Pnmi.Port[1].TxSwQueueMax;
 
4014                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4015                 *pLen = sizeof(SK_U64);
 
4018         case OID_SKGE_TX_RETRY:
 
4019                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4020                 if (MacType == SK_MAC_XMAC) {
 
4022                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4023                                 Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
 
4025                         /* Single net mode */
 
4027                                 Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
 
4028                                         pAC->Pnmi.BufPort[1].TxRetryCts;
 
4033                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4034                                 Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
 
4036                         /* Single net mode */
 
4038                                 Val64 = pAC->Pnmi.Port[0].TxRetryCts +
 
4039                                         pAC->Pnmi.Port[1].TxRetryCts;
 
4042                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4043                 *pLen = sizeof(SK_U64);
 
4046         case OID_SKGE_RX_INTR_CTS:
 
4047                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4048                 if (MacType == SK_MAC_XMAC) {
 
4050                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4051                                 Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
 
4053                         /* Single net mode */
 
4055                                 Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
 
4056                                         pAC->Pnmi.BufPort[1].RxIntrCts;
 
4061                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4062                                 Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
 
4064                         /* Single net mode */
 
4066                                 Val64 = pAC->Pnmi.Port[0].RxIntrCts +
 
4067                                         pAC->Pnmi.Port[1].RxIntrCts;
 
4070                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4071                 *pLen = sizeof(SK_U64);
 
4074         case OID_SKGE_TX_INTR_CTS:
 
4075                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4076                 if (MacType == SK_MAC_XMAC) {
 
4078                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4079                                 Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
 
4081                         /* Single net mode */
 
4083                                 Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
 
4084                                         pAC->Pnmi.BufPort[1].TxIntrCts;
 
4089                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4090                                 Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
 
4092                         /* Single net mode */
 
4094                                 Val64 = pAC->Pnmi.Port[0].TxIntrCts +
 
4095                                         pAC->Pnmi.Port[1].TxIntrCts;
 
4098                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4099                 *pLen = sizeof(SK_U64);
 
4102         case OID_SKGE_RX_NO_BUF_CTS:
 
4103                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4104                 if (MacType == SK_MAC_XMAC) {
 
4106                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4107                                 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
 
4109                         /* Single net mode */
 
4111                                 Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
 
4112                                         pAC->Pnmi.BufPort[1].RxNoBufCts;
 
4117                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4118                                 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
 
4120                         /* Single net mode */
 
4122                                 Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
 
4123                                         pAC->Pnmi.Port[1].RxNoBufCts;
 
4126                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4127                 *pLen = sizeof(SK_U64);
 
4130         case OID_SKGE_TX_NO_BUF_CTS:
 
4131                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4132                 if (MacType == SK_MAC_XMAC) {
 
4134                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4135                                 Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
 
4137                         /* Single net mode */
 
4139                                 Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
 
4140                                         pAC->Pnmi.BufPort[1].TxNoBufCts;
 
4145                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4146                                 Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
 
4148                         /* Single net mode */
 
4150                                 Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
 
4151                                         pAC->Pnmi.Port[1].TxNoBufCts;
 
4154                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4155                 *pLen = sizeof(SK_U64);
 
4158         case OID_SKGE_TX_USED_DESCR_NO:
 
4159                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4160                 if (MacType == SK_MAC_XMAC) {
 
4162                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4163                                 Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
 
4165                         /* Single net mode */
 
4167                                 Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
 
4168                                         pAC->Pnmi.BufPort[1].TxUsedDescrNo;
 
4173                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4174                                 Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
 
4176                         /* Single net mode */
 
4178                                 Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
 
4179                                         pAC->Pnmi.Port[1].TxUsedDescrNo;
 
4182                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4183                 *pLen = sizeof(SK_U64);
 
4186         case OID_SKGE_RX_DELIVERED_CTS:
 
4187                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4188                 if (MacType == SK_MAC_XMAC) {
 
4190                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4191                                 Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
 
4193                         /* Single net mode */
 
4195                                 Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
 
4196                                         pAC->Pnmi.BufPort[1].RxDeliveredCts;
 
4201                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4202                                 Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
 
4204                         /* Single net mode */
 
4206                                 Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
 
4207                                         pAC->Pnmi.Port[1].RxDeliveredCts;
 
4210                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4211                 *pLen = sizeof(SK_U64);
 
4214         case OID_SKGE_RX_OCTETS_DELIV_CTS:
 
4215                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4216                 if (MacType == SK_MAC_XMAC) {
 
4218                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4219                                 Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
 
4221                         /* Single net mode */
 
4223                                 Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
 
4224                                         pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
 
4229                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4230                                 Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
 
4232                         /* Single net mode */
 
4234                                 Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
 
4235                                         pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
 
4238                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4239                 *pLen = sizeof(SK_U64);
 
4242         case OID_SKGE_RX_HW_ERROR_CTS:
 
4243                 SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
 
4244                 *pLen = sizeof(SK_U64);
 
4247         case OID_SKGE_TX_HW_ERROR_CTS:
 
4248                 SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
 
4249                 *pLen = sizeof(SK_U64);
 
4252         case OID_SKGE_IN_ERRORS_CTS:
 
4253                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4254                 if (MacType == SK_MAC_XMAC) {
 
4256                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4257                                 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
 
4259                         /* Single net mode */
 
4261                                 Val64 = Val64RxHwErrs +
 
4262                                         pAC->Pnmi.BufPort[0].RxNoBufCts +
 
4263                                         pAC->Pnmi.BufPort[1].RxNoBufCts;
 
4268                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4269                                 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
 
4271                         /* Single net mode */
 
4273                                 Val64 = Val64RxHwErrs +
 
4274                                         pAC->Pnmi.Port[0].RxNoBufCts +
 
4275                                         pAC->Pnmi.Port[1].RxNoBufCts;
 
4278                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4279                 *pLen = sizeof(SK_U64);
 
4282         case OID_SKGE_OUT_ERROR_CTS:
 
4283                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4284                 if (MacType == SK_MAC_XMAC) {
 
4286                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4287                                 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
 
4289                         /* Single net mode */
 
4291                                 Val64 = Val64TxHwErrs +
 
4292                                         pAC->Pnmi.BufPort[0].TxNoBufCts +
 
4293                                         pAC->Pnmi.BufPort[1].TxNoBufCts;
 
4298                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4299                                 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
 
4301                         /* Single net mode */
 
4303                                 Val64 = Val64TxHwErrs +
 
4304                                         pAC->Pnmi.Port[0].TxNoBufCts +
 
4305                                         pAC->Pnmi.Port[1].TxNoBufCts;
 
4308                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4309                 *pLen = sizeof(SK_U64);
 
4312         case OID_SKGE_ERR_RECOVERY_CTS:
 
4313                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4314                 if (MacType == SK_MAC_XMAC) {
 
4316                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4317                                 Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
 
4319                         /* Single net mode */
 
4321                                 Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
 
4322                                         pAC->Pnmi.BufPort[1].ErrRecoveryCts;
 
4327                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4328                                 Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
 
4330                         /* Single net mode */
 
4332                                 Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
 
4333                                         pAC->Pnmi.Port[1].ErrRecoveryCts;
 
4336                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4337                 *pLen = sizeof(SK_U64);
 
4340         case OID_SKGE_SYSUPTIME:
 
4341                 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
 
4342                 Val64 -= pAC->Pnmi.StartUpTime;
 
4343                 SK_PNMI_STORE_U64(pBuf, Val64);
 
4344                 *pLen = sizeof(SK_U64);
 
4347         case OID_SKGE_MDB_VERSION:
 
4348                 Val32 = SK_PNMI_MDB_VERSION;
 
4349                 SK_PNMI_STORE_U32(pBuf, Val32);
 
4350                 *pLen = sizeof(SK_U32);
 
4353         case OID_GEN_RCV_ERROR:
 
4354                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4355                 if (MacType == SK_MAC_XMAC) {
 
4356                         Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
 
4359                         Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
 
4363                  * by default 32bit values are evaluated
 
4366                         Val32 = (SK_U32)Val64;
 
4367                         SK_PNMI_STORE_U32(pBuf, Val32);
 
4368                         *pLen = sizeof(SK_U32);
 
4371                         SK_PNMI_STORE_U64(pBuf, Val64);
 
4372                         *pLen = sizeof(SK_U64);
 
4376         case OID_GEN_XMIT_ERROR:
 
4377                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4378                 if (MacType == SK_MAC_XMAC) {
 
4379                         Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
 
4382                         Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
 
4386                  * by default 32bit values are evaluated
 
4389                         Val32 = (SK_U32)Val64;
 
4390                         SK_PNMI_STORE_U32(pBuf, Val32);
 
4391                         *pLen = sizeof(SK_U32);
 
4394                         SK_PNMI_STORE_U64(pBuf, Val64);
 
4395                         *pLen = sizeof(SK_U64);
 
4399         case OID_GEN_RCV_NO_BUFFER:
 
4400                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
4401                 if (MacType == SK_MAC_XMAC) {
 
4402                         Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
 
4405                         Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
 
4409                  * by default 32bit values are evaluated
 
4412                         Val32 = (SK_U32)Val64;
 
4413                         SK_PNMI_STORE_U32(pBuf, Val32);
 
4414                         *pLen = sizeof(SK_U32);
 
4417                         SK_PNMI_STORE_U64(pBuf, Val64);
 
4418                         *pLen = sizeof(SK_U64);
 
4422         case OID_GEN_TRANSMIT_QUEUE_LENGTH:
 
4423                 Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
 
4424                 SK_PNMI_STORE_U32(pBuf, Val32);
 
4425                 *pLen = sizeof(SK_U32);
 
4429                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
 
4433                 return (SK_PNMI_ERR_GENERAL);
 
4436         if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
 
4437                 Id == OID_SKGE_TX_HW_ERROR_CTS ||
 
4438                 Id == OID_SKGE_IN_ERRORS_CTS ||
 
4439                 Id == OID_SKGE_OUT_ERROR_CTS ||
 
4440                 Id == OID_GEN_XMIT_ERROR ||
 
4441                 Id == OID_GEN_RCV_ERROR) {
 
4443                 pAC->Pnmi.MacUpdatedFlag --;
 
4446         return (SK_PNMI_ERR_OK);
 
4449 /*****************************************************************************
 
4451  * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
 
4454  *      Get/Presets/Sets the RLMT OIDs.
 
4457  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
4458  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
4459  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
4460  *                               the correct data (e.g. a 32bit value is
 
4461  *                               needed, but a 16 bit value was passed).
 
4462  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 
4464  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 
4465  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
4466  *                           exist (e.g. port instance 3 on a two port
 
4469 PNMI_STATIC int Rlmt(
 
4470 SK_AC *pAC,             /* Pointer to adapter context */
 
4471 SK_IOC IoC,             /* IO context handle */
 
4472 int Action,             /* GET/PRESET/SET action */
 
4473 SK_U32 Id,              /* Object ID that is to be processed */
 
4474 char *pBuf,             /* Buffer used for the management data transfer */
 
4475 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
4476 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
4477 unsigned int TableIndex, /* Index to the Id table */
 
4478 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
4481         unsigned int    PhysPortIndex;
 
4482         unsigned int    PhysPortMax;
 
4483         SK_EVPARA       EventParam;
 
4489          * Check instance. Only single instance OIDs are allowed here.
 
4491         if (Instance != (SK_U32)(-1) && Instance != 1) {
 
4494                 return (SK_PNMI_ERR_UNKNOWN_INST);
 
4498          * Perform the requested action.
 
4500         if (Action == SK_PNMI_GET) {
 
4503                  * Check if the buffer length is large enough.
 
4508                 case OID_SKGE_RLMT_MODE:
 
4509                 case OID_SKGE_RLMT_PORT_ACTIVE:
 
4510                 case OID_SKGE_RLMT_PORT_PREFERRED:
 
4511                         if (*pLen < sizeof(SK_U8)) {
 
4513                                 *pLen = sizeof(SK_U8);
 
4514                                 return (SK_PNMI_ERR_TOO_SHORT);
 
4518                 case OID_SKGE_RLMT_PORT_NUMBER:
 
4519                         if (*pLen < sizeof(SK_U32)) {
 
4521                                 *pLen = sizeof(SK_U32);
 
4522                                 return (SK_PNMI_ERR_TOO_SHORT);
 
4526                 case OID_SKGE_RLMT_CHANGE_CTS:
 
4527                 case OID_SKGE_RLMT_CHANGE_TIME:
 
4528                 case OID_SKGE_RLMT_CHANGE_ESTIM:
 
4529                 case OID_SKGE_RLMT_CHANGE_THRES:
 
4530                         if (*pLen < sizeof(SK_U64)) {
 
4532                                 *pLen = sizeof(SK_U64);
 
4533                                 return (SK_PNMI_ERR_TOO_SHORT);
 
4538                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
 
4542                         return (SK_PNMI_ERR_GENERAL);
 
4546                  * Update RLMT statistic and increment semaphores to indicate
 
4547                  * that an update was already done. Maybe RLMT will hold its
 
4548                  * statistic always up to date some time. Then we can
 
4549                  * remove this type of call.
 
4551                 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
 
4556                 pAC->Pnmi.RlmtUpdatedFlag ++;
 
4563                 case OID_SKGE_RLMT_MODE:
 
4564                         *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
 
4565                         *pLen = sizeof(char);
 
4568                 case OID_SKGE_RLMT_PORT_NUMBER:
 
4569                         Val32 = (SK_U32)pAC->GIni.GIMacsFound;
 
4570                         SK_PNMI_STORE_U32(pBuf, Val32);
 
4571                         *pLen = sizeof(SK_U32);
 
4574                 case OID_SKGE_RLMT_PORT_ACTIVE:
 
4577                          * If multiple ports may become active this OID
 
4578                          * doesn't make sense any more. A new variable in
 
4579                          * the port structure should be created. However,
 
4580                          * for this variable the first active port is
 
4583                         PhysPortMax = pAC->GIni.GIMacsFound;
 
4585                         for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
 
4588                                 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
 
4590                                         *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
 
4594                         *pLen = sizeof(char);
 
4597                 case OID_SKGE_RLMT_PORT_PREFERRED:
 
4598                         *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
 
4599                         *pLen = sizeof(char);
 
4602                 case OID_SKGE_RLMT_CHANGE_CTS:
 
4603                         Val64 = pAC->Pnmi.RlmtChangeCts;
 
4604                         SK_PNMI_STORE_U64(pBuf, Val64);
 
4605                         *pLen = sizeof(SK_U64);
 
4608                 case OID_SKGE_RLMT_CHANGE_TIME:
 
4609                         Val64 = pAC->Pnmi.RlmtChangeTime;
 
4610                         SK_PNMI_STORE_U64(pBuf, Val64);
 
4611                         *pLen = sizeof(SK_U64);
 
4614                 case OID_SKGE_RLMT_CHANGE_ESTIM:
 
4615                         Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
 
4616                         SK_PNMI_STORE_U64(pBuf, Val64);
 
4617                         *pLen = sizeof(SK_U64);
 
4620                 case OID_SKGE_RLMT_CHANGE_THRES:
 
4621                         Val64 = pAC->Pnmi.RlmtChangeThreshold;
 
4622                         SK_PNMI_STORE_U64(pBuf, Val64);
 
4623                         *pLen = sizeof(SK_U64);
 
4627                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
 
4628                                 ("Rlmt: Unknown OID should be handled before"));
 
4630                         pAC->Pnmi.RlmtUpdatedFlag --;
 
4632                         return (SK_PNMI_ERR_GENERAL);
 
4635                 pAC->Pnmi.RlmtUpdatedFlag --;
 
4638                 /* Perform a preset or set */
 
4641                 case OID_SKGE_RLMT_MODE:
 
4642                         /* Check if the buffer length is plausible */
 
4643                         if (*pLen < sizeof(char)) {
 
4645                                 *pLen = sizeof(char);
 
4646                                 return (SK_PNMI_ERR_TOO_SHORT);
 
4648                         /* Check if the value range is correct */
 
4649                         if (*pLen != sizeof(char) ||
 
4650                                 (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
 
4651                                 *(SK_U8 *)pBuf > 15) {
 
4654                                 return (SK_PNMI_ERR_BAD_VALUE);
 
4656                         /* The preset ends here */
 
4657                         if (Action == SK_PNMI_PRESET) {
 
4660                                 return (SK_PNMI_ERR_OK);
 
4662                         /* Send an event to RLMT to change the mode */
 
4663                         SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
 
4664                         EventParam.Para32[0] |= (SK_U32)(*pBuf);
 
4665                         EventParam.Para32[1] = 0;
 
4666                         if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
 
4669                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
 
4673                                 return (SK_PNMI_ERR_GENERAL);
 
4677                 case OID_SKGE_RLMT_PORT_PREFERRED:
 
4678                         /* Check if the buffer length is plausible */
 
4679                         if (*pLen < sizeof(char)) {
 
4681                                 *pLen = sizeof(char);
 
4682                                 return (SK_PNMI_ERR_TOO_SHORT);
 
4684                         /* Check if the value range is correct */
 
4685                         if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
 
4686                                 (SK_U8)pAC->GIni.GIMacsFound) {
 
4689                                 return (SK_PNMI_ERR_BAD_VALUE);
 
4691                         /* The preset ends here */
 
4692                         if (Action == SK_PNMI_PRESET) {
 
4695                                 return (SK_PNMI_ERR_OK);
 
4699                          * Send an event to RLMT change the preferred port.
 
4700                          * A param of -1 means automatic mode. RLMT will
 
4701                          * make the decision which is the preferred port.
 
4703                         SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
 
4704                         EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
 
4705                         EventParam.Para32[1] = NetIndex;
 
4706                         if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
 
4709                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
 
4713                                 return (SK_PNMI_ERR_GENERAL);
 
4717                 case OID_SKGE_RLMT_CHANGE_THRES:
 
4718                         /* Check if the buffer length is plausible */
 
4719                         if (*pLen < sizeof(SK_U64)) {
 
4721                                 *pLen = sizeof(SK_U64);
 
4722                                 return (SK_PNMI_ERR_TOO_SHORT);
 
4725                          * There are not many restrictions to the
 
4728                         if (*pLen != sizeof(SK_U64)) {
 
4731                                 return (SK_PNMI_ERR_BAD_VALUE);
 
4733                         /* A preset ends here */
 
4734                         if (Action == SK_PNMI_PRESET) {
 
4737                                 return (SK_PNMI_ERR_OK);
 
4740                          * Store the new threshold, which will be taken
 
4741                          * on the next timer event.
 
4743                         SK_PNMI_READ_U64(pBuf, Val64);
 
4744                         pAC->Pnmi.RlmtChangeThreshold = Val64;
 
4748                         /* The other OIDs are not be able for set */
 
4750                         return (SK_PNMI_ERR_READ_ONLY);
 
4754         return (SK_PNMI_ERR_OK);
 
4757 /*****************************************************************************
 
4759  * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
 
4762  *      Performs get requests on multiple instance variables.
 
4765  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
4766  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
4767  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
4768  *                               the correct data (e.g. a 32bit value is
 
4769  *                               needed, but a 16 bit value was passed).
 
4770  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
4771  *                           exist (e.g. port instance 3 on a two port
 
4774 PNMI_STATIC int RlmtStat(
 
4775 SK_AC *pAC,             /* Pointer to adapter context */
 
4776 SK_IOC IoC,             /* IO context handle */
 
4777 int Action,             /* GET/PRESET/SET action */
 
4778 SK_U32 Id,              /* Object ID that is to be processed */
 
4779 char *pBuf,             /* Buffer used for the management data transfer */
 
4780 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
4781 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
4782 unsigned int TableIndex, /* Index to the Id table */
 
4783 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
4785         unsigned int    PhysPortMax;
 
4786         unsigned int    PhysPortIndex;
 
4788         unsigned int    Offset;
 
4794          * Calculate the port indexes from the instance.
 
4796         PhysPortMax = pAC->GIni.GIMacsFound;
 
4798         if ((Instance != (SK_U32)(-1))) {
 
4799                 /* Check instance range */
 
4800                 if ((Instance < 1) || (Instance > PhysPortMax)) {
 
4803                         return (SK_PNMI_ERR_UNKNOWN_INST);
 
4806                 /* Single net mode */
 
4807                 PhysPortIndex = Instance - 1;
 
4810                 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4811                         PhysPortIndex = NetIndex;
 
4814                 /* Both net modes */
 
4815                 Limit = PhysPortIndex + 1;
 
4818                 /* Single net mode */
 
4820                 Limit = PhysPortMax;
 
4823                 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
4824                         PhysPortIndex = NetIndex;
 
4825                         Limit = PhysPortIndex + 1;
 
4830          * Currently only get requests are allowed.
 
4832         if (Action != SK_PNMI_GET) {
 
4835                 return (SK_PNMI_ERR_READ_ONLY);
 
4839          * Check if the buffer length is large enough.
 
4843         case OID_SKGE_RLMT_PORT_INDEX:
 
4844         case OID_SKGE_RLMT_STATUS:
 
4845                 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
 
4847                         *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
 
4848                         return (SK_PNMI_ERR_TOO_SHORT);
 
4852         case OID_SKGE_RLMT_TX_HELLO_CTS:
 
4853         case OID_SKGE_RLMT_RX_HELLO_CTS:
 
4854         case OID_SKGE_RLMT_TX_SP_REQ_CTS:
 
4855         case OID_SKGE_RLMT_RX_SP_CTS:
 
4856                 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
 
4858                         *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
 
4859                         return (SK_PNMI_ERR_TOO_SHORT);
 
4864                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
 
4868                 return (SK_PNMI_ERR_GENERAL);
 
4873          * Update statistic and increment semaphores to indicate that
 
4874          * an update was already done.
 
4876         if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
 
4881         pAC->Pnmi.RlmtUpdatedFlag ++;
 
4887         for (; PhysPortIndex < Limit; PhysPortIndex ++) {
 
4891                 case OID_SKGE_RLMT_PORT_INDEX:
 
4892                         Val32 = PhysPortIndex;
 
4893                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
4894                         Offset += sizeof(SK_U32);
 
4897                 case OID_SKGE_RLMT_STATUS:
 
4898                         if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
 
4900                                 pAC->Rlmt.Port[PhysPortIndex].PortState ==
 
4903                                 Val32 = SK_PNMI_RLMT_STATUS_ERROR;
 
4905                         else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
 
4907                                 Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
 
4910                                 Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
 
4912                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
4913                         Offset += sizeof(SK_U32);
 
4916                 case OID_SKGE_RLMT_TX_HELLO_CTS:
 
4917                         Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
 
4918                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
 
4919                         Offset += sizeof(SK_U64);
 
4922                 case OID_SKGE_RLMT_RX_HELLO_CTS:
 
4923                         Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
 
4924                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
 
4925                         Offset += sizeof(SK_U64);
 
4928                 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
 
4929                         Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
 
4930                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
 
4931                         Offset += sizeof(SK_U64);
 
4934                 case OID_SKGE_RLMT_RX_SP_CTS:
 
4935                         Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
 
4936                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
 
4937                         Offset += sizeof(SK_U64);
 
4941                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
 
4942                                 ("RlmtStat: Unknown OID should be errored before"));
 
4944                         pAC->Pnmi.RlmtUpdatedFlag --;
 
4946                         return (SK_PNMI_ERR_GENERAL);
 
4951         pAC->Pnmi.RlmtUpdatedFlag --;
 
4953         return (SK_PNMI_ERR_OK);
 
4956 /*****************************************************************************
 
4958  * MacPrivateConf - OID handler function of OIDs concerning the configuration
 
4961  *      Get/Presets/Sets the OIDs concerning the configuration.
 
4964  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
4965  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
4966  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
4967  *                               the correct data (e.g. a 32bit value is
 
4968  *                               needed, but a 16 bit value was passed).
 
4969  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 
4971  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 
4972  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
4973  *                           exist (e.g. port instance 3 on a two port
 
4976 PNMI_STATIC int MacPrivateConf(
 
4977 SK_AC *pAC,             /* Pointer to adapter context */
 
4978 SK_IOC IoC,             /* IO context handle */
 
4979 int Action,             /* GET/PRESET/SET action */
 
4980 SK_U32 Id,              /* Object ID that is to be processed */
 
4981 char *pBuf,             /* Buffer used for the management data transfer */
 
4982 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
4983 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
4984 unsigned int TableIndex, /* Index to the Id table */
 
4985 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
4987         unsigned int    PhysPortMax;
 
4988         unsigned int    PhysPortIndex;
 
4989         unsigned int    LogPortMax;
 
4990         unsigned int    LogPortIndex;
 
4992         unsigned int    Offset;
 
4996         SK_EVPARA       EventParam;
 
5000          * Calculate instance if wished. MAC index 0 is the virtual MAC.
 
5002         PhysPortMax = pAC->GIni.GIMacsFound;
 
5003         LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
 
5005         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
 
5009         if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
 
5010                 /* Check instance range */
 
5011                 if ((Instance < 1) || (Instance > LogPortMax)) {
 
5014                         return (SK_PNMI_ERR_UNKNOWN_INST);
 
5016                 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
 
5017                 Limit = LogPortIndex + 1;
 
5020         else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
 
5029         if (Action == SK_PNMI_GET) {
 
5035                 case OID_SKGE_CONNECTOR:
 
5036                 case OID_SKGE_LINK_CAP:
 
5037                 case OID_SKGE_LINK_MODE:
 
5038                 case OID_SKGE_LINK_MODE_STATUS:
 
5039                 case OID_SKGE_LINK_STATUS:
 
5040                 case OID_SKGE_FLOWCTRL_CAP:
 
5041                 case OID_SKGE_FLOWCTRL_MODE:
 
5042                 case OID_SKGE_FLOWCTRL_STATUS:
 
5043                 case OID_SKGE_PHY_OPERATION_CAP:
 
5044                 case OID_SKGE_PHY_OPERATION_MODE:
 
5045                 case OID_SKGE_PHY_OPERATION_STATUS:
 
5046                 case OID_SKGE_SPEED_CAP:
 
5047                 case OID_SKGE_SPEED_MODE:
 
5048                 case OID_SKGE_SPEED_STATUS:
 
5049                         if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
 
5051                                 *pLen = (Limit - LogPortIndex) * sizeof(SK_U8);
 
5052                                 return (SK_PNMI_ERR_TOO_SHORT);
 
5057         case OID_SKGE_PHY_TYPE:
 
5058                         if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) {
 
5060                                 *pLen = (Limit - LogPortIndex) * sizeof(SK_U32);
 
5061                                 return (SK_PNMI_ERR_TOO_SHORT);
 
5066                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
 
5069                         return (SK_PNMI_ERR_GENERAL);
 
5073                  * Update statistic and increment semaphore to indicate
 
5074                  * that an update was already done.
 
5076                 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
 
5081                 pAC->Pnmi.SirqUpdatedFlag ++;
 
5087                 for (; LogPortIndex < Limit; LogPortIndex ++) {
 
5089                         pBufPtr = pBuf + Offset;
 
5094                                 *pBufPtr = pAC->Pnmi.PMD;
 
5095                                 Offset += sizeof(char);
 
5098                         case OID_SKGE_CONNECTOR:
 
5099                                 *pBufPtr = pAC->Pnmi.Connector;
 
5100                                 Offset += sizeof(char);
 
5103                         case OID_SKGE_PHY_TYPE:
 
5104                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5105                                         if (LogPortIndex == 0) {
 
5109                                                 /* Get value for physical ports */
 
5110                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5112                                                 Val32 = pAC->GIni.GP[PhysPortIndex].PhyType;
 
5113                                                 SK_PNMI_STORE_U32(pBufPtr, Val32);
 
5116                                 else { /* DualNetMode */
 
5118                                         Val32 = pAC->GIni.GP[NetIndex].PhyType;
 
5119                                         SK_PNMI_STORE_U32(pBufPtr, Val32);
 
5121                                 Offset += sizeof(SK_U32);
 
5124                         case OID_SKGE_LINK_CAP:
 
5125                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5126                                         if (LogPortIndex == 0) {
 
5127                                                 /* Get value for virtual port */
 
5128                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5131                                                 /* Get value for physical ports */
 
5132                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5135                                                 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkCap;
 
5138                                 else { /* DualNetMode */
 
5140                                         *pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap;
 
5142                                 Offset += sizeof(char);
 
5145                         case OID_SKGE_LINK_MODE:
 
5146                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5147                                         if (LogPortIndex == 0) {
 
5148                                                 /* Get value for virtual port */
 
5149                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5152                                                 /* Get value for physical ports */
 
5153                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5156                                                 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
 
5159                                 else { /* DualNetMode */
 
5161                                         *pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf;
 
5163                                 Offset += sizeof(char);
 
5166                         case OID_SKGE_LINK_MODE_STATUS:
 
5167                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5168                                         if (LogPortIndex == 0) {
 
5169                                                 /* Get value for virtual port */
 
5170                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5173                                                 /* Get value for physical port */
 
5174                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5178                                                         CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
 
5181                                 else { /* DualNetMode */
 
5183                                         *pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex);
 
5185                                 Offset += sizeof(char);
 
5188                         case OID_SKGE_LINK_STATUS:
 
5189                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5190                                         if (LogPortIndex == 0) {
 
5191                                                 /* Get value for virtual port */
 
5192                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5195                                                 /* Get value for physical ports */
 
5196                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5199                                                 *pBufPtr = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
 
5202                                 else { /* DualNetMode */
 
5204                                         *pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex);
 
5206                                 Offset += sizeof(char);
 
5209                         case OID_SKGE_FLOWCTRL_CAP:
 
5210                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5211                                         if (LogPortIndex == 0) {
 
5212                                                 /* Get value for virtual port */
 
5213                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5216                                                 /* Get value for physical ports */
 
5217                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5220                                                 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
 
5223                                 else { /* DualNetMode */
 
5225                                         *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
 
5227                                 Offset += sizeof(char);
 
5230                         case OID_SKGE_FLOWCTRL_MODE:
 
5231                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5232                                         if (LogPortIndex == 0) {
 
5233                                                 /* Get value for virtual port */
 
5234                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5237                                                 /* Get value for physical port */
 
5238                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5241                                                 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
 
5244                                 else { /* DualNetMode */
 
5246                                         *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
 
5248                                 Offset += sizeof(char);
 
5251                         case OID_SKGE_FLOWCTRL_STATUS:
 
5252                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5253                                         if (LogPortIndex == 0) {
 
5254                                                 /* Get value for virtual port */
 
5255                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5258                                                 /* Get value for physical port */
 
5259                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5262                                                 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
 
5265                                 else { /* DualNetMode */
 
5267                                         *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
 
5269                                 Offset += sizeof(char);
 
5272                         case OID_SKGE_PHY_OPERATION_CAP:
 
5273                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5274                                         if (LogPortIndex == 0) {
 
5275                                                 /* Get value for virtual port */
 
5276                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5279                                                 /* Get value for physical ports */
 
5280                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5283                                                 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSCap;
 
5286                                 else { /* DualNetMode */
 
5288                                         *pBufPtr = pAC->GIni.GP[NetIndex].PMSCap;
 
5290                                 Offset += sizeof(char);
 
5293                         case OID_SKGE_PHY_OPERATION_MODE:
 
5294                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5295                                         if (LogPortIndex == 0) {
 
5296                                                 /* Get value for virtual port */
 
5297                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5300                                                 /* Get value for physical port */
 
5301                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5304                                                 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSMode;
 
5307                                 else { /* DualNetMode */
 
5309                                         *pBufPtr = pAC->GIni.GP[NetIndex].PMSMode;
 
5311                                 Offset += sizeof(char);
 
5314                         case OID_SKGE_PHY_OPERATION_STATUS:
 
5315                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5316                                         if (LogPortIndex == 0) {
 
5317                                                 /* Get value for virtual port */
 
5318                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5321                                                 /* Get value for physical port */
 
5322                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5325                                                 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSStatus;
 
5330                                         *pBufPtr = pAC->GIni.GP[NetIndex].PMSStatus;
 
5332                                 Offset += sizeof(char);
 
5335                         case OID_SKGE_SPEED_CAP:
 
5336                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5337                                         if (LogPortIndex == 0) {
 
5338                                                 /* Get value for virtual port */
 
5339                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5342                                                 /* Get value for physical ports */
 
5343                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5346                                                 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedCap;
 
5349                                 else { /* DualNetMode */
 
5351                                         *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
 
5353                                 Offset += sizeof(char);
 
5356                         case OID_SKGE_SPEED_MODE:
 
5357                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5358                                         if (LogPortIndex == 0) {
 
5359                                                 /* Get value for virtual port */
 
5360                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5363                                                 /* Get value for physical port */
 
5364                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5367                                                 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
 
5370                                 else { /* DualNetMode */
 
5372                                         *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed;
 
5374                                 Offset += sizeof(char);
 
5377                         case OID_SKGE_SPEED_STATUS:
 
5378                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 
5379                                         if (LogPortIndex == 0) {
 
5380                                                 /* Get value for virtual port */
 
5381                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
 
5384                                                 /* Get value for physical port */
 
5385                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 
5388                                                 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
 
5391                                 else { /* DualNetMode */
 
5393                                         *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
 
5395                                 Offset += sizeof(char);
 
5399                                 Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
 
5400                                 SK_PNMI_STORE_U32(pBufPtr, Val32);
 
5401                                 Offset += sizeof(SK_U32);
 
5405                                 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
 
5406                                         ("MacPrivateConf: Unknown OID should be handled before"));
 
5408                                 pAC->Pnmi.SirqUpdatedFlag --;
 
5409                                 return (SK_PNMI_ERR_GENERAL);
 
5413                 pAC->Pnmi.SirqUpdatedFlag --;
 
5415                 return (SK_PNMI_ERR_OK);
 
5419          * From here SET or PRESET action. Check if the passed
 
5420          * buffer length is plausible.
 
5424         case OID_SKGE_LINK_MODE:
 
5425         case OID_SKGE_FLOWCTRL_MODE:
 
5426         case OID_SKGE_PHY_OPERATION_MODE:
 
5427         case OID_SKGE_SPEED_MODE:
 
5428                 if (*pLen < Limit - LogPortIndex) {
 
5430                         *pLen = Limit - LogPortIndex;
 
5431                         return (SK_PNMI_ERR_TOO_SHORT);
 
5433                 if (*pLen != Limit - LogPortIndex) {
 
5436                         return (SK_PNMI_ERR_BAD_VALUE);
 
5441                 if (*pLen < sizeof(SK_U32)) {
 
5443                         *pLen = sizeof(SK_U32);
 
5444                         return (SK_PNMI_ERR_TOO_SHORT);
 
5446                 if (*pLen != sizeof(SK_U32)) {
 
5449                         return (SK_PNMI_ERR_BAD_VALUE);
 
5455                 return (SK_PNMI_ERR_READ_ONLY);
 
5459          * Perform preset or set
 
5462         for (; LogPortIndex < Limit; LogPortIndex ++) {
 
5466                 case OID_SKGE_LINK_MODE:
 
5467                         /* Check the value range */
 
5468                         Val8 = *(pBuf + Offset);
 
5471                                 Offset += sizeof(char);
 
5474                         if (Val8 < SK_LMODE_HALF ||
 
5475                                 (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
 
5476                                 (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
 
5479                                 return (SK_PNMI_ERR_BAD_VALUE);
 
5482                         /* The preset ends here */
 
5483                         if (Action == SK_PNMI_PRESET) {
 
5485                                 return (SK_PNMI_ERR_OK);
 
5488                         if (LogPortIndex == 0) {
 
5491                                  * The virtual port consists of all currently
 
5492                                  * active ports. Find them and send an event
 
5493                                  * with the new link mode to SIRQ.
 
5495                                 for (PhysPortIndex = 0;
 
5496                                         PhysPortIndex < PhysPortMax;
 
5499                                         if (!pAC->Pnmi.Port[PhysPortIndex].
 
5505                                         EventParam.Para32[0] = PhysPortIndex;
 
5506                                         EventParam.Para32[1] = (SK_U32)Val8;
 
5507                                         if (SkGeSirqEvent(pAC, IoC,
 
5511                                                 SK_ERR_LOG(pAC, SK_ERRCL_SW,
 
5516                                                 return (SK_PNMI_ERR_GENERAL);
 
5522                                  * Send an event with the new link mode to
 
5525                                 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
 
5527                                 EventParam.Para32[1] = (SK_U32)Val8;
 
5528                                 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
 
5531                                         SK_ERR_LOG(pAC, SK_ERRCL_SW,
 
5536                                         return (SK_PNMI_ERR_GENERAL);
 
5539                         Offset += sizeof(char);
 
5542                 case OID_SKGE_FLOWCTRL_MODE:
 
5543                         /* Check the value range */
 
5544                         Val8 = *(pBuf + Offset);
 
5547                                 Offset += sizeof(char);
 
5550                         if (Val8 < SK_FLOW_MODE_NONE ||
 
5551                                 (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
 
5552                                 (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
 
5555                                 return (SK_PNMI_ERR_BAD_VALUE);
 
5558                         /* The preset ends here */
 
5559                         if (Action == SK_PNMI_PRESET) {
 
5561                                 return (SK_PNMI_ERR_OK);
 
5564                         if (LogPortIndex == 0) {
 
5567                                  * The virtual port consists of all currently
 
5568                                  * active ports. Find them and send an event
 
5569                                  * with the new flow control mode to SIRQ.
 
5571                                 for (PhysPortIndex = 0;
 
5572                                         PhysPortIndex < PhysPortMax;
 
5575                                         if (!pAC->Pnmi.Port[PhysPortIndex].
 
5581                                         EventParam.Para32[0] = PhysPortIndex;
 
5582                                         EventParam.Para32[1] = (SK_U32)Val8;
 
5583                                         if (SkGeSirqEvent(pAC, IoC,
 
5584                                                 SK_HWEV_SET_FLOWMODE,
 
5587                                                 SK_ERR_LOG(pAC, SK_ERRCL_SW,
 
5592                                                 return (SK_PNMI_ERR_GENERAL);
 
5598                                  * Send an event with the new flow control
 
5599                                  * mode to the SIRQ module.
 
5601                                 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
 
5603                                 EventParam.Para32[1] = (SK_U32)Val8;
 
5604                                 if (SkGeSirqEvent(pAC, IoC,
 
5605                                         SK_HWEV_SET_FLOWMODE, EventParam)
 
5608                                         SK_ERR_LOG(pAC, SK_ERRCL_SW,
 
5613                                         return (SK_PNMI_ERR_GENERAL);
 
5616                         Offset += sizeof(char);
 
5619                 case OID_SKGE_PHY_OPERATION_MODE :
 
5620                         /* Check the value range */
 
5621                         Val8 = *(pBuf + Offset);
 
5623                                 /* mode of this port remains unchanged */
 
5624                                 Offset += sizeof(char);
 
5627                         if (Val8 < SK_MS_MODE_AUTO ||
 
5628                                 (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
 
5629                                 (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
 
5632                                 return (SK_PNMI_ERR_BAD_VALUE);
 
5635                         /* The preset ends here */
 
5636                         if (Action == SK_PNMI_PRESET) {
 
5638                                 return (SK_PNMI_ERR_OK);
 
5641                         if (LogPortIndex == 0) {
 
5644                                  * The virtual port consists of all currently
 
5645                                  * active ports. Find them and send an event
 
5646                                  * with new master/slave (role) mode to SIRQ.
 
5648                                 for (PhysPortIndex = 0;
 
5649                                         PhysPortIndex < PhysPortMax;
 
5652                                         if (!pAC->Pnmi.Port[PhysPortIndex].
 
5658                                         EventParam.Para32[0] = PhysPortIndex;
 
5659                                         EventParam.Para32[1] = (SK_U32)Val8;
 
5660                                         if (SkGeSirqEvent(pAC, IoC,
 
5664                                                 SK_ERR_LOG(pAC, SK_ERRCL_SW,
 
5669                                                 return (SK_PNMI_ERR_GENERAL);
 
5675                                  * Send an event with the new master/slave
 
5676                                  * (role) mode to the SIRQ module.
 
5678                                 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
 
5680                                 EventParam.Para32[1] = (SK_U32)Val8;
 
5681                                 if (SkGeSirqEvent(pAC, IoC,
 
5682                                         SK_HWEV_SET_ROLE, EventParam) > 0) {
 
5684                                         SK_ERR_LOG(pAC, SK_ERRCL_SW,
 
5689                                         return (SK_PNMI_ERR_GENERAL);
 
5693                         Offset += sizeof(char);
 
5696                 case OID_SKGE_SPEED_MODE:
 
5697                         /* Check the value range */
 
5698                         Val8 = *(pBuf + Offset);
 
5701                                 Offset += sizeof(char);
 
5704                         if (Val8 < (SK_LSPEED_AUTO) ||
 
5705                                 (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) ||
 
5706                                 (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) {
 
5709                                 return (SK_PNMI_ERR_BAD_VALUE);
 
5712                         /* The preset ends here */
 
5713                         if (Action == SK_PNMI_PRESET) {
 
5715                                 return (SK_PNMI_ERR_OK);
 
5718                         if (LogPortIndex == 0) {
 
5721                                  * The virtual port consists of all currently
 
5722                                  * active ports. Find them and send an event
 
5723                                  * with the new flow control mode to SIRQ.
 
5725                                 for (PhysPortIndex = 0;
 
5726                                         PhysPortIndex < PhysPortMax;
 
5729                                         if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
 
5734                                         EventParam.Para32[0] = PhysPortIndex;
 
5735                                         EventParam.Para32[1] = (SK_U32)Val8;
 
5736                                         if (SkGeSirqEvent(pAC, IoC,
 
5740                                                 SK_ERR_LOG(pAC, SK_ERRCL_SW,
 
5745                                                 return (SK_PNMI_ERR_GENERAL);
 
5751                                  * Send an event with the new flow control
 
5752                                  * mode to the SIRQ module.
 
5754                                 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
 
5756                                 EventParam.Para32[1] = (SK_U32)Val8;
 
5757                                 if (SkGeSirqEvent(pAC, IoC,
 
5761                                         SK_ERR_LOG(pAC, SK_ERRCL_SW,
 
5766                                         return (SK_PNMI_ERR_GENERAL);
 
5769                         Offset += sizeof(char);
 
5773                         /* Check the value range */
 
5774                         Val32 = *(SK_U32*)(pBuf + Offset);
 
5776                                 /* mtu of this port remains unchanged */
 
5777                                 Offset += sizeof(SK_U32);
 
5780                         if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
 
5782                                 return (SK_PNMI_ERR_BAD_VALUE);
 
5785                         /* The preset ends here */
 
5786                         if (Action == SK_PNMI_PRESET) {
 
5787                                 return (SK_PNMI_ERR_OK);
 
5790                         if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
 
5791                                 return (SK_PNMI_ERR_GENERAL);
 
5794                         Offset += sizeof(SK_U32);
 
5798             SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
 
5799                 ("MacPrivateConf: Unknown OID should be handled before set"));
 
5802                         return (SK_PNMI_ERR_GENERAL);
 
5806         return (SK_PNMI_ERR_OK);
 
5809 /*****************************************************************************
 
5811  * Monitor - OID handler function for RLMT_MONITOR_XXX
 
5814  *      Because RLMT currently does not support the monitoring of
 
5815  *      remote adapter cards, we return always an empty table.
 
5818  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
5819  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
5820  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
5821  *                               the correct data (e.g. a 32bit value is
 
5822  *                               needed, but a 16 bit value was passed).
 
5823  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
 
5825  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
 
5826  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
5827  *                           exist (e.g. port instance 3 on a two port
 
5830 PNMI_STATIC int Monitor(
 
5831 SK_AC *pAC,             /* Pointer to adapter context */
 
5832 SK_IOC IoC,             /* IO context handle */
 
5833 int Action,             /* GET/PRESET/SET action */
 
5834 SK_U32 Id,              /* Object ID that is to be processed */
 
5835 char *pBuf,             /* Buffer used for the management data transfer */
 
5836 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
5837 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
5838 unsigned int TableIndex, /* Index to the Id table */
 
5839 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
5843         unsigned int    Offset;
 
5844         unsigned int    Entries;
 
5848          * Calculate instance if wished.
 
5850         /* XXX Not yet implemented. Return always an empty table. */
 
5853         if ((Instance != (SK_U32)(-1))) {
 
5855                 if ((Instance < 1) || (Instance > Entries)) {
 
5858                         return (SK_PNMI_ERR_UNKNOWN_INST);
 
5861                 Index = (unsigned int)Instance - 1;
 
5862                 Limit = (unsigned int)Instance;
 
5872         if (Action == SK_PNMI_GET) {
 
5874                 for (Offset=0; Index < Limit; Index ++) {
 
5878                         case OID_SKGE_RLMT_MONITOR_INDEX:
 
5879                         case OID_SKGE_RLMT_MONITOR_ADDR:
 
5880                         case OID_SKGE_RLMT_MONITOR_ERRS:
 
5881                         case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
 
5882                         case OID_SKGE_RLMT_MONITOR_ADMIN:
 
5886                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
 
5890                                 return (SK_PNMI_ERR_GENERAL);
 
5896                 /* Only MONITOR_ADMIN can be set */
 
5897                 if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
 
5900                         return (SK_PNMI_ERR_READ_ONLY);
 
5903                 /* Check if the length is plausible */
 
5904                 if (*pLen < (Limit - Index)) {
 
5906                         return (SK_PNMI_ERR_TOO_SHORT);
 
5908                 /* Okay, we have a wide value range */
 
5909                 if (*pLen != (Limit - Index)) {
 
5912                         return (SK_PNMI_ERR_BAD_VALUE);
 
5915                 for (Offset=0; Index < Limit; Index ++) {
 
5919  * XXX Not yet implemented. Return always BAD_VALUE, because the table
 
5923                 return (SK_PNMI_ERR_BAD_VALUE);
 
5926         return (SK_PNMI_ERR_OK);
 
5929 /*****************************************************************************
 
5931  * VirtualConf - Calculates the values of configuration OIDs for virtual port
 
5934  *      We handle here the get of the configuration group OIDs, which are
 
5935  *      a little bit complicated. The virtual port consists of all currently
 
5936  *      active physical ports. If multiple ports are active and configured
 
5937  *      differently we get in some trouble to return a single value. So we
 
5938  *      get the value of the first active port and compare it with that of
 
5939  *      the other active ports. If they are not the same, we return a value
 
5940  *      that indicates that the state is indeterminated.
 
5945 PNMI_STATIC void VirtualConf(
 
5946 SK_AC *pAC,             /* Pointer to adapter context */
 
5947 SK_IOC IoC,             /* IO context handle */
 
5948 SK_U32 Id,              /* Object ID that is to be processed */
 
5949 char *pBuf)             /* Buffer used for the management data transfer */
 
5951         unsigned int    PhysPortMax;
 
5952         unsigned int    PhysPortIndex;
 
5955         SK_BOOL         PortActiveFlag;
 
5959         PortActiveFlag = SK_FALSE;
 
5960         PhysPortMax = pAC->GIni.GIMacsFound;
 
5962         for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
 
5965                 pPrt = &pAC->GIni.GP[PhysPortIndex];
 
5967                 /* Check if the physical port is active */
 
5968                 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
 
5973                 PortActiveFlag = SK_TRUE;
 
5977                 case OID_SKGE_PHY_TYPE:
 
5978                         /* Check if it is the first active port */
 
5980                                 Val32 = pPrt->PhyType;
 
5981                                 SK_PNMI_STORE_U32(pBuf, Val32);
 
5985                 case OID_SKGE_LINK_CAP:
 
5988                          * Different capabilities should not happen, but
 
5989                          * in the case of the cases OR them all together.
 
5990                          * From a curious point of view the virtual port
 
5991                          * is capable of all found capabilities.
 
5993                         *pBuf |= pPrt->PLinkCap;
 
5996                 case OID_SKGE_LINK_MODE:
 
5997                         /* Check if it is the first active port */
 
6000                                 *pBuf = pPrt->PLinkModeConf;
 
6005                          * If we find an active port with a different link
 
6006                          * mode than the first one we return a value that
 
6007                          * indicates that the link mode is indeterminated.
 
6009                         if (*pBuf != pPrt->PLinkModeConf) {
 
6011                                 *pBuf = SK_LMODE_INDETERMINATED;
 
6015                 case OID_SKGE_LINK_MODE_STATUS:
 
6016                         /* Get the link mode of the physical port */
 
6017                         Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
 
6019                         /* Check if it is the first active port */
 
6027                          * If we find an active port with a different link
 
6028                          * mode status than the first one we return a value
 
6029                          * that indicates that the link mode status is
 
6032                         if (*pBuf != Val8) {
 
6034                                 *pBuf = SK_LMODE_STAT_INDETERMINATED;
 
6038                 case OID_SKGE_LINK_STATUS:
 
6039                         /* Get the link status of the physical port */
 
6040                         Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
 
6042                         /* Check if it is the first active port */
 
6050                          * If we find an active port with a different link
 
6051                          * status than the first one, we return a value
 
6052                          * that indicates that the link status is
 
6055                         if (*pBuf != Val8) {
 
6057                                 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
 
6061                 case OID_SKGE_FLOWCTRL_CAP:
 
6062                         /* Check if it is the first active port */
 
6065                                 *pBuf = pPrt->PFlowCtrlCap;
 
6070                          * From a curious point of view the virtual port
 
6071                          * is capable of all found capabilities.
 
6073                         *pBuf |= pPrt->PFlowCtrlCap;
 
6076                 case OID_SKGE_FLOWCTRL_MODE:
 
6077                         /* Check if it is the first active port */
 
6080                                 *pBuf = pPrt->PFlowCtrlMode;
 
6085                          * If we find an active port with a different flow
 
6086                          * control mode than the first one, we return a value
 
6087                          * that indicates that the mode is indeterminated.
 
6089                         if (*pBuf != pPrt->PFlowCtrlMode) {
 
6091                                 *pBuf = SK_FLOW_MODE_INDETERMINATED;
 
6095                 case OID_SKGE_FLOWCTRL_STATUS:
 
6096                         /* Check if it is the first active port */
 
6099                                 *pBuf = pPrt->PFlowCtrlStatus;
 
6104                          * If we find an active port with a different flow
 
6105                          * control status than the first one, we return a
 
6106                          * value that indicates that the status is
 
6109                         if (*pBuf != pPrt->PFlowCtrlStatus) {
 
6111                                 *pBuf = SK_FLOW_STAT_INDETERMINATED;
 
6115                 case OID_SKGE_PHY_OPERATION_CAP:
 
6116                         /* Check if it is the first active port */
 
6119                                 *pBuf = pPrt->PMSCap;
 
6124                          * From a curious point of view the virtual port
 
6125                          * is capable of all found capabilities.
 
6127                         *pBuf |= pPrt->PMSCap;
 
6130                 case OID_SKGE_PHY_OPERATION_MODE:
 
6131                         /* Check if it is the first active port */
 
6134                                 *pBuf = pPrt->PMSMode;
 
6139                          * If we find an active port with a different master/
 
6140                          * slave mode than the first one, we return a value
 
6141                          * that indicates that the mode is indeterminated.
 
6143                         if (*pBuf != pPrt->PMSMode) {
 
6145                                 *pBuf = SK_MS_MODE_INDETERMINATED;
 
6149                 case OID_SKGE_PHY_OPERATION_STATUS:
 
6150                         /* Check if it is the first active port */
 
6153                                 *pBuf = pPrt->PMSStatus;
 
6158                          * If we find an active port with a different master/
 
6159                          * slave status than the first one, we return a
 
6160                          * value that indicates that the status is
 
6163                         if (*pBuf != pPrt->PMSStatus) {
 
6165                                 *pBuf = SK_MS_STAT_INDETERMINATED;
 
6169                 case OID_SKGE_SPEED_MODE:
 
6170                         /* Check if it is the first active port */
 
6173                                 *pBuf = pPrt->PLinkSpeed;
 
6178                          * If we find an active port with a different flow
 
6179                          * control mode than the first one, we return a value
 
6180                          * that indicates that the mode is indeterminated.
 
6182                         if (*pBuf != pPrt->PLinkSpeed) {
 
6184                                 *pBuf = SK_LSPEED_INDETERMINATED;
 
6188                 case OID_SKGE_SPEED_STATUS:
 
6189                         /* Check if it is the first active port */
 
6192                                 *pBuf = pPrt->PLinkSpeedUsed;
 
6197                          * If we find an active port with a different flow
 
6198                          * control status than the first one, we return a
 
6199                          * value that indicates that the status is
 
6202                         if (*pBuf != pPrt->PLinkSpeedUsed) {
 
6204                                 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
 
6211          * If no port is active return an indeterminated answer
 
6213         if (!PortActiveFlag) {
 
6217                 case OID_SKGE_LINK_CAP:
 
6218                         *pBuf = SK_LMODE_CAP_INDETERMINATED;
 
6221                 case OID_SKGE_LINK_MODE:
 
6222                         *pBuf = SK_LMODE_INDETERMINATED;
 
6225                 case OID_SKGE_LINK_MODE_STATUS:
 
6226                         *pBuf = SK_LMODE_STAT_INDETERMINATED;
 
6229                 case OID_SKGE_LINK_STATUS:
 
6230                         *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
 
6233                 case OID_SKGE_FLOWCTRL_CAP:
 
6234                 case OID_SKGE_FLOWCTRL_MODE:
 
6235                         *pBuf = SK_FLOW_MODE_INDETERMINATED;
 
6238                 case OID_SKGE_FLOWCTRL_STATUS:
 
6239                         *pBuf = SK_FLOW_STAT_INDETERMINATED;
 
6242                 case OID_SKGE_PHY_OPERATION_CAP:
 
6243                         *pBuf = SK_MS_CAP_INDETERMINATED;
 
6246                 case OID_SKGE_PHY_OPERATION_MODE:
 
6247                         *pBuf = SK_MS_MODE_INDETERMINATED;
 
6250                 case OID_SKGE_PHY_OPERATION_STATUS:
 
6251                         *pBuf = SK_MS_STAT_INDETERMINATED;
 
6253                 case OID_SKGE_SPEED_CAP:
 
6254                         *pBuf = SK_LSPEED_CAP_INDETERMINATED;
 
6257                 case OID_SKGE_SPEED_MODE:
 
6258                         *pBuf = SK_LSPEED_INDETERMINATED;
 
6261                 case OID_SKGE_SPEED_STATUS:
 
6262                         *pBuf = SK_LSPEED_STAT_INDETERMINATED;
 
6268 /*****************************************************************************
 
6270  * CalculateLinkStatus - Determins the link status of a physical port
 
6273  *      Determins the link status the following way:
 
6274  *        LSTAT_PHY_DOWN:  Link is down
 
6275  *        LSTAT_AUTONEG:   Auto-negotiation failed
 
6276  *        LSTAT_LOG_DOWN:  Link is up but RLMT did not yet put the port
 
6278  *        LSTAT_LOG_UP:    RLMT marked the port as up
 
6281  *      Link status of physical port
 
6283 PNMI_STATIC SK_U8 CalculateLinkStatus(
 
6284 SK_AC *pAC,                     /* Pointer to adapter context */
 
6285 SK_IOC IoC,                     /* IO context handle */
 
6286 unsigned int PhysPortIndex)     /* Physical port index */
 
6290         if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
 
6292                 Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
 
6294         else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
 
6296                 Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
 
6298         else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
 
6300                 Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
 
6303                 Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
 
6309 /*****************************************************************************
 
6311  * CalculateLinkModeStatus - Determins the link mode status of a phys. port
 
6314  *      The COMMON module only tells us if the mode is half or full duplex.
 
6315  *      But in the decade of auto sensing it is useful for the user to
 
6316  *      know if the mode was negotiated or forced. Therefore we have a
 
6317  *      look to the mode, which was last used by the negotiation process.
 
6320  *      The link mode status
 
6322 PNMI_STATIC SK_U8 CalculateLinkModeStatus(
 
6323 SK_AC *pAC,                     /* Pointer to adapter context */
 
6324 SK_IOC IoC,                     /* IO context handle */
 
6325 unsigned int PhysPortIndex)     /* Physical port index */
 
6329         /* Get the current mode, which can be full or half duplex */
 
6330         Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
 
6332         /* Check if no valid mode could be found (link is down) */
 
6333         if (Result < SK_LMODE_STAT_HALF) {
 
6335                 Result = SK_LMODE_STAT_UNKNOWN;
 
6337         else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
 
6340                  * Auto-negotiation was used to bring up the link. Change
 
6341                  * the already found duplex status that it indicates
 
6342                  * auto-negotiation was involved.
 
6344                 if (Result == SK_LMODE_STAT_HALF) {
 
6346                         Result = SK_LMODE_STAT_AUTOHALF;
 
6348                 else if (Result == SK_LMODE_STAT_FULL) {
 
6350                         Result = SK_LMODE_STAT_AUTOFULL;
 
6357 /*****************************************************************************
 
6359  * GetVpdKeyArr - Obtain an array of VPD keys
 
6362  *      Read the VPD keys and build an array of VPD keys, which are
 
6366  *      SK_PNMI_ERR_OK       Task successfully performed.
 
6367  *      SK_PNMI_ERR_GENERAL  Something went wrong.
 
6369 PNMI_STATIC int GetVpdKeyArr(
 
6370 SK_AC *pAC,             /* Pointer to adapter context */
 
6371 SK_IOC IoC,             /* IO context handle */
 
6372 char *pKeyArr,          /* Ptr KeyArray */
 
6373 unsigned int KeyArrLen, /* Length of array in bytes */
 
6374 unsigned int *pKeyNo)   /* Number of keys */
 
6376         unsigned int            BufKeysLen = SK_PNMI_VPD_BUFSIZE;
 
6377         char                    BufKeys[SK_PNMI_VPD_BUFSIZE];
 
6378         unsigned int            StartOffset;
 
6379         unsigned int            Offset;
 
6384         SK_MEMSET(pKeyArr, 0, KeyArrLen);
 
6389         Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
 
6393                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
 
6396                 return (SK_PNMI_ERR_GENERAL);
 
6398         /* If no keys are available return now */
 
6399         if (*pKeyNo == 0 || BufKeysLen == 0) {
 
6401                 return (SK_PNMI_ERR_OK);
 
6404          * If the key list is too long for us trunc it and give a
 
6405          * errorlog notification. This case should not happen because
 
6406          * the maximum number of keys is limited due to RAM limitations
 
6408         if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
 
6410                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
 
6413                 *pKeyNo = SK_PNMI_VPD_ENTRIES;
 
6417          * Now build an array of fixed string length size and copy
 
6418          * the keys together.
 
6420         for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
 
6423                 if (BufKeys[Offset] != 0) {
 
6428                 if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
 
6430                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
 
6432                         return (SK_PNMI_ERR_GENERAL);
 
6435                 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
 
6436                         &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
 
6439                 StartOffset = Offset + 1;
 
6442         /* Last key not zero terminated? Get it anyway */
 
6443         if (StartOffset < Offset) {
 
6445                 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
 
6446                         &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
 
6449         return (SK_PNMI_ERR_OK);
 
6452 /*****************************************************************************
 
6454  * SirqUpdate - Let the SIRQ update its internal values
 
6457  *      Just to be sure that the SIRQ module holds its internal data
 
6458  *      structures up to date, we send an update event before we make
 
6462  *      SK_PNMI_ERR_OK       Task successfully performed.
 
6463  *      SK_PNMI_ERR_GENERAL  Something went wrong.
 
6465 PNMI_STATIC int SirqUpdate(
 
6466 SK_AC *pAC,     /* Pointer to adapter context */
 
6467 SK_IOC IoC)     /* IO context handle */
 
6469         SK_EVPARA       EventParam;
 
6472         /* Was the module already updated during the current PNMI call? */
 
6473         if (pAC->Pnmi.SirqUpdatedFlag > 0) {
 
6475                 return (SK_PNMI_ERR_OK);
 
6478         /* Send an synchronuous update event to the module */
 
6479         SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
 
6480         if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
 
6482                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
 
6485                 return (SK_PNMI_ERR_GENERAL);
 
6488         return (SK_PNMI_ERR_OK);
 
6491 /*****************************************************************************
 
6493  * RlmtUpdate - Let the RLMT update its internal values
 
6496  *      Just to be sure that the RLMT module holds its internal data
 
6497  *      structures up to date, we send an update event before we make
 
6501  *      SK_PNMI_ERR_OK       Task successfully performed.
 
6502  *      SK_PNMI_ERR_GENERAL  Something went wrong.
 
6504 PNMI_STATIC int RlmtUpdate(
 
6505 SK_AC *pAC,     /* Pointer to adapter context */
 
6506 SK_IOC IoC,     /* IO context handle */
 
6507 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode allways zero */
 
6509         SK_EVPARA       EventParam;
 
6512         /* Was the module already updated during the current PNMI call? */
 
6513         if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
 
6515                 return (SK_PNMI_ERR_OK);
 
6518         /* Send an synchronuous update event to the module */
 
6519         SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
 
6520         EventParam.Para32[0] = NetIndex;
 
6521         EventParam.Para32[1] = (SK_U32)-1;
 
6522         if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
 
6524                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
 
6527                 return (SK_PNMI_ERR_GENERAL);
 
6530         return (SK_PNMI_ERR_OK);
 
6533 /*****************************************************************************
 
6535  * MacUpdate - Force the XMAC to output the current statistic
 
6538  *      The XMAC holds its statistic internally. To obtain the current
 
6539  *      values we must send a command so that the statistic data will
 
6540  *      be written to a predefined memory area on the adapter.
 
6543  *      SK_PNMI_ERR_OK       Task successfully performed.
 
6544  *      SK_PNMI_ERR_GENERAL  Something went wrong.
 
6546 PNMI_STATIC int MacUpdate(
 
6547 SK_AC *pAC,             /* Pointer to adapter context */
 
6548 SK_IOC IoC,             /* IO context handle */
 
6549 unsigned int FirstMac,  /* Index of the first Mac to be updated */
 
6550 unsigned int LastMac)   /* Index of the last Mac to be updated */
 
6552         unsigned int    MacIndex;
 
6555          * Were the statistics already updated during the
 
6556          * current PNMI call?
 
6558         if (pAC->Pnmi.MacUpdatedFlag > 0) {
 
6560                 return (SK_PNMI_ERR_OK);
 
6563         /* Send an update command to all MACs specified */
 
6564         for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
 
6567                  * 2002-09-13 pweber:   Freeze the current SW counters.
 
6568                  *                      (That should be done as close as
 
6569                  *                      possible to the update of the
 
6572                 if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
 
6573                         pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
 
6576                 /* 2002-09-13 pweber:  Update the HW counter  */
 
6577                 if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
 
6579                         return (SK_PNMI_ERR_GENERAL);
 
6583         return (SK_PNMI_ERR_OK);
 
6586 /*****************************************************************************
 
6588  * GetStatVal - Retrieve an XMAC statistic counter
 
6591  *      Retrieves the statistic counter of a virtual or physical port. The
 
6592  *      virtual port is identified by the index 0. It consists of all
 
6593  *      currently active ports. To obtain the counter value for this port
 
6594  *      we must add the statistic counter of all active ports. To grant
 
6595  *      continuous counter values for the virtual port even when port
 
6596  *      switches occur we must additionally add a delta value, which was
 
6597  *      calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
 
6600  *      Requested statistic value
 
6602 PNMI_STATIC SK_U64 GetStatVal(
 
6603 SK_AC *pAC,                                     /* Pointer to adapter context */
 
6604 SK_IOC IoC,                                     /* IO context handle */
 
6605 unsigned int LogPortIndex,      /* Index of the logical Port to be processed */
 
6606 unsigned int StatIndex,         /* Index to statistic value */
 
6607 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode allways zero */
 
6609         unsigned int    PhysPortIndex;
 
6610         unsigned int    PhysPortMax;
 
6614         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {   /* Dual net mode */
 
6616                 PhysPortIndex = NetIndex;
 
6618                 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
 
6620         else {  /* Single Net mode */
 
6622                 if (LogPortIndex == 0) {
 
6624                         PhysPortMax = pAC->GIni.GIMacsFound;
 
6626                         /* Add counter of all active ports */
 
6627                         for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
 
6630                                 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
 
6632                                         Val += GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
 
6636                         /* Correct value because of port switches */
 
6637                         Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
 
6640                         /* Get counter value of physical port */
 
6641                         PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
 
6643                         Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
 
6649 /*****************************************************************************
 
6651  * GetPhysStatVal - Get counter value for physical port
 
6654  *      Builds a 64bit counter value. Except for the octet counters
 
6655  *      the lower 32bit are counted in hardware and the upper 32bit
 
6656  *      in software by monitoring counter overflow interrupts in the
 
6657  *      event handler. To grant continous counter values during XMAC
 
6658  *      resets (caused by a workaround) we must add a delta value.
 
6659  *      The delta was calculated in the event handler when a
 
6660  *      SK_PNMI_EVT_XMAC_RESET was received.
 
6665 PNMI_STATIC SK_U64 GetPhysStatVal(
 
6666 SK_AC *pAC,                                     /* Pointer to adapter context */
 
6667 SK_IOC IoC,                                     /* IO context handle */
 
6668 unsigned int PhysPortIndex,     /* Index of the logical Port to be processed */
 
6669 unsigned int StatIndex)         /* Index to statistic value */
 
6676         unsigned int HelpIndex;
 
6679         SK_PNMI_PORT    *pPnmiPrt;
 
6680         SK_GEMACFUNC    *pFnMac;
 
6682         pPrt = &pAC->GIni.GP[PhysPortIndex];
 
6684         MacType = pAC->GIni.GIMacType;
 
6686         /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
 
6687         if (MacType == SK_MAC_XMAC) {
 
6688                 pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
 
6691                 pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex];
 
6694         pFnMac   = &pAC->GIni.GIFunc;
 
6696         switch (StatIndex) {
 
6698                 if (MacType == SK_MAC_GMAC) {
 
6699                         (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6700                                                         StatAddr[SK_PNMI_HTX_BROADCAST][MacType].Reg,
 
6702                         (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6703                                                         StatAddr[SK_PNMI_HTX_MULTICAST][MacType].Reg,
 
6706                         (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6707                                                         StatAddr[SK_PNMI_HTX_UNICAST][MacType].Reg,
 
6712                         (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6713                                                                                   StatAddr[StatIndex][MacType].Reg,
 
6716                 HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6720                 if (MacType == SK_MAC_GMAC) {
 
6721                         (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6722                                                         StatAddr[SK_PNMI_HRX_BROADCAST][MacType].Reg,
 
6724                         (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6725                                                         StatAddr[SK_PNMI_HRX_MULTICAST][MacType].Reg,
 
6728                         (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6729                                                         StatAddr[SK_PNMI_HRX_UNICAST][MacType].Reg,
 
6734                         (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6735                                                                                   StatAddr[StatIndex][MacType].Reg,
 
6738                 HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6741         case SK_PNMI_HTX_OCTET:
 
6742         case SK_PNMI_HRX_OCTET:
 
6743                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6744                                                                           StatAddr[StatIndex][MacType].Reg,
 
6746                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6747                                                                           StatAddr[StatIndex + 1][MacType].Reg,
 
6751         case SK_PNMI_HTX_BURST:
 
6752         case SK_PNMI_HTX_EXCESS_DEF:
 
6753         case SK_PNMI_HTX_CARRIER:
 
6754                 /* Not supported by GMAC */
 
6755                 if (MacType == SK_MAC_GMAC) {
 
6759                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6760                                                                           StatAddr[StatIndex][MacType].Reg,
 
6762                 HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6765         case SK_PNMI_HTX_MACC:
 
6766                 /* GMAC only supports PAUSE MAC control frames */
 
6767                 if (MacType == SK_MAC_GMAC) {
 
6768                         HelpIndex = SK_PNMI_HTX_PMACC;
 
6771                         HelpIndex = StatIndex;
 
6774                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6775                                                                 StatAddr[HelpIndex][MacType].Reg,
 
6778                 HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6781         case SK_PNMI_HTX_COL:
 
6782         case SK_PNMI_HRX_UNDERSIZE:
 
6783                 /* Not supported by XMAC */
 
6784                 if (MacType == SK_MAC_XMAC) {
 
6788                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6789                                                                           StatAddr[StatIndex][MacType].Reg,
 
6791                 HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6794         case SK_PNMI_HTX_DEFFERAL:
 
6795                 /* Not supported by GMAC */
 
6796                 if (MacType == SK_MAC_GMAC) {
 
6801                  * XMAC counts frames with deferred transmission
 
6802                  * even in full-duplex mode.
 
6804                  * In full-duplex mode the counter remains constant!
 
6806                 if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) ||
 
6807                         (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL)) {
 
6813                         /* Otherwise get contents of hardware register */
 
6814                         (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6815                                                                                   StatAddr[StatIndex][MacType].Reg,
 
6817                         HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6821         case SK_PNMI_HRX_BADOCTET:
 
6822                 /* Not supported by XMAC */
 
6823                 if (MacType == SK_MAC_XMAC) {
 
6827                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6828                                                                           StatAddr[StatIndex][MacType].Reg,
 
6830                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6831                                                                           StatAddr[StatIndex + 1][MacType].Reg,
 
6835         case SK_PNMI_HTX_OCTETLOW:
 
6836         case SK_PNMI_HRX_OCTETLOW:
 
6837         case SK_PNMI_HRX_BADOCTETLOW:
 
6840         case SK_PNMI_HRX_LONGFRAMES:
 
6841                 /* For XMAC the SW counter is managed by PNMI */
 
6842                 if (MacType == SK_MAC_XMAC) {
 
6843                         return (pPnmiPrt->StatRxLongFrameCts);
 
6846                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6847                                                                           StatAddr[StatIndex][MacType].Reg,
 
6849                 HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6852         case SK_PNMI_HRX_TOO_LONG:
 
6853                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6854                                                                 StatAddr[StatIndex][MacType].Reg,
 
6856                 HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6858                 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
 
6860                 if (MacType == SK_MAC_GMAC) {
 
6861                         /* For GMAC the SW counter is additionally managed by PNMI */
 
6862                         Val += pPnmiPrt->StatRxFrameTooLongCts;
 
6866                          * Frames longer than IEEE 802.3 frame max size are counted
 
6867                          * by XMAC in frame_too_long counter even reception of long
 
6868                          * frames was enabled and the frame was correct.
 
6869                          * So correct the value by subtracting RxLongFrame counter.
 
6871                         Val -= pPnmiPrt->StatRxLongFrameCts;
 
6874                 LowVal = (SK_U32)Val;
 
6875                 HighVal = (SK_U32)(Val >> 32);
 
6878         case SK_PNMI_HRX_SHORTS:
 
6879                 /* Not supported by GMAC */
 
6880                 if (MacType == SK_MAC_GMAC) {
 
6886                  * XMAC counts short frame errors even if link down (#10620)
 
6888                  * If link-down the counter remains constant
 
6890                 if (pPrt->PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
 
6892                         /* Otherwise get incremental difference */
 
6893                         (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6894                                                                                   StatAddr[StatIndex][MacType].Reg,
 
6896                         HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6898                         Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
 
6899                         Val -= pPnmiPrt->RxShortZeroMark;
 
6901                         LowVal = (SK_U32)Val;
 
6902                         HighVal = (SK_U32)(Val >> 32);
 
6906         case SK_PNMI_HRX_MACC:
 
6907         case SK_PNMI_HRX_MACC_UNKWN:
 
6908         case SK_PNMI_HRX_BURST:
 
6909         case SK_PNMI_HRX_MISSED:
 
6910         case SK_PNMI_HRX_FRAMING:
 
6911         case SK_PNMI_HRX_CARRIER:
 
6912         case SK_PNMI_HRX_IRLENGTH:
 
6913         case SK_PNMI_HRX_SYMBOL:
 
6914         case SK_PNMI_HRX_CEXT:
 
6915                 /* Not supported by GMAC */
 
6916                 if (MacType == SK_MAC_GMAC) {
 
6920                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6921                                                                           StatAddr[StatIndex][MacType].Reg,
 
6923                 HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6926         case SK_PNMI_HRX_PMACC_ERR:
 
6927                 /* For GMAC the SW counter is managed by PNMI */
 
6928                 if (MacType == SK_MAC_GMAC) {
 
6929                         return (pPnmiPrt->StatRxPMaccErr);
 
6932                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6933                                                                           StatAddr[StatIndex][MacType].Reg,
 
6935                 HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6938         /* SW counter managed by PNMI */
 
6939         case SK_PNMI_HTX_SYNC:
 
6940                 LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
 
6941                 HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
 
6944         /* SW counter managed by PNMI */
 
6945         case SK_PNMI_HTX_SYNC_OCTET:
 
6946                 LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
 
6947                 HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
 
6950         case SK_PNMI_HRX_FCS:
 
6952                  * Broadcom filters FCS errors and counts it in
 
6953                  * Receive Error Counter register
 
6955                 if (pPrt->PhyType == SK_PHY_BCOM) {
 
6956                         /* do not read while not initialized (PHY_READ hangs!)*/
 
6957                         if (pPrt->PState != SK_PRT_RESET) {
 
6958                                 SkXmPhyRead(pAC, IoC, PhysPortIndex, PHY_BCOM_RE_CTR, &Word);
 
6962                         HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6965                         (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6966                                                                                   StatAddr[StatIndex][MacType].Reg,
 
6968                         HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6973                 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 
6974                                                                           StatAddr[StatIndex][MacType].Reg,
 
6976                 HighVal = pPnmiPrt->CounterHigh[StatIndex];
 
6980         Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
 
6982         /* Correct value because of possible XMAC reset. XMAC Errata #2 */
 
6983         Val += pPnmiPrt->CounterOffset[StatIndex];
 
6988 /*****************************************************************************
 
6990  * ResetCounter - Set all counters and timestamps to zero
 
6993  *      Notifies other common modules which store statistic data to
 
6994  *      reset their counters and finally reset our own counters.
 
6999 PNMI_STATIC void ResetCounter(
 
7000 SK_AC *pAC,             /* Pointer to adapter context */
 
7001 SK_IOC IoC,             /* IO context handle */
 
7004         unsigned int    PhysPortIndex;
 
7005         SK_EVPARA       EventParam;
 
7008         SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
 
7010         /* Notify sensor module */
 
7011         SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
 
7013         /* Notify RLMT module */
 
7014         EventParam.Para32[0] = NetIndex;
 
7015         EventParam.Para32[1] = (SK_U32)-1;
 
7016         SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
 
7017         EventParam.Para32[1] = 0;
 
7019         /* Notify SIRQ module */
 
7020         SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
 
7022         /* Notify CSUM module */
 
7024         EventParam.Para32[0] = NetIndex;
 
7025         EventParam.Para32[1] = (SK_U32)-1;
 
7026         SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
 
7028 #endif /* SK_USE_CSUM */
 
7030         /* Clear XMAC statistic */
 
7031         for (PhysPortIndex = 0; PhysPortIndex <
 
7032                 (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
 
7034                 (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex);
 
7036                 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
 
7037                         0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
 
7038                 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
 
7039                         CounterOffset, 0, sizeof(pAC->Pnmi.Port[
 
7040                         PhysPortIndex].CounterOffset));
 
7041                 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
 
7042                         0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
 
7043                 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
 
7044                         StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
 
7045                         PhysPortIndex].StatSyncOctetsCts));
 
7046                 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
 
7047                         StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
 
7048                         PhysPortIndex].StatRxLongFrameCts));
 
7049                 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
 
7050                                   StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[
 
7051                         PhysPortIndex].StatRxFrameTooLongCts));
 
7052                 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
 
7053                                   StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[
 
7054                         PhysPortIndex].StatRxPMaccErr));
 
7058          * Clear local statistics
 
7060         SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
 
7061                   sizeof(pAC->Pnmi.VirtualCounterOffset));
 
7062         pAC->Pnmi.RlmtChangeCts = 0;
 
7063         pAC->Pnmi.RlmtChangeTime = 0;
 
7064         SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
 
7065                 sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
 
7066         pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
 
7067         pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
 
7068         pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
 
7069         pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
 
7070         pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
 
7071         pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
 
7072         pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
 
7073         pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
 
7074         pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
 
7075         pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
 
7076         pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
 
7077         pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
 
7080 /*****************************************************************************
 
7082  * GetTrapEntry - Get an entry in the trap buffer
 
7085  *      The trap buffer stores various events. A user application somehow
 
7086  *      gets notified that an event occured and retrieves the trap buffer
 
7087  *      contens (or simply polls the buffer). The buffer is organized as
 
7088  *      a ring which stores the newest traps at the beginning. The oldest
 
7089  *      traps are overwritten by the newest ones. Each trap entry has a
 
7090  *      unique number, so that applications may detect new trap entries.
 
7093  *      A pointer to the trap entry
 
7095 PNMI_STATIC char* GetTrapEntry(
 
7096 SK_AC *pAC,             /* Pointer to adapter context */
 
7097 SK_U32 TrapId,          /* SNMP ID of the trap */
 
7098 unsigned int Size)      /* Space needed for trap entry */
 
7100         unsigned int            BufPad = pAC->Pnmi.TrapBufPad;
 
7101         unsigned int            BufFree = pAC->Pnmi.TrapBufFree;
 
7102         unsigned int            Beg = pAC->Pnmi.TrapQueueBeg;
 
7103         unsigned int            End = pAC->Pnmi.TrapQueueEnd;
 
7104         char                    *pBuf = &pAC->Pnmi.TrapBuf[0];
 
7106         unsigned int            NeededSpace;
 
7107         unsigned int            EntrySize;
 
7112         /* Last byte of entry will get a copy of the entry length */
 
7116          * Calculate needed buffer space */
 
7123                 NeededSpace = Beg + Size;
 
7128          * Check if enough buffer space is provided. Otherwise
 
7129          * free some entries. Leave one byte space between begin
 
7130          * and end of buffer to make it possible to detect whether
 
7131          * the buffer is full or empty
 
7133         while (BufFree < NeededSpace + 1) {
 
7137                         End = SK_PNMI_TRAP_QUEUE_LEN;
 
7140                 EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
 
7141                 BufFree += EntrySize;
 
7144                 SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
 
7146                 if (End == BufPad) {
 
7148                         SK_MEMSET(pBuf, (char)(-1), End);
 
7157          * Insert new entry as first entry. Newest entries are
 
7158          * stored at the beginning of the queue.
 
7163                 Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
 
7168         BufFree -= NeededSpace;
 
7170         /* Save the current offsets */
 
7171         pAC->Pnmi.TrapQueueBeg = Beg;
 
7172         pAC->Pnmi.TrapQueueEnd = End;
 
7173         pAC->Pnmi.TrapBufPad = BufPad;
 
7174         pAC->Pnmi.TrapBufFree = BufFree;
 
7176         /* Initialize the trap entry */
 
7177         *(pBuf + Beg + Size - 1) = (char)Size;
 
7178         *(pBuf + Beg) = (char)Size;
 
7179         Val32 = (pAC->Pnmi.TrapUnique) ++;
 
7180         SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
 
7181         SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
 
7182         Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
 
7183         SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
 
7185         return (pBuf + Beg);
 
7188 /*****************************************************************************
 
7190  * CopyTrapQueue - Copies the trap buffer for the TRAP OID
 
7193  *      On a query of the TRAP OID the trap buffer contents will be
 
7194  *      copied continuously to the request buffer, which must be large
 
7195  *      enough. No length check is performed.
 
7200 PNMI_STATIC void CopyTrapQueue(
 
7201 SK_AC *pAC,             /* Pointer to adapter context */
 
7202 char *pDstBuf)          /* Buffer to which the queued traps will be copied */
 
7204         unsigned int    BufPad = pAC->Pnmi.TrapBufPad;
 
7205         unsigned int    Trap = pAC->Pnmi.TrapQueueBeg;
 
7206         unsigned int    End = pAC->Pnmi.TrapQueueEnd;
 
7207         char            *pBuf = &pAC->Pnmi.TrapBuf[0];
 
7209         unsigned int    DstOff = 0;
 
7212         while (Trap != End) {
 
7214                 Len = (unsigned int)*(pBuf + Trap);
 
7217                  * Last byte containing a copy of the length will
 
7220                 *(pDstBuf + DstOff) = (char)(Len - 1);
 
7221                 SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
 
7225                 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
 
7232 /*****************************************************************************
 
7234  * GetTrapQueueLen - Get the length of the trap buffer
 
7237  *      Evaluates the number of currently stored traps and the needed
 
7238  *      buffer size to retrieve them.
 
7243 PNMI_STATIC void GetTrapQueueLen(
 
7244 SK_AC *pAC,             /* Pointer to adapter context */
 
7245 unsigned int *pLen,     /* Length in Bytes of all queued traps */
 
7246 unsigned int *pEntries) /* Returns number of trapes stored in queue */
 
7248         unsigned int    BufPad = pAC->Pnmi.TrapBufPad;
 
7249         unsigned int    Trap = pAC->Pnmi.TrapQueueBeg;
 
7250         unsigned int    End = pAC->Pnmi.TrapQueueEnd;
 
7251         char            *pBuf = &pAC->Pnmi.TrapBuf[0];
 
7253         unsigned int    Entries = 0;
 
7254         unsigned int    TotalLen = 0;
 
7257         while (Trap != End) {
 
7259                 Len = (unsigned int)*(pBuf + Trap);
 
7260                 TotalLen += Len - 1;
 
7264                 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
 
7270         *pEntries = Entries;
 
7274 /*****************************************************************************
 
7276  * QueueSimpleTrap - Store a simple trap to the trap buffer
 
7279  *      A simple trap is a trap with now additional data. It consists
 
7280  *      simply of a trap code.
 
7285 PNMI_STATIC void QueueSimpleTrap(
 
7286 SK_AC *pAC,             /* Pointer to adapter context */
 
7287 SK_U32 TrapId)          /* Type of sensor trap */
 
7289         GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
 
7292 /*****************************************************************************
 
7294  * QueueSensorTrap - Stores a sensor trap in the trap buffer
 
7297  *      Gets an entry in the trap buffer and fills it with sensor related
 
7303 PNMI_STATIC void QueueSensorTrap(
 
7304 SK_AC *pAC,                     /* Pointer to adapter context */
 
7305 SK_U32 TrapId,                  /* Type of sensor trap */
 
7306 unsigned int SensorIndex)       /* Index of sensor which caused the trap */
 
7309         unsigned int    Offset;
 
7310         unsigned int    DescrLen;
 
7314         /* Get trap buffer entry */
 
7315         DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
 
7316         pBuf = GetTrapEntry(pAC, TrapId,
 
7317                 SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
 
7318         Offset = SK_PNMI_TRAP_SIMPLE_LEN;
 
7320         /* Store additionally sensor trap related data */
 
7321         Val32 = OID_SKGE_SENSOR_INDEX;
 
7322         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
7323         *(pBuf + Offset + 4) = 4;
 
7324         Val32 = (SK_U32)SensorIndex;
 
7325         SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
 
7328         Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
 
7329         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
7330         *(pBuf + Offset + 4) = (char)DescrLen;
 
7331         SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
 
7333         Offset += DescrLen + 5;
 
7335         Val32 = OID_SKGE_SENSOR_TYPE;
 
7336         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
7337         *(pBuf + Offset + 4) = 1;
 
7338         *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
 
7341         Val32 = OID_SKGE_SENSOR_VALUE;
 
7342         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 
7343         *(pBuf + Offset + 4) = 4;
 
7344         Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
 
7345         SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
 
7348 /*****************************************************************************
 
7350  * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
 
7353  *      Nothing further to explain.
 
7358 PNMI_STATIC void QueueRlmtNewMacTrap(
 
7359 SK_AC *pAC,             /* Pointer to adapter context */
 
7360 unsigned int ActiveMac) /* Index (0..n) of the currently active port */
 
7366         pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
 
7367                 SK_PNMI_TRAP_RLMT_CHANGE_LEN);
 
7369         Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
 
7370         SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
 
7371         *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
 
7372         *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
 
7375 /*****************************************************************************
 
7377  * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
 
7380  *      Nothing further to explain.
 
7385 PNMI_STATIC void QueueRlmtPortTrap(
 
7386 SK_AC *pAC,             /* Pointer to adapter context */
 
7387 SK_U32 TrapId,          /* Type of RLMT port trap */
 
7388 unsigned int PortIndex) /* Index of the port, which changed its state */
 
7394         pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
 
7396         Val32 = OID_SKGE_RLMT_PORT_INDEX;
 
7397         SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
 
7398         *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
 
7399         *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
 
7402 /*****************************************************************************
 
7404  * CopyMac - Copies a MAC address
 
7407  *      Nothing further to explain.
 
7412 PNMI_STATIC void CopyMac(
 
7413 char *pDst,             /* Pointer to destination buffer */
 
7414 SK_MAC_ADDR *pMac)      /* Pointer of Source */
 
7419         for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
 
7421                 *(pDst + i) = pMac->a[i];
 
7425 #ifdef SK_POWER_MGMT
 
7426 /*****************************************************************************
 
7428  * PowerManagement - OID handler function of PowerManagement OIDs
 
7431  *      The code is simple. No description necessary.
 
7434  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
7435  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
7436  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
7437  *                               the correct data (e.g. a 32bit value is
 
7438  *                               needed, but a 16 bit value was passed).
 
7439  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
7440  *                               exist (e.g. port instance 3 on a two port
 
7444 PNMI_STATIC int PowerManagement(
 
7445 SK_AC *pAC,             /* Pointer to adapter context */
 
7446 SK_IOC IoC,             /* IO context handle */
 
7447 int Action,             /* Get/PreSet/Set action */
 
7448 SK_U32 Id,              /* Object ID that is to be processed */
 
7449 char *pBuf,             /* Buffer to which to mgmt data will be retrieved */
 
7450 unsigned int *pLen,     /* On call: buffer length. On return: used buffer */
 
7451 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
7452 unsigned int TableIndex, /* Index to the Id table */
 
7453 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode allways zero */
 
7456         SK_U32  RetCode = SK_PNMI_ERR_GENERAL;
 
7459          * Check instance. We only handle single instance variables
 
7461         if (Instance != (SK_U32)(-1) && Instance != 1) {
 
7464                 return (SK_PNMI_ERR_UNKNOWN_INST);
 
7471     case OID_PNP_CAPABILITIES:
 
7472         if (*pLen < sizeof(SK_PNP_CAPABILITIES)) {
 
7474             *pLen = sizeof(SK_PNP_CAPABILITIES);
 
7475             return (SK_PNMI_ERR_TOO_SHORT);
 
7479         case OID_PNP_SET_POWER:
 
7480     case OID_PNP_QUERY_POWER:
 
7481         if (*pLen < sizeof(SK_DEVICE_POWER_STATE))
 
7483                 *pLen = sizeof(SK_DEVICE_POWER_STATE);
 
7484                 return (SK_PNMI_ERR_TOO_SHORT);
 
7488     case OID_PNP_ADD_WAKE_UP_PATTERN:
 
7489     case OID_PNP_REMOVE_WAKE_UP_PATTERN:
 
7490                 if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) {
 
7492                         *pLen = sizeof(SK_PM_PACKET_PATTERN);
 
7493                         return (SK_PNMI_ERR_TOO_SHORT);
 
7497     case OID_PNP_ENABLE_WAKE_UP:
 
7498         if (*pLen < sizeof(SK_U32)) {
 
7500             *pLen = sizeof(SK_U32);
 
7501             return (SK_PNMI_ERR_TOO_SHORT);
 
7509         if (Action == SK_PNMI_GET) {
 
7516                 case OID_PNP_CAPABILITIES:
 
7517                         RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen);
 
7520                 case OID_PNP_QUERY_POWER:
 
7521                         /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
 
7522                          the miniport to indicate whether it can transition its NIC
 
7523                          to the low-power state.
 
7524                          A miniport driver must always return NDIS_STATUS_SUCCESS
 
7525                          to a query of OID_PNP_QUERY_POWER. */
 
7526                         *pLen = sizeof(SK_DEVICE_POWER_STATE);
 
7527             RetCode = SK_PNMI_ERR_OK;
 
7530                         /* NDIS handles these OIDs as write-only.
 
7531                          * So in case of get action the buffer with written length = 0
 
7534                 case OID_PNP_SET_POWER:
 
7535                 case OID_PNP_ADD_WAKE_UP_PATTERN:
 
7536                 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
 
7538             RetCode = SK_PNMI_ERR_NOT_SUPPORTED;
 
7541                 case OID_PNP_ENABLE_WAKE_UP:
 
7542                         RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen);
 
7546                         RetCode = SK_PNMI_ERR_GENERAL;
 
7555          * Perform preset or set
 
7558         /* POWER module does not support PRESET action */
 
7559         if (Action == SK_PNMI_PRESET) {
 
7560                 return (SK_PNMI_ERR_OK);
 
7564         case OID_PNP_SET_POWER:
 
7565                 RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen);        
 
7568         case OID_PNP_ADD_WAKE_UP_PATTERN:
 
7569                 RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen);        
 
7572         case OID_PNP_REMOVE_WAKE_UP_PATTERN:
 
7573                 RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen);     
 
7576         case OID_PNP_ENABLE_WAKE_UP:
 
7577                 RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen);
 
7581                 RetCode = SK_PNMI_ERR_READ_ONLY;
 
7586 #endif /* SK_POWER_MGMT */
 
7588 #ifdef SK_DIAG_SUPPORT
 
7589 /*****************************************************************************
 
7591  * DiagActions - OID handler function of Diagnostic driver 
 
7594  *      The code is simple. No description necessary.
 
7597  *      SK_PNMI_ERR_OK           The request was successfully performed.
 
7598  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
7599  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
7600  *                               the correct data (e.g. a 32bit value is
 
7601  *                               needed, but a 16 bit value was passed).
 
7602  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
7603  *                           exist (e.g. port instance 3 on a two port
 
7607 PNMI_STATIC int DiagActions(
 
7608 SK_AC *pAC,             /* Pointer to adapter context */
 
7609 SK_IOC IoC,             /* IO context handle */
 
7610 int Action,             /* GET/PRESET/SET action */
 
7611 SK_U32 Id,              /* Object ID that is to be processed */
 
7612 char *pBuf,             /* Buffer used for the management data transfer */
 
7613 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
7614 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
 
7615 unsigned int TableIndex, /* Index to the Id table */
 
7616 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
7620         SK_U32  RetCode = SK_PNMI_ERR_GENERAL;
 
7623          * Check instance. We only handle single instance variables.
 
7625         if (Instance != (SK_U32)(-1) && Instance != 1) {
 
7628                 return (SK_PNMI_ERR_UNKNOWN_INST);
 
7636         case OID_SKGE_DIAG_MODE:
 
7637                 if (*pLen < sizeof(SK_U32)) {
 
7639                         *pLen = sizeof(SK_U32);
 
7640                         return (SK_PNMI_ERR_TOO_SHORT);
 
7645                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040, SK_PNMI_ERR040MSG);
 
7647                 return (SK_PNMI_ERR_GENERAL);
 
7650         /* Perform action. */
 
7653         if (Action == SK_PNMI_GET) {
 
7657                 case OID_SKGE_DIAG_MODE:
 
7658                         DiagStatus = pAC->Pnmi.DiagAttached;
 
7659                         SK_PNMI_STORE_U32(pBuf, DiagStatus);
 
7660                         *pLen = sizeof(SK_U32); 
 
7661                         RetCode = SK_PNMI_ERR_OK;
 
7666                         RetCode = SK_PNMI_ERR_GENERAL;
 
7672         /* From here SET or PRESET value. */
 
7674         /* PRESET value is not supported. */
 
7675         if (Action == SK_PNMI_PRESET) {
 
7676                 return (SK_PNMI_ERR_OK); 
 
7681                 case OID_SKGE_DIAG_MODE:
 
7683                         /* Handle the SET. */
 
7686                                 /* Attach the DIAG to this adapter. */
 
7687                                 case SK_DIAG_ATTACHED:
 
7688                                         /* Check if we come from running */
 
7689                                         if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
 
7691                                                 RetCode = SkDrvLeaveDiagMode(pAC);
 
7694                                         else if (pAC->Pnmi.DiagAttached == SK_DIAG_IDLE) {
 
7696                                                 RetCode = SK_PNMI_ERR_OK;
 
7701                                                 RetCode = SK_PNMI_ERR_GENERAL;
 
7705                                         if (RetCode == SK_PNMI_ERR_OK) {
 
7707                                                 pAC->Pnmi.DiagAttached = SK_DIAG_ATTACHED;
 
7711                                 /* Enter the DIAG mode in the driver. */
 
7712                                 case SK_DIAG_RUNNING:
 
7713                                         RetCode = SK_PNMI_ERR_OK;
 
7716                                          * If DiagAttached is set, we can tell the driver
 
7717                                          * to enter the DIAG mode.
 
7719                                         if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
 
7720                                                 /* If DiagMode is not active, we can enter it. */
 
7721                                                 if (!pAC->DiagModeActive) {
 
7723                                                         RetCode = SkDrvEnterDiagMode(pAC); 
 
7727                                                         RetCode = SK_PNMI_ERR_GENERAL;
 
7732                                                 RetCode = SK_PNMI_ERR_GENERAL;
 
7735                                         if (RetCode == SK_PNMI_ERR_OK) {
 
7737                                                 pAC->Pnmi.DiagAttached = SK_DIAG_RUNNING;
 
7742                                         /* Check if we come from running */
 
7743                                         if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
 
7745                                                 RetCode = SkDrvLeaveDiagMode(pAC);
 
7748                                         else if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
 
7750                                                 RetCode = SK_PNMI_ERR_OK;
 
7755                                                 RetCode = SK_PNMI_ERR_GENERAL;
 
7759                                         if (RetCode == SK_PNMI_ERR_OK) {
 
7761                                                 pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
 
7766                                         RetCode = SK_PNMI_ERR_BAD_VALUE;
 
7772                         RetCode = SK_PNMI_ERR_GENERAL;
 
7775         if (RetCode == SK_PNMI_ERR_OK) {
 
7776                 *pLen = sizeof(SK_U32);
 
7784 #endif /* SK_DIAG_SUPPORT */
 
7786 /*****************************************************************************
 
7788  * Vct - OID handler function of  OIDs
 
7791  *      The code is simple. No description necessary.
 
7794  *      SK_PNMI_ERR_OK           The request was performed successfully.
 
7795  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
 
7796  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
 
7797  *                               the correct data (e.g. a 32bit value is
 
7798  *                               needed, but a 16 bit value was passed).
 
7799  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
7800  *                           exist (e.g. port instance 3 on a two port
 
7802  *      SK_PNMI_ERR_READ_ONLY    Only the Get action is allowed.
 
7806 PNMI_STATIC int Vct(
 
7807 SK_AC *pAC,             /* Pointer to adapter context */
 
7808 SK_IOC IoC,             /* IO context handle */
 
7809 int Action,             /* GET/PRESET/SET action */
 
7810 SK_U32 Id,              /* Object ID that is to be processed */
 
7811 char *pBuf,             /* Buffer used for the management data transfer */
 
7812 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
 
7813 SK_U32 Instance,        /* Instance (-1,2..n) that is to be queried */
 
7814 unsigned int TableIndex, /* Index to the Id table */
 
7815 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
 
7818         SK_PNMI_VCT     *pVctBackupData;
 
7821         SK_U32          PhysPortIndex;
 
7825         SK_U32          RetCode = SK_PNMI_ERR_GENERAL;
 
7831          * Calculate the port indexes from the instance.
 
7833         PhysPortMax = pAC->GIni.GIMacsFound;
 
7834         LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
 
7836         /* Dual net mode? */
 
7837         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
7841         if ((Instance != (SK_U32) (-1))) {
 
7842                 /* Check instance range. */
 
7843                 if ((Instance < 2) || (Instance > LogPortMax)) {
 
7845                         return (SK_PNMI_ERR_UNKNOWN_INST);
 
7848                 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 
7849                         PhysPortIndex = NetIndex;
 
7852                         PhysPortIndex = Instance - 2;
 
7854                 Limit = PhysPortIndex + 1;
 
7858                  * Instance == (SK_U32) (-1), get all Instances of that OID.
 
7860                  * Not implemented yet. May be used in future releases.
 
7863                 Limit = PhysPortMax;
 
7866         pPrt = &pAC->GIni.GP[PhysPortIndex];
 
7867         if (pPrt->PHWLinkUp) {
 
7874         /* Check MAC type */
 
7875         if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
 
7877                 return (SK_PNMI_ERR_GENERAL);
 
7880         /* Initialize backup data pointer. */
 
7881         pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
 
7883         /* Check action type */
 
7884         if (Action == SK_PNMI_GET) {
 
7888                 case OID_SKGE_VCT_GET:
 
7889                         if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
 
7890                                 *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
 
7891                                 return (SK_PNMI_ERR_TOO_SHORT);
 
7895                 case OID_SKGE_VCT_STATUS:
 
7896                         if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
 
7897                                 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
 
7898                                 return (SK_PNMI_ERR_TOO_SHORT);
 
7904                         return (SK_PNMI_ERR_GENERAL);
 
7909                 for (; PhysPortIndex < Limit; PhysPortIndex++) {
 
7912                         case OID_SKGE_VCT_GET:
 
7913                                 if ((Link == SK_FALSE) &&
 
7914                                         (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
 
7915                                         RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
 
7917                                                 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
 
7918                                                 pAC->Pnmi.VctStatus[PhysPortIndex] |=
 
7919                                                         (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
 
7921                                                 /* Copy results for later use to PNMI struct. */
 
7922                                                 for (i = 0; i < 4; i++)  {
 
7923                                                         if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
 
7924                                                                 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
 
7925                                                                         pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
 
7928                                                         if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
 
7929                                                                 CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
 
7934                                                         pVctBackupData->PMdiPairLen[i] = CableLength;
 
7935                                                         pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
 
7938                                                 Para.Para32[0] = PhysPortIndex;
 
7939                                                 Para.Para32[1] = -1;
 
7940                                                 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
 
7941                                                 SkEventDispatcher(pAC, IoC);
 
7944                                                 ; /* VCT test is running. */
 
7948                                 /* Get all results. */
 
7949                                 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
 
7950                                 Offset += sizeof(SK_U8);
 
7951                                 *(pBuf + Offset) = pPrt->PCableLen;
 
7952                                 Offset += sizeof(SK_U8);
 
7953                                 for (i = 0; i < 4; i++)  {
 
7954                                         SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
 
7955                                         Offset += sizeof(SK_U32);
 
7957                                 for (i = 0; i < 4; i++)  {
 
7958                                         *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
 
7959                                         Offset += sizeof(SK_U8);
 
7962                                 RetCode = SK_PNMI_ERR_OK;
 
7965                         case OID_SKGE_VCT_STATUS:
 
7966                                 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
 
7967                                 Offset += sizeof(SK_U8);
 
7968                                 RetCode = SK_PNMI_ERR_OK;
 
7973                                 return (SK_PNMI_ERR_GENERAL);
 
7979         } /* if SK_PNMI_GET */
 
7982          * From here SET or PRESET action. Check if the passed
 
7983          * buffer length is plausible.
 
7988         case OID_SKGE_VCT_SET:
 
7989                 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
 
7990                         *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
 
7991                         return (SK_PNMI_ERR_TOO_SHORT);
 
7997                 return (SK_PNMI_ERR_GENERAL);
 
8001          * Perform preset or set.
 
8004         /* VCT does not support PRESET action. */
 
8005         if (Action == SK_PNMI_PRESET) {
 
8006                 return (SK_PNMI_ERR_OK);
 
8010         for (; PhysPortIndex < Limit; PhysPortIndex++) {
 
8012                 case OID_SKGE_VCT_SET: /* Start VCT test. */
 
8013                         if (Link == SK_FALSE) {
 
8014                                 SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
 
8016                                 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
 
8017                                 if (RetCode == 0) { /* RetCode: 0 => Start! */
 
8018                                         pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
 
8019                                         pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
 
8020                                         pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
 
8023                                          * Start VCT timer counter.
 
8025                                         SK_MEMSET((char *) &Para, 0, sizeof(Para));
 
8026                                         Para.Para32[0] = PhysPortIndex;
 
8027                                         Para.Para32[1] = -1;
 
8028                                         SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
 
8029                                                 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
 
8030                                         SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
 
8031                                         RetCode = SK_PNMI_ERR_OK;
 
8033                                 else { /* RetCode: 2 => Running! */
 
8034                                         SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
 
8035                                         RetCode = SK_PNMI_ERR_OK;
 
8038                         else { /* RetCode: 4 => Link! */
 
8040                                 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
 
8041                                 RetCode = SK_PNMI_ERR_OK;
 
8043                         Offset += sizeof(SK_U32);
 
8048                         return (SK_PNMI_ERR_GENERAL);
 
8057 PNMI_STATIC void CheckVctStatus(
 
8062 SK_U32          PhysPortIndex)
 
8065         SK_PNMI_VCT     *pVctData;
 
8068         pPrt = &pAC->GIni.GP[PhysPortIndex];
 
8070         pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
 
8071         pVctData->VctStatus = SK_PNMI_VCT_NONE;
 
8073         if (!pPrt->PHWLinkUp) {
 
8075                 /* Was a VCT test ever made before? */
 
8076                 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
 
8077                         if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
 
8078                                 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
 
8081                                 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
 
8085                 /* Check VCT test status. */
 
8086                 RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
 
8087                 if (RetCode == 2) { /* VCT test is running. */
 
8088                         pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
 
8090                 else { /* VCT data was copied to pAC here. Check PENDING state. */
 
8091                         if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
 
8092                                 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
 
8096                 if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
 
8097                         pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
 
8102                 /* Was a VCT test ever made before? */
 
8103                 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
 
8104                         pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
 
8105                         pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
 
8108                 /* DSP only valid in 100/1000 modes. */
 
8109                 if (pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed !=
 
8110                         SK_LSPEED_STAT_10MBPS) {        
 
8111                         pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
 
8114 } /* CheckVctStatus */
 
8117 /*****************************************************************************
 
8119  *      SkPnmiGenIoctl - Handles new generic PNMI IOCTL, calls the needed
 
8120  *                       PNMI function depending on the subcommand and
 
8121  *                       returns all data belonging to the complete database
 
8125  *      Looks up the requested subcommand, calls the corresponding handler
 
8126  *      function and passes all required parameters to it.
 
8127  *      The function is called by the driver. It is needed to handle the new
 
8128  *  generic PNMI IOCTL. This IOCTL is given to the driver and contains both
 
8129  *  the OID and a subcommand to decide what kind of request has to be done.
 
8132  *      SK_PNMI_ERR_OK           The request was successfully performed
 
8133  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured
 
8134  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to take
 
8136  *      SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown
 
8137  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
 
8138  *                           exist (e.g. port instance 3 on a two port
 
8142 SK_AC           *pAC,           /* Pointer to adapter context struct */
 
8143 SK_IOC          IoC,            /* I/O context */
 
8144 void            *pBuf,          /* Buffer used for the management data transfer */
 
8145 unsigned int *pLen,             /* Length of buffer */
 
8146 SK_U32          NetIndex)       /* NetIndex (0..n), in single net mode always zero */
 
8148 SK_I32  Mode;                   /* Store value of subcommand. */
 
8149 SK_U32  Oid;                    /* Store value of OID. */
 
8150 int             ReturnCode;             /* Store return value to show status of PNMI action. */
 
8151 int     HeaderLength;   /* Length of desired action plus OID. */
 
8153         ReturnCode = SK_PNMI_ERR_GENERAL;
 
8155         SK_MEMCPY(&Mode, pBuf, sizeof(SK_I32));
 
8156         SK_MEMCPY(&Oid, (char *) pBuf + sizeof(SK_I32), sizeof(SK_U32));
 
8157         HeaderLength = sizeof(SK_I32) + sizeof(SK_U32);
 
8158         *pLen = *pLen - HeaderLength;
 
8159         SK_MEMCPY((char *) pBuf + sizeof(SK_I32), (char *) pBuf + HeaderLength, *pLen);
 
8162         case SK_GET_SINGLE_VAR:
 
8163                 ReturnCode = SkPnmiGetVar(pAC, IoC, Oid, 
 
8164                                 (char *) pBuf + sizeof(SK_I32), pLen,
 
8165                                 ((SK_U32) (-1)), NetIndex);
 
8166                 SK_PNMI_STORE_U32(pBuf, ReturnCode);
 
8167                 *pLen = *pLen + sizeof(SK_I32);
 
8169         case SK_PRESET_SINGLE_VAR:
 
8170                 ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid, 
 
8171                                 (char *) pBuf + sizeof(SK_I32), pLen,
 
8172                                 ((SK_U32) (-1)), NetIndex);
 
8173                 SK_PNMI_STORE_U32(pBuf, ReturnCode);
 
8174                 *pLen = *pLen + sizeof(SK_I32);
 
8176         case SK_SET_SINGLE_VAR:
 
8177                 ReturnCode = SkPnmiSetVar(pAC, IoC, Oid, 
 
8178                                 (char *) pBuf + sizeof(SK_I32), pLen,
 
8179                                 ((SK_U32) (-1)), NetIndex);
 
8180                 SK_PNMI_STORE_U32(pBuf, ReturnCode);
 
8181                 *pLen = *pLen + sizeof(SK_I32);
 
8183         case SK_GET_FULL_MIB:
 
8184                 ReturnCode = SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex);
 
8186         case SK_PRESET_FULL_MIB:
 
8187                 ReturnCode = SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
 
8189         case SK_SET_FULL_MIB:
 
8190                 ReturnCode = SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
 
8196         return (ReturnCode);