1 /*****************************************************************************
2 *
3 * Name: skgepnmi.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Purpose: Private Network Management Interface
6 *
7 ****************************************************************************/
8
9 /******************************************************************************
10 *
11 * (C)Copyright 1998-2002 SysKonnect GmbH.
12 * (C)Copyright 2002-2003 Marvell.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * The information in this file is provided "AS IS" without warranty.
20 *
21 ******************************************************************************/
22
23 #ifndef _lint
24 static const char SysKonnectFileId[] =
25 "@(#) $Id: skgepnmi.c,v 1.111 2003/09/15 13:35:35 tschilli Exp $ (C) Marvell.";
26 #endif /* !_lint */
27
28 #include "h/skdrv1st.h"
29 #include "h/sktypes.h"
30 #include "h/xmac_ii.h"
31 #include "h/skdebug.h"
32 #include "h/skqueue.h"
33 #include "h/skgepnmi.h"
34 #include "h/skgesirq.h"
35 #include "h/skcsum.h"
36 #include "h/skvpd.h"
37 #include "h/skgehw.h"
38 #include "h/skgeinit.h"
39 #include "h/skdrv2nd.h"
40 #include "h/skgepnm2.h"
41 #ifdef SK_POWER_MGMT
42 #include "h/skgepmgt.h"
43 #endif
44 /* defines *******************************************************************/
45
46 #ifndef DEBUG
47 #define PNMI_STATIC static
48 #else /* DEBUG */
49 #define PNMI_STATIC
50 #endif /* DEBUG */
51
52 /*
53 * Public Function prototypes
54 */
55 int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level);
56 int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
57 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
58 int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
59 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
60 int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
61 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
62 int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
63 unsigned int *pLen, SK_U32 NetIndex);
64 int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
65 unsigned int *pLen, SK_U32 NetIndex);
66 int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
67 unsigned int *pLen, SK_U32 NetIndex);
68 int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
69 int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf,
70 unsigned int * pLen, SK_U32 NetIndex);
71
72
73 /*
74 * Private Function prototypes
75 */
76
77 PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
78 PhysPortIndex);
79 PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
80 PhysPortIndex);
81 PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac);
82 PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
83 PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
84 unsigned int PhysPortIndex, unsigned int StatIndex);
85 PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
86 unsigned int StatIndex, SK_U32 NetIndex);
87 PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
88 PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
89 unsigned int *pEntries);
90 PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr,
91 unsigned int KeyArrLen, unsigned int *pKeyNo);
92 PNMI_STATIC int LookupId(SK_U32 Id);
93 PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
94 unsigned int LastMac);
95 PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
96 unsigned int *pLen, SK_U32 NetIndex);
97 PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id,
98 char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
99 PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
100 PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
101 unsigned int PortIndex);
102 PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
103 unsigned int SensorIndex);
104 PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
105 PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
106 PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
107 PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
108 PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
109 PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
110 unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
111 PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
112
113 /*
114 * Table to correlate OID with handler function and index to
115 * hardware register stored in StatAddress if applicable.
116 */
117 #include "skgemib.c"
118
119 /* global variables **********************************************************/
120
121 /*
122 * Overflow status register bit table and corresponding counter
123 * dependent on MAC type - the number relates to the size of overflow
124 * mask returned by the pFnMacOverflow function
125 */
126 PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = {
127 /* Bit0 */ { SK_PNMI_HTX, SK_PNMI_HTX_UNICAST},
128 /* Bit1 */ { SK_PNMI_HTX_OCTETHIGH, SK_PNMI_HTX_BROADCAST},
129 /* Bit2 */ { SK_PNMI_HTX_OCTETLOW, SK_PNMI_HTX_PMACC},
130 /* Bit3 */ { SK_PNMI_HTX_BROADCAST, SK_PNMI_HTX_MULTICAST},
131 /* Bit4 */ { SK_PNMI_HTX_MULTICAST, SK_PNMI_HTX_OCTETLOW},
132 /* Bit5 */ { SK_PNMI_HTX_UNICAST, SK_PNMI_HTX_OCTETHIGH},
133 /* Bit6 */ { SK_PNMI_HTX_LONGFRAMES, SK_PNMI_HTX_64},
134 /* Bit7 */ { SK_PNMI_HTX_BURST, SK_PNMI_HTX_127},
135 /* Bit8 */ { SK_PNMI_HTX_PMACC, SK_PNMI_HTX_255},
136 /* Bit9 */ { SK_PNMI_HTX_MACC, SK_PNMI_HTX_511},
137 /* Bit10 */ { SK_PNMI_HTX_SINGLE_COL, SK_PNMI_HTX_1023},
138 /* Bit11 */ { SK_PNMI_HTX_MULTI_COL, SK_PNMI_HTX_MAX},
139 /* Bit12 */ { SK_PNMI_HTX_EXCESS_COL, SK_PNMI_HTX_LONGFRAMES},
140 /* Bit13 */ { SK_PNMI_HTX_LATE_COL, SK_PNMI_HTX_RESERVED},
141 /* Bit14 */ { SK_PNMI_HTX_DEFFERAL, SK_PNMI_HTX_COL},
142 /* Bit15 */ { SK_PNMI_HTX_EXCESS_DEF, SK_PNMI_HTX_LATE_COL},
143 /* Bit16 */ { SK_PNMI_HTX_UNDERRUN, SK_PNMI_HTX_EXCESS_COL},
144 /* Bit17 */ { SK_PNMI_HTX_CARRIER, SK_PNMI_HTX_MULTI_COL},
145 /* Bit18 */ { SK_PNMI_HTX_UTILUNDER, SK_PNMI_HTX_SINGLE_COL},
146 /* Bit19 */ { SK_PNMI_HTX_UTILOVER, SK_PNMI_HTX_UNDERRUN},
147 /* Bit20 */ { SK_PNMI_HTX_64, SK_PNMI_HTX_RESERVED},
148 /* Bit21 */ { SK_PNMI_HTX_127, SK_PNMI_HTX_RESERVED},
149 /* Bit22 */ { SK_PNMI_HTX_255, SK_PNMI_HTX_RESERVED},
150 /* Bit23 */ { SK_PNMI_HTX_511, SK_PNMI_HTX_RESERVED},
151 /* Bit24 */ { SK_PNMI_HTX_1023, SK_PNMI_HTX_RESERVED},
152 /* Bit25 */ { SK_PNMI_HTX_MAX, SK_PNMI_HTX_RESERVED},
153 /* Bit26 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
154 /* Bit27 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
155 /* Bit28 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
156 /* Bit29 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
157 /* Bit30 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
158 /* Bit31 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
159 /* Bit32 */ { SK_PNMI_HRX, SK_PNMI_HRX_UNICAST},
160 /* Bit33 */ { SK_PNMI_HRX_OCTETHIGH, SK_PNMI_HRX_BROADCAST},
161 /* Bit34 */ { SK_PNMI_HRX_OCTETLOW, SK_PNMI_HRX_PMACC},
162 /* Bit35 */ { SK_PNMI_HRX_BROADCAST, SK_PNMI_HRX_MULTICAST},
163 /* Bit36 */ { SK_PNMI_HRX_MULTICAST, SK_PNMI_HRX_FCS},
164 /* Bit37 */ { SK_PNMI_HRX_UNICAST, SK_PNMI_HRX_RESERVED},
165 /* Bit38 */ { SK_PNMI_HRX_PMACC, SK_PNMI_HRX_OCTETLOW},
166 /* Bit39 */ { SK_PNMI_HRX_MACC, SK_PNMI_HRX_OCTETHIGH},
167 /* Bit40 */ { SK_PNMI_HRX_PMACC_ERR, SK_PNMI_HRX_BADOCTETLOW},
168 /* Bit41 */ { SK_PNMI_HRX_MACC_UNKWN, SK_PNMI_HRX_BADOCTETHIGH},
169 /* Bit42 */ { SK_PNMI_HRX_BURST, SK_PNMI_HRX_UNDERSIZE},
170 /* Bit43 */ { SK_PNMI_HRX_MISSED, SK_PNMI_HRX_RUNT},
171 /* Bit44 */ { SK_PNMI_HRX_FRAMING, SK_PNMI_HRX_64},
172 /* Bit45 */ { SK_PNMI_HRX_OVERFLOW, SK_PNMI_HRX_127},
173 /* Bit46 */ { SK_PNMI_HRX_JABBER, SK_PNMI_HRX_255},
174 /* Bit47 */ { SK_PNMI_HRX_CARRIER, SK_PNMI_HRX_511},
175 /* Bit48 */ { SK_PNMI_HRX_IRLENGTH, SK_PNMI_HRX_1023},
176 /* Bit49 */ { SK_PNMI_HRX_SYMBOL, SK_PNMI_HRX_MAX},
177 /* Bit50 */ { SK_PNMI_HRX_SHORTS, SK_PNMI_HRX_LONGFRAMES},
178 /* Bit51 */ { SK_PNMI_HRX_RUNT, SK_PNMI_HRX_TOO_LONG},
179 /* Bit52 */ { SK_PNMI_HRX_TOO_LONG, SK_PNMI_HRX_JABBER},
180 /* Bit53 */ { SK_PNMI_HRX_FCS, SK_PNMI_HRX_RESERVED},
181 /* Bit54 */ { SK_PNMI_HRX_RESERVED, SK_PNMI_HRX_OVERFLOW},
182 /* Bit55 */ { SK_PNMI_HRX_CEXT, SK_PNMI_HRX_RESERVED},
183 /* Bit56 */ { SK_PNMI_HRX_UTILUNDER, SK_PNMI_HRX_RESERVED},
184 /* Bit57 */ { SK_PNMI_HRX_UTILOVER, SK_PNMI_HRX_RESERVED},
185 /* Bit58 */ { SK_PNMI_HRX_64, SK_PNMI_HRX_RESERVED},
186 /* Bit59 */ { SK_PNMI_HRX_127, SK_PNMI_HRX_RESERVED},
187 /* Bit60 */ { SK_PNMI_HRX_255, SK_PNMI_HRX_RESERVED},
188 /* Bit61 */ { SK_PNMI_HRX_511, SK_PNMI_HRX_RESERVED},
189 /* Bit62 */ { SK_PNMI_HRX_1023, SK_PNMI_HRX_RESERVED},
190 /* Bit63 */ { SK_PNMI_HRX_MAX, SK_PNMI_HRX_RESERVED}
191 };
192
193 /*
194 * Table for hardware register saving on resets and port switches
195 */
196 PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = {
197 /* SK_PNMI_HTX */
198 {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}},
199 /* SK_PNMI_HTX_OCTETHIGH */
200 {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}},
201 /* SK_PNMI_HTX_OCTETLOW */
202 {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}},
203 /* SK_PNMI_HTX_BROADCAST */
204 {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}},
205 /* SK_PNMI_HTX_MULTICAST */
206 {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}},
207 /* SK_PNMI_HTX_UNICAST */
208 {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}},
209 /* SK_PNMI_HTX_BURST */
210 {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}},
211 /* SK_PNMI_HTX_PMACC */
212 {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}},
213 /* SK_PNMI_HTX_MACC */
214 {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
215 /* SK_PNMI_HTX_COL */
216 {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}},
217 /* SK_PNMI_HTX_SINGLE_COL */
218 {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}},
219 /* SK_PNMI_HTX_MULTI_COL */
220 {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}},
221 /* SK_PNMI_HTX_EXCESS_COL */
222 {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}},
223 /* SK_PNMI_HTX_LATE_COL */
224 {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}},
225 /* SK_PNMI_HTX_DEFFERAL */
226 {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}},
227 /* SK_PNMI_HTX_EXCESS_DEF */
228 {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}},
229 /* SK_PNMI_HTX_UNDERRUN */
230 {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}},
231 /* SK_PNMI_HTX_CARRIER */
232 {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}},
233 /* SK_PNMI_HTX_UTILUNDER */
234 {{0, SK_FALSE}, {0, SK_FALSE}},
235 /* SK_PNMI_HTX_UTILOVER */
236 {{0, SK_FALSE}, {0, SK_FALSE}},
237 /* SK_PNMI_HTX_64 */
238 {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}},
239 /* SK_PNMI_HTX_127 */
240 {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}},
241 /* SK_PNMI_HTX_255 */
242 {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}},
243 /* SK_PNMI_HTX_511 */
244 {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}},
245 /* SK_PNMI_HTX_1023 */
246 {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}},
247 /* SK_PNMI_HTX_MAX */
248 {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}},
249 /* SK_PNMI_HTX_LONGFRAMES */
250 {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}},
251 /* SK_PNMI_HTX_SYNC */
252 {{0, SK_FALSE}, {0, SK_FALSE}},
253 /* SK_PNMI_HTX_SYNC_OCTET */
254 {{0, SK_FALSE}, {0, SK_FALSE}},
255 /* SK_PNMI_HTX_RESERVED */
256 {{0, SK_FALSE}, {0, SK_FALSE}},
257 /* SK_PNMI_HRX */
258 {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}},
259 /* SK_PNMI_HRX_OCTETHIGH */
260 {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}},
261 /* SK_PNMI_HRX_OCTETLOW */
262 {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}},
263 /* SK_PNMI_HRX_BADOCTETHIGH */
264 {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}},
265 /* SK_PNMI_HRX_BADOCTETLOW */
266 {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}},
267 /* SK_PNMI_HRX_BROADCAST */
268 {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}},
269 /* SK_PNMI_HRX_MULTICAST */
270 {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}},
271 /* SK_PNMI_HRX_UNICAST */
272 {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}},
273 /* SK_PNMI_HRX_PMACC */
274 {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}},
275 /* SK_PNMI_HRX_MACC */
276 {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
277 /* SK_PNMI_HRX_PMACC_ERR */
278 {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}},
279 /* SK_PNMI_HRX_MACC_UNKWN */
280 {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}},
281 /* SK_PNMI_HRX_BURST */
282 {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}},
283 /* SK_PNMI_HRX_MISSED */
284 {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}},
285 /* SK_PNMI_HRX_FRAMING */
286 {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}},
287 /* SK_PNMI_HRX_UNDERSIZE */
288 {{0, SK_FALSE}, {GM_RXF_SHT, SK_TRUE}},
289 /* SK_PNMI_HRX_OVERFLOW */
290 {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}},
291 /* SK_PNMI_HRX_JABBER */
292 {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}},
293 /* SK_PNMI_HRX_CARRIER */
294 {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}},
295 /* SK_PNMI_HRX_IRLENGTH */
296 {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}},
297 /* SK_PNMI_HRX_SYMBOL */
298 {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}},
299 /* SK_PNMI_HRX_SHORTS */
300 {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}},
301 /* SK_PNMI_HRX_RUNT */
302 {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}},
303 /* SK_PNMI_HRX_TOO_LONG */
304 {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}},
305 /* SK_PNMI_HRX_FCS */
306 {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}},
307 /* SK_PNMI_HRX_CEXT */
308 {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}},
309 /* SK_PNMI_HRX_UTILUNDER */
310 {{0, SK_FALSE}, {0, SK_FALSE}},
311 /* SK_PNMI_HRX_UTILOVER */
312 {{0, SK_FALSE}, {0, SK_FALSE}},
313 /* SK_PNMI_HRX_64 */
314 {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}},
315 /* SK_PNMI_HRX_127 */
316 {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}},
317 /* SK_PNMI_HRX_255 */
318 {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}},
319 /* SK_PNMI_HRX_511 */
320 {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}},
321 /* SK_PNMI_HRX_1023 */
322 {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}},
323 /* SK_PNMI_HRX_MAX */
324 {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}},
325 /* SK_PNMI_HRX_LONGFRAMES */
326 {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}},
327 /* SK_PNMI_HRX_RESERVED */
328 {{0, SK_FALSE}, {0, SK_FALSE}}
329 };
330
331
332 /*****************************************************************************
333 *
334 * Public functions
335 *
336 */
337
338 /*****************************************************************************
339 *
340 * SkPnmiInit - Init function of PNMI
341 *
342 * Description:
343 * SK_INIT_DATA: Initialises the data structures
344 * SK_INIT_IO: Resets the XMAC statistics, determines the device and
345 * connector type.
346 * SK_INIT_RUN: Starts a timer event for port switch per hour
347 * calculation.
348 *
349 * Returns:
350 * Always 0
351 */
SkPnmiInit(SK_AC * pAC,SK_IOC IoC,int Level)352 int SkPnmiInit(
353 SK_AC *pAC, /* Pointer to adapter context */
354 SK_IOC IoC, /* IO context handle */
355 int Level) /* Initialization level */
356 {
357 unsigned int PortMax; /* Number of ports */
358 unsigned int PortIndex; /* Current port index in loop */
359 SK_U16 Val16; /* Multiple purpose 16 bit variable */
360 SK_U8 Val8; /* Mulitple purpose 8 bit variable */
361 SK_EVPARA EventParam; /* Event struct for timer event */
362 SK_PNMI_VCT *pVctBackupData;
363
364
365 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
366 ("PNMI: SkPnmiInit: Called, level=%d\n", Level));
367
368 switch (Level) {
369
370 case SK_INIT_DATA:
371 SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
372 pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
373 pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
374 pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
375 for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
376
377 pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
378 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
379 }
380
381 #ifdef SK_PNMI_CHECK
382 if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) {
383
384 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG);
385
386 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
387 ("CounterOffset struct size (%d) differs from"
388 "SK_PNMI_MAX_IDX (%d)\n",
389 SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
390 }
391
392 if (SK_PNMI_MAX_IDX !=
393 (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) {
394
395 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG);
396
397 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
398 ("StatAddr table size (%d) differs from "
399 "SK_PNMI_MAX_IDX (%d)\n",
400 (sizeof(StatAddr) /
401 (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)),
402 SK_PNMI_MAX_IDX));
403 }
404 #endif /* SK_PNMI_CHECK */
405 break;
406
407 case SK_INIT_IO:
408 /*
409 * Reset MAC counters
410 */
411 PortMax = pAC->GIni.GIMacsFound;
412
413 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
414
415 pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
416 }
417
418 /* Initialize DSP variables for Vct() to 0xff => Never written! */
419 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
420 pAC->GIni.GP[PortIndex].PCableLen = 0xff;
421 pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
422 pVctBackupData->PCableLen = 0xff;
423 }
424
425 /*
426 * Get pci bus speed
427 */
428 SK_IN16(IoC, B0_CTST, &Val16);
429 if ((Val16 & CS_BUS_CLOCK) == 0) {
430
431 pAC->Pnmi.PciBusSpeed = 33;
432 }
433 else {
434 pAC->Pnmi.PciBusSpeed = 66;
435 }
436
437 /*
438 * Get pci bus width
439 */
440 SK_IN16(IoC, B0_CTST, &Val16);
441 if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
442
443 pAC->Pnmi.PciBusWidth = 32;
444 }
445 else {
446 pAC->Pnmi.PciBusWidth = 64;
447 }
448
449 /*
450 * Get chipset
451 */
452 switch (pAC->GIni.GIChipId) {
453 case CHIP_ID_GENESIS:
454 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
455 break;
456
457 case CHIP_ID_YUKON:
458 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
459 break;
460
461 default:
462 break;
463 }
464
465 /*
466 * Get PMD and DeviceType
467 */
468 SK_IN8(IoC, B2_PMD_TYP, &Val8);
469 switch (Val8) {
470 case 'S':
471 pAC->Pnmi.PMD = 3;
472 if (pAC->GIni.GIMacsFound > 1) {
473
474 pAC->Pnmi.DeviceType = 0x00020002;
475 }
476 else {
477 pAC->Pnmi.DeviceType = 0x00020001;
478 }
479 break;
480
481 case 'L':
482 pAC->Pnmi.PMD = 2;
483 if (pAC->GIni.GIMacsFound > 1) {
484
485 pAC->Pnmi.DeviceType = 0x00020004;
486 }
487 else {
488 pAC->Pnmi.DeviceType = 0x00020003;
489 }
490 break;
491
492 case 'C':
493 pAC->Pnmi.PMD = 4;
494 if (pAC->GIni.GIMacsFound > 1) {
495
496 pAC->Pnmi.DeviceType = 0x00020006;
497 }
498 else {
499 pAC->Pnmi.DeviceType = 0x00020005;
500 }
501 break;
502
503 case 'T':
504 pAC->Pnmi.PMD = 5;
505 if (pAC->GIni.GIMacsFound > 1) {
506
507 pAC->Pnmi.DeviceType = 0x00020008;
508 }
509 else {
510 pAC->Pnmi.DeviceType = 0x00020007;
511 }
512 break;
513
514 default :
515 pAC->Pnmi.PMD = 1;
516 pAC->Pnmi.DeviceType = 0;
517 break;
518 }
519
520 /*
521 * Get connector
522 */
523 SK_IN8(IoC, B2_CONN_TYP, &Val8);
524 switch (Val8) {
525 case 'C':
526 pAC->Pnmi.Connector = 2;
527 break;
528
529 case 'D':
530 pAC->Pnmi.Connector = 3;
531 break;
532
533 case 'F':
534 pAC->Pnmi.Connector = 4;
535 break;
536
537 case 'J':
538 pAC->Pnmi.Connector = 5;
539 break;
540
541 case 'V':
542 pAC->Pnmi.Connector = 6;
543 break;
544
545 default:
546 pAC->Pnmi.Connector = 1;
547 break;
548 }
549 break;
550
551 case SK_INIT_RUN:
552 /*
553 * Start timer for RLMT change counter
554 */
555 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
556 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
557 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
558 EventParam);
559 break;
560
561 default:
562 break; /* Nothing todo */
563 }
564
565 return (0);
566 }
567
568 /*****************************************************************************
569 *
570 * SkPnmiGetVar - Retrieves the value of a single OID
571 *
572 * Description:
573 * Calls a general sub-function for all this stuff. If the instance
574 * -1 is passed, the values of all instances are returned in an
575 * array of values.
576 *
577 * Returns:
578 * SK_PNMI_ERR_OK The request was successfully performed
579 * SK_PNMI_ERR_GENERAL A general severe internal error occured
580 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
581 * the data.
582 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
583 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
584 * exist (e.g. port instance 3 on a two port
585 * adapter.
586 */
SkPnmiGetVar(SK_AC * pAC,SK_IOC IoC,SK_U32 Id,void * pBuf,unsigned int * pLen,SK_U32 Instance,SK_U32 NetIndex)587 int SkPnmiGetVar(
588 SK_AC *pAC, /* Pointer to adapter context */
589 SK_IOC IoC, /* IO context handle */
590 SK_U32 Id, /* Object ID that is to be processed */
591 void *pBuf, /* Buffer to which the management data will be copied */
592 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
593 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
594 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
595 {
596 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
597 ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
598 Id, *pLen, Instance, NetIndex));
599
600 return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
601 Instance, NetIndex));
602 }
603
604 /*****************************************************************************
605 *
606 * SkPnmiPreSetVar - Presets the value of a single OID
607 *
608 * Description:
609 * Calls a general sub-function for all this stuff. The preset does
610 * the same as a set, but returns just before finally setting the
611 * new value. This is usefull to check if a set might be successfull.
612 * If the instance -1 is passed, an array of values is supposed and
613 * all instances of the OID will be set.
614 *
615 * Returns:
616 * SK_PNMI_ERR_OK The request was successfully performed.
617 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
618 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
619 * the correct data (e.g. a 32bit value is
620 * needed, but a 16 bit value was passed).
621 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
622 * value range.
623 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
624 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
625 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
626 * exist (e.g. port instance 3 on a two port
627 * adapter.
628 */
SkPnmiPreSetVar(SK_AC * pAC,SK_IOC IoC,SK_U32 Id,void * pBuf,unsigned int * pLen,SK_U32 Instance,SK_U32 NetIndex)629 int SkPnmiPreSetVar(
630 SK_AC *pAC, /* Pointer to adapter context */
631 SK_IOC IoC, /* IO context handle */
632 SK_U32 Id, /* Object ID that is to be processed */
633 void *pBuf, /* Buffer to which the management data will be copied */
634 unsigned int *pLen, /* Total length of management data */
635 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
636 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
637 {
638 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
639 ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
640 Id, *pLen, Instance, NetIndex));
641
642
643 return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
644 Instance, NetIndex));
645 }
646
647 /*****************************************************************************
648 *
649 * SkPnmiSetVar - Sets the value of a single OID
650 *
651 * Description:
652 * Calls a general sub-function for all this stuff. The preset does
653 * the same as a set, but returns just before finally setting the
654 * new value. This is usefull to check if a set might be successfull.
655 * If the instance -1 is passed, an array of values is supposed and
656 * all instances of the OID will be set.
657 *
658 * Returns:
659 * SK_PNMI_ERR_OK The request was successfully performed.
660 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
661 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
662 * the correct data (e.g. a 32bit value is
663 * needed, but a 16 bit value was passed).
664 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
665 * value range.
666 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
667 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
668 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
669 * exist (e.g. port instance 3 on a two port
670 * adapter.
671 */
SkPnmiSetVar(SK_AC * pAC,SK_IOC IoC,SK_U32 Id,void * pBuf,unsigned int * pLen,SK_U32 Instance,SK_U32 NetIndex)672 int SkPnmiSetVar(
673 SK_AC *pAC, /* Pointer to adapter context */
674 SK_IOC IoC, /* IO context handle */
675 SK_U32 Id, /* Object ID that is to be processed */
676 void *pBuf, /* Buffer to which the management data will be copied */
677 unsigned int *pLen, /* Total length of management data */
678 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
679 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
680 {
681 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
682 ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
683 Id, *pLen, Instance, NetIndex));
684
685 return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
686 Instance, NetIndex));
687 }
688
689 /*****************************************************************************
690 *
691 * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA
692 *
693 * Description:
694 * Runs through the IdTable, queries the single OIDs and stores the
695 * returned data into the management database structure
696 * SK_PNMI_STRUCT_DATA. The offset of the OID in the structure
697 * is stored in the IdTable. The return value of the function will also
698 * be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
699 * minimum size of SK_PNMI_MIN_STRUCT_SIZE.
700 *
701 * Returns:
702 * SK_PNMI_ERR_OK The request was successfully performed
703 * SK_PNMI_ERR_GENERAL A general severe internal error occured
704 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
705 * the data.
706 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
707 */
SkPnmiGetStruct(SK_AC * pAC,SK_IOC IoC,void * pBuf,unsigned int * pLen,SK_U32 NetIndex)708 int SkPnmiGetStruct(
709 SK_AC *pAC, /* Pointer to adapter context */
710 SK_IOC IoC, /* IO context handle */
711 void *pBuf, /* Buffer to which the management data will be copied. */
712 unsigned int *pLen, /* Length of buffer */
713 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
714 {
715 int Ret;
716 unsigned int TableIndex;
717 unsigned int DstOffset;
718 unsigned int InstanceNo;
719 unsigned int InstanceCnt;
720 SK_U32 Instance;
721 unsigned int TmpLen;
722 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
723
724
725 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
726 ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
727 *pLen, NetIndex));
728
729 if (*pLen < SK_PNMI_STRUCT_SIZE) {
730
731 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
732
733 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
734 (SK_U32)(-1));
735 }
736
737 *pLen = SK_PNMI_STRUCT_SIZE;
738 return (SK_PNMI_ERR_TOO_SHORT);
739 }
740
741 /*
742 * Check NetIndex
743 */
744 if (NetIndex >= pAC->Rlmt.NumNets) {
745 return (SK_PNMI_ERR_UNKNOWN_NET);
746 }
747
748 /* Update statistic */
749 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
750
751 if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
752 SK_PNMI_ERR_OK) {
753
754 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
755 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
756 return (Ret);
757 }
758
759 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
760
761 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
762 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
763 return (Ret);
764 }
765
766 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
767
768 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
769 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
770 return (Ret);
771 }
772
773 /*
774 * Increment semaphores to indicate that an update was
775 * already done
776 */
777 pAC->Pnmi.MacUpdatedFlag ++;
778 pAC->Pnmi.RlmtUpdatedFlag ++;
779 pAC->Pnmi.SirqUpdatedFlag ++;
780
781 /* Get vpd keys for instance calculation */
782 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
783 if (Ret != SK_PNMI_ERR_OK) {
784
785 pAC->Pnmi.MacUpdatedFlag --;
786 pAC->Pnmi.RlmtUpdatedFlag --;
787 pAC->Pnmi.SirqUpdatedFlag --;
788
789 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
790 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
791 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
792 return (SK_PNMI_ERR_GENERAL);
793 }
794
795 /* Retrieve values */
796 SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
797 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
798
799 InstanceNo = IdTable[TableIndex].InstanceNo;
800 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
801 InstanceCnt ++) {
802
803 DstOffset = IdTable[TableIndex].Offset +
804 (InstanceCnt - 1) *
805 IdTable[TableIndex].StructSize;
806
807 /*
808 * For the VPD the instance is not an index number
809 * but the key itself. Determin with the instance
810 * counter the VPD key to be used.
811 */
812 if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
813 IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
814 IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
815 IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
816
817 SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
818 }
819 else {
820 Instance = (SK_U32)InstanceCnt;
821 }
822
823 TmpLen = *pLen - DstOffset;
824 Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
825 IdTable[TableIndex].Id, (char *)pBuf +
826 DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
827
828 /*
829 * An unknown instance error means that we reached
830 * the last instance of that variable. Proceed with
831 * the next OID in the table and ignore the return
832 * code.
833 */
834 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
835
836 break;
837 }
838
839 if (Ret != SK_PNMI_ERR_OK) {
840
841 pAC->Pnmi.MacUpdatedFlag --;
842 pAC->Pnmi.RlmtUpdatedFlag --;
843 pAC->Pnmi.SirqUpdatedFlag --;
844
845 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
846 SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
847 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
848 return (Ret);
849 }
850 }
851 }
852
853 pAC->Pnmi.MacUpdatedFlag --;
854 pAC->Pnmi.RlmtUpdatedFlag --;
855 pAC->Pnmi.SirqUpdatedFlag --;
856
857 *pLen = SK_PNMI_STRUCT_SIZE;
858 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
859 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
860 return (SK_PNMI_ERR_OK);
861 }
862
863 /*****************************************************************************
864 *
865 * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
866 *
867 * Description:
868 * Calls a general sub-function for all this set stuff. The preset does
869 * the same as a set, but returns just before finally setting the
870 * new value. This is usefull to check if a set might be successfull.
871 * The sub-function runs through the IdTable, checks which OIDs are able
872 * to set, and calls the handler function of the OID to perform the
873 * preset. The return value of the function will also be stored in
874 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
875 * SK_PNMI_MIN_STRUCT_SIZE.
876 *
877 * Returns:
878 * SK_PNMI_ERR_OK The request was successfully performed.
879 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
880 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
881 * the correct data (e.g. a 32bit value is
882 * needed, but a 16 bit value was passed).
883 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
884 * value range.
885 */
SkPnmiPreSetStruct(SK_AC * pAC,SK_IOC IoC,void * pBuf,unsigned int * pLen,SK_U32 NetIndex)886 int SkPnmiPreSetStruct(
887 SK_AC *pAC, /* Pointer to adapter context */
888 SK_IOC IoC, /* IO context handle */
889 void *pBuf, /* Buffer which contains the data to be set */
890 unsigned int *pLen, /* Length of buffer */
891 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
892 {
893 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
894 ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
895 *pLen, NetIndex));
896
897 return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf,
898 pLen, NetIndex));
899 }
900
901 /*****************************************************************************
902 *
903 * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA
904 *
905 * Description:
906 * Calls a general sub-function for all this set stuff. The return value
907 * of the function will also be stored in SK_PNMI_STRUCT_DATA if the
908 * passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE.
909 * The sub-function runs through the IdTable, checks which OIDs are able
910 * to set, and calls the handler function of the OID to perform the
911 * set. The return value of the function will also be stored in
912 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
913 * SK_PNMI_MIN_STRUCT_SIZE.
914 *
915 * Returns:
916 * SK_PNMI_ERR_OK The request was successfully performed.
917 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
918 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
919 * the correct data (e.g. a 32bit value is
920 * needed, but a 16 bit value was passed).
921 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
922 * value range.
923 */
SkPnmiSetStruct(SK_AC * pAC,SK_IOC IoC,void * pBuf,unsigned int * pLen,SK_U32 NetIndex)924 int SkPnmiSetStruct(
925 SK_AC *pAC, /* Pointer to adapter context */
926 SK_IOC IoC, /* IO context handle */
927 void *pBuf, /* Buffer which contains the data to be set */
928 unsigned int *pLen, /* Length of buffer */
929 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
930 {
931 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
932 ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
933 *pLen, NetIndex));
934
935 return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf,
936 pLen, NetIndex));
937 }
938
939 /*****************************************************************************
940 *
941 * SkPnmiEvent - Event handler
942 *
943 * Description:
944 * Handles the following events:
945 * SK_PNMI_EVT_SIRQ_OVERFLOW When a hardware counter overflows an
946 * interrupt will be generated which is
947 * first handled by SIRQ which generates a
948 * this event. The event increments the
949 * upper 32 bit of the 64 bit counter.
950 * SK_PNMI_EVT_SEN_XXX The event is generated by the I2C module
951 * when a sensor reports a warning or
952 * error. The event will store a trap
953 * message in the trap buffer.
954 * SK_PNMI_EVT_CHG_EST_TIMER The timer event was initiated by this
955 * module and is used to calculate the
956 * port switches per hour.
957 * SK_PNMI_EVT_CLEAR_COUNTER The event clears all counters and
958 * timestamps.
959 * SK_PNMI_EVT_XMAC_RESET The event is generated by the driver
960 * before a hard reset of the XMAC is
961 * performed. All counters will be saved
962 * and added to the hardware counter
963 * values after reset to grant continuous
964 * counter values.
965 * SK_PNMI_EVT_RLMT_PORT_UP Generated by RLMT to notify that a port
966 * went logically up. A trap message will
967 * be stored to the trap buffer.
968 * SK_PNMI_EVT_RLMT_PORT_DOWN Generated by RLMT to notify that a port
969 * went logically down. A trap message will
970 * be stored to the trap buffer.
971 * SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
972 * spanning tree root bridges were
973 * detected. A trap message will be stored
974 * to the trap buffer.
975 * SK_PNMI_EVT_RLMT_ACTIVE_DOWN Notifies PNMI that an active port went
976 * down. PNMI will not further add the
977 * statistic values to the virtual port.
978 * SK_PNMI_EVT_RLMT_ACTIVE_UP Notifies PNMI that a port went up and
979 * is now an active port. PNMI will now
980 * add the statistic data of this port to
981 * the virtual port.
982 * SK_PNMI_EVT_RLMT_SET_NETS Notifies PNMI about the net mode. The first parameter
983 * contains the number of nets. 1 means single net, 2 means
984 * dual net. The second parameter is -1
985 *
986 * Returns:
987 * Always 0
988 */
SkPnmiEvent(SK_AC * pAC,SK_IOC IoC,SK_U32 Event,SK_EVPARA Param)989 int SkPnmiEvent(
990 SK_AC *pAC, /* Pointer to adapter context */
991 SK_IOC IoC, /* IO context handle */
992 SK_U32 Event, /* Event-Id */
993 SK_EVPARA Param) /* Event dependent parameter */
994 {
995 unsigned int PhysPortIndex;
996 unsigned int MaxNetNumber;
997 int CounterIndex;
998 int Ret;
999 SK_U16 MacStatus;
1000 SK_U64 OverflowStatus;
1001 SK_U64 Mask;
1002 int MacType;
1003 SK_U64 Value;
1004 SK_U32 Val32;
1005 SK_U16 Register;
1006 SK_EVPARA EventParam;
1007 SK_U64 NewestValue;
1008 SK_U64 OldestValue;
1009 SK_U64 Delta;
1010 SK_PNMI_ESTIMATE *pEst;
1011 SK_U32 NetIndex;
1012 SK_GEPORT *pPrt;
1013 SK_PNMI_VCT *pVctBackupData;
1014 SK_U32 RetCode;
1015 int i;
1016 SK_U32 CableLength;
1017
1018
1019 #ifdef DEBUG
1020 if (Event != SK_PNMI_EVT_XMAC_RESET) {
1021
1022 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1023 ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n",
1024 (unsigned int)Event, (unsigned int)Param.Para64));
1025 }
1026 #endif /* DEBUG */
1027 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call");
1028
1029 MacType = pAC->GIni.GIMacType;
1030
1031 switch (Event) {
1032
1033 case SK_PNMI_EVT_SIRQ_OVERFLOW:
1034 PhysPortIndex = (int)Param.Para32[0];
1035 MacStatus = (SK_U16)Param.Para32[1];
1036 #ifdef DEBUG
1037 if (PhysPortIndex >= SK_MAX_MACS) {
1038
1039 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1040 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter"
1041 " wrong, PhysPortIndex=0x%x\n",
1042 PhysPortIndex));
1043 return (0);
1044 }
1045 #endif /* DEBUG */
1046 OverflowStatus = 0;
1047
1048 /*
1049 * Check which source caused an overflow interrupt.
1050 */
1051 if ((pAC->GIni.GIFunc.pFnMacOverflow(pAC, IoC, PhysPortIndex,
1052 MacStatus, &OverflowStatus) != 0) ||
1053 (OverflowStatus == 0)) {
1054
1055 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1056 return (0);
1057 }
1058
1059 /*
1060 * Check the overflow status register and increment
1061 * the upper dword of corresponding counter.
1062 */
1063 for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8;
1064 CounterIndex ++) {
1065
1066 Mask = (SK_U64)1 << CounterIndex;
1067 if ((OverflowStatus & Mask) == 0) {
1068
1069 continue;
1070 }
1071
1072 switch (StatOvrflwBit[CounterIndex][MacType]) {
1073
1074 case SK_PNMI_HTX_UTILUNDER:
1075 case SK_PNMI_HTX_UTILOVER:
1076 if (MacType == SK_MAC_XMAC) {
1077 XM_IN16(IoC, PhysPortIndex, XM_TX_CMD, &Register);
1078 Register |= XM_TX_SAM_LINE;
1079 XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD, Register);
1080 }
1081 break;
1082
1083 case SK_PNMI_HRX_UTILUNDER:
1084 case SK_PNMI_HRX_UTILOVER:
1085 if (MacType == SK_MAC_XMAC) {
1086 XM_IN16(IoC, PhysPortIndex, XM_RX_CMD, &Register);
1087 Register |= XM_RX_SAM_LINE;
1088 XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD, Register);
1089 }
1090 break;
1091
1092 case SK_PNMI_HTX_OCTETHIGH:
1093 case SK_PNMI_HTX_OCTETLOW:
1094 case SK_PNMI_HTX_RESERVED:
1095 case SK_PNMI_HRX_OCTETHIGH:
1096 case SK_PNMI_HRX_OCTETLOW:
1097 case SK_PNMI_HRX_IRLENGTH:
1098 case SK_PNMI_HRX_RESERVED:
1099
1100 /*
1101 * the following counters aren't be handled (id > 63)
1102 */
1103 case SK_PNMI_HTX_SYNC:
1104 case SK_PNMI_HTX_SYNC_OCTET:
1105 break;
1106
1107 case SK_PNMI_HRX_LONGFRAMES:
1108 if (MacType == SK_MAC_GMAC) {
1109 pAC->Pnmi.Port[PhysPortIndex].
1110 CounterHigh[CounterIndex] ++;
1111 }
1112 break;
1113
1114 default:
1115 pAC->Pnmi.Port[PhysPortIndex].
1116 CounterHigh[CounterIndex] ++;
1117 }
1118 }
1119 break;
1120
1121 case SK_PNMI_EVT_SEN_WAR_LOW:
1122 #ifdef DEBUG
1123 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1124
1125 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1126 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n",
1127 (unsigned int)Param.Para64));
1128 return (0);
1129 }
1130 #endif /* DEBUG */
1131
1132 /*
1133 * Store a trap message in the trap buffer and generate
1134 * an event for user space applications with the
1135 * SK_DRIVER_SENDEVENT macro.
1136 */
1137 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW,
1138 (unsigned int)Param.Para64);
1139 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1140 break;
1141
1142 case SK_PNMI_EVT_SEN_WAR_UPP:
1143 #ifdef DEBUG
1144 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1145
1146 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1147 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n",
1148 (unsigned int)Param.Para64));
1149 return (0);
1150 }
1151 #endif /* DEBUG */
1152
1153 /*
1154 * Store a trap message in the trap buffer and generate
1155 * an event for user space applications with the
1156 * SK_DRIVER_SENDEVENT macro.
1157 */
1158 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP,
1159 (unsigned int)Param.Para64);
1160 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1161 break;
1162
1163 case SK_PNMI_EVT_SEN_ERR_LOW:
1164 #ifdef DEBUG
1165 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1166
1167 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1168 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n",
1169 (unsigned int)Param.Para64));
1170 return (0);
1171 }
1172 #endif /* DEBUG */
1173
1174 /*
1175 * Store a trap message in the trap buffer and generate
1176 * an event for user space applications with the
1177 * SK_DRIVER_SENDEVENT macro.
1178 */
1179 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW,
1180 (unsigned int)Param.Para64);
1181 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1182 break;
1183
1184 case SK_PNMI_EVT_SEN_ERR_UPP:
1185 #ifdef DEBUG
1186 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1187
1188 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1189 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
1190 (unsigned int)Param.Para64));
1191 return (0);
1192 }
1193 #endif /* DEBUG */
1194
1195 /*
1196 * Store a trap message in the trap buffer and generate
1197 * an event for user space applications with the
1198 * SK_DRIVER_SENDEVENT macro.
1199 */
1200 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP,
1201 (unsigned int)Param.Para64);
1202 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1203 break;
1204
1205 case SK_PNMI_EVT_CHG_EST_TIMER:
1206 /*
1207 * Calculate port switch average on a per hour basis
1208 * Time interval for check : 28125 ms
1209 * Number of values for average : 8
1210 *
1211 * Be careful in changing these values, on change check
1212 * - typedef of SK_PNMI_ESTIMATE (Size of EstValue
1213 * array one less than value number)
1214 * - Timer initialization SkTimerStart() in SkPnmiInit
1215 * - Delta value below must be multiplicated with
1216 * power of 2
1217 *
1218 */
1219 pEst = &pAC->Pnmi.RlmtChangeEstimate;
1220 CounterIndex = pEst->EstValueIndex + 1;
1221 if (CounterIndex == 7) {
1222
1223 CounterIndex = 0;
1224 }
1225 pEst->EstValueIndex = CounterIndex;
1226
1227 NewestValue = pAC->Pnmi.RlmtChangeCts;
1228 OldestValue = pEst->EstValue[CounterIndex];
1229 pEst->EstValue[CounterIndex] = NewestValue;
1230
1231 /*
1232 * Calculate average. Delta stores the number of
1233 * port switches per 28125 * 8 = 225000 ms
1234 */
1235 if (NewestValue >= OldestValue) {
1236
1237 Delta = NewestValue - OldestValue;
1238 }
1239 else {
1240 /* Overflow situation */
1241 Delta = (SK_U64)(0 - OldestValue) + NewestValue;
1242 }
1243
1244 /*
1245 * Extrapolate delta to port switches per hour.
1246 * Estimate = Delta * (3600000 / 225000)
1247 * = Delta * 16
1248 * = Delta << 4
1249 */
1250 pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4;
1251
1252 /*
1253 * Check if threshold is exceeded. If the threshold is
1254 * permanently exceeded every 28125 ms an event will be
1255 * generated to remind the user of this condition.
1256 */
1257 if ((pAC->Pnmi.RlmtChangeThreshold != 0) &&
1258 (pAC->Pnmi.RlmtChangeEstimate.Estimate >=
1259 pAC->Pnmi.RlmtChangeThreshold)) {
1260
1261 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES);
1262 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1263 }
1264
1265 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
1266 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
1267 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
1268 EventParam);
1269 break;
1270
1271 case SK_PNMI_EVT_CLEAR_COUNTER:
1272 /*
1273 * Param.Para32[0] contains the NetIndex (0 ..1).
1274 * Param.Para32[1] is reserved, contains -1.
1275 */
1276 NetIndex = (SK_U32)Param.Para32[0];
1277
1278 #ifdef DEBUG
1279 if (NetIndex >= pAC->Rlmt.NumNets) {
1280
1281 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1282 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
1283 NetIndex));
1284
1285 return (0);
1286 }
1287 #endif /* DEBUG */
1288
1289 /*
1290 * Set all counters and timestamps to zero.
1291 * The according NetIndex is required as a
1292 * parameter of the event.
1293 */
1294 ResetCounter(pAC, IoC, NetIndex);
1295 break;
1296
1297 case SK_PNMI_EVT_XMAC_RESET:
1298 /*
1299 * To grant continuous counter values store the current
1300 * XMAC statistic values to the entries 1..n of the
1301 * CounterOffset array. XMAC Errata #2
1302 */
1303 #ifdef DEBUG
1304 if ((unsigned int)Param.Para64 >= SK_MAX_MACS) {
1305
1306 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1307 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n",
1308 (unsigned int)Param.Para64));
1309 return (0);
1310 }
1311 #endif
1312 PhysPortIndex = (unsigned int)Param.Para64;
1313
1314 /*
1315 * Update XMAC statistic to get fresh values
1316 */
1317 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
1318 if (Ret != SK_PNMI_ERR_OK) {
1319
1320 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1321 return (0);
1322 }
1323 /*
1324 * Increment semaphore to indicate that an update was
1325 * already done
1326 */
1327 pAC->Pnmi.MacUpdatedFlag ++;
1328
1329 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1330 CounterIndex ++) {
1331
1332 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1333
1334 continue;
1335 }
1336
1337 pAC->Pnmi.Port[PhysPortIndex].CounterOffset[CounterIndex] =
1338 GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1339
1340 pAC->Pnmi.Port[PhysPortIndex].CounterHigh[CounterIndex] = 0;
1341 }
1342
1343 pAC->Pnmi.MacUpdatedFlag --;
1344 break;
1345
1346 case SK_PNMI_EVT_RLMT_PORT_UP:
1347 PhysPortIndex = (unsigned int)Param.Para32[0];
1348 #ifdef DEBUG
1349 if (PhysPortIndex >= SK_MAX_MACS) {
1350
1351 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1352 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter"
1353 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1354
1355 return (0);
1356 }
1357 #endif /* DEBUG */
1358
1359 /*
1360 * Store a trap message in the trap buffer and generate an event for
1361 * user space applications with the SK_DRIVER_SENDEVENT macro.
1362 */
1363 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
1364 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1365
1366 /* Bugfix for XMAC errata (#10620)*/
1367 if (MacType == SK_MAC_XMAC) {
1368 /* Add incremental difference to offset (#10620)*/
1369 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1370 XM_RXE_SHT_ERR, &Val32);
1371
1372 Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1373 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1374 pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
1375 Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
1376 }
1377
1378 /* Tell VctStatus() that a link was up meanwhile. */
1379 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK;
1380 break;
1381
1382 case SK_PNMI_EVT_RLMT_PORT_DOWN:
1383 PhysPortIndex = (unsigned int)Param.Para32[0];
1384
1385 #ifdef DEBUG
1386 if (PhysPortIndex >= SK_MAX_MACS) {
1387
1388 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1389 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter"
1390 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1391
1392 return (0);
1393 }
1394 #endif /* DEBUG */
1395
1396 /*
1397 * Store a trap message in the trap buffer and generate an event for
1398 * user space applications with the SK_DRIVER_SENDEVENT macro.
1399 */
1400 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
1401 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1402
1403 /* Bugfix #10620 - get zero level for incremental difference */
1404 if (MacType == SK_MAC_XMAC) {
1405
1406 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1407 XM_RXE_SHT_ERR, &Val32);
1408
1409 pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark =
1410 (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1411 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1412 }
1413 break;
1414
1415 case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
1416 PhysPortIndex = (unsigned int)Param.Para32[0];
1417 NetIndex = (SK_U32)Param.Para32[1];
1418
1419 #ifdef DEBUG
1420 if (PhysPortIndex >= SK_MAX_MACS) {
1421
1422 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1423 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
1424 PhysPortIndex));
1425 }
1426
1427 if (NetIndex >= pAC->Rlmt.NumNets) {
1428
1429 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1430 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
1431 NetIndex));
1432 }
1433 #endif /* DEBUG */
1434
1435 /*
1436 * For now, ignore event if NetIndex != 0.
1437 */
1438 if (Param.Para32[1] != 0) {
1439
1440 return (0);
1441 }
1442
1443 /*
1444 * Nothing to do if port is already inactive
1445 */
1446 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1447
1448 return (0);
1449 }
1450
1451 /*
1452 * Update statistic counters to calculate new offset for the virtual
1453 * port and increment semaphore to indicate that an update was already
1454 * done.
1455 */
1456 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1457 SK_PNMI_ERR_OK) {
1458
1459 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1460 return (0);
1461 }
1462 pAC->Pnmi.MacUpdatedFlag ++;
1463
1464 /*
1465 * Calculate new counter offset for virtual port to grant continous
1466 * counting on port switches. The virtual port consists of all currently
1467 * active ports. The port down event indicates that a port is removed
1468 * from the virtual port. Therefore add the counter value of the removed
1469 * port to the CounterOffset for the virtual port to grant the same
1470 * counter value.
1471 */
1472 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1473 CounterIndex ++) {
1474
1475 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1476
1477 continue;
1478 }
1479
1480 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1481
1482 pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
1483 }
1484
1485 /*
1486 * Set port to inactive
1487 */
1488 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
1489
1490 pAC->Pnmi.MacUpdatedFlag --;
1491 break;
1492
1493 case SK_PNMI_EVT_RLMT_ACTIVE_UP:
1494 PhysPortIndex = (unsigned int)Param.Para32[0];
1495 NetIndex = (SK_U32)Param.Para32[1];
1496
1497 #ifdef DEBUG
1498 if (PhysPortIndex >= SK_MAX_MACS) {
1499
1500 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1501 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
1502 PhysPortIndex));
1503 }
1504
1505 if (NetIndex >= pAC->Rlmt.NumNets) {
1506
1507 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1508 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
1509 NetIndex));
1510 }
1511 #endif /* DEBUG */
1512
1513 /*
1514 * For now, ignore event if NetIndex != 0.
1515 */
1516 if (Param.Para32[1] != 0) {
1517
1518 return (0);
1519 }
1520
1521 /*
1522 * Nothing to do if port is already active
1523 */
1524 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1525
1526 return (0);
1527 }
1528
1529 /*
1530 * Statistic maintenance
1531 */
1532 pAC->Pnmi.RlmtChangeCts ++;
1533 pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
1534
1535 /*
1536 * Store a trap message in the trap buffer and generate an event for
1537 * user space applications with the SK_DRIVER_SENDEVENT macro.
1538 */
1539 QueueRlmtNewMacTrap(pAC, PhysPortIndex);
1540 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1541
1542 /*
1543 * Update statistic counters to calculate new offset for the virtual
1544 * port and increment semaphore to indicate that an update was
1545 * already done.
1546 */
1547 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1548 SK_PNMI_ERR_OK) {
1549
1550 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1551 return (0);
1552 }
1553 pAC->Pnmi.MacUpdatedFlag ++;
1554
1555 /*
1556 * Calculate new counter offset for virtual port to grant continous
1557 * counting on port switches. A new port is added to the virtual port.
1558 * Therefore substract the counter value of the new port from the
1559 * CounterOffset for the virtual port to grant the same value.
1560 */
1561 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1562 CounterIndex ++) {
1563
1564 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1565
1566 continue;
1567 }
1568
1569 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1570
1571 pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
1572 }
1573
1574 /* Set port to active */
1575 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
1576
1577 pAC->Pnmi.MacUpdatedFlag --;
1578 break;
1579
1580 case SK_PNMI_EVT_RLMT_SEGMENTATION:
1581 /*
1582 * Para.Para32[0] contains the NetIndex.
1583 */
1584
1585 /*
1586 * Store a trap message in the trap buffer and generate an event for
1587 * user space applications with the SK_DRIVER_SENDEVENT macro.
1588 */
1589 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
1590 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1591 break;
1592
1593 case SK_PNMI_EVT_RLMT_SET_NETS:
1594 /*
1595 * Param.Para32[0] contains the number of Nets.
1596 * Param.Para32[1] is reserved, contains -1.
1597 */
1598 /*
1599 * Check number of nets
1600 */
1601 MaxNetNumber = pAC->GIni.GIMacsFound;
1602 if (((unsigned int)Param.Para32[0] < 1)
1603 || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
1604 return (SK_PNMI_ERR_UNKNOWN_NET);
1605 }
1606
1607 if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
1608 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
1609 }
1610 else { /* dual net mode */
1611 pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
1612 }
1613 break;
1614
1615 case SK_PNMI_EVT_VCT_RESET:
1616 PhysPortIndex = Param.Para32[0];
1617 pPrt = &pAC->GIni.GP[PhysPortIndex];
1618 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
1619
1620 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
1621 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
1622 if (RetCode == 2) {
1623 /*
1624 * VCT test is still running.
1625 * Start VCT timer counter again.
1626 */
1627 SK_MEMSET((char *) &Param, 0, sizeof(Param));
1628 Param.Para32[0] = PhysPortIndex;
1629 Param.Para32[1] = -1;
1630 SkTimerStart(pAC, IoC,
1631 &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
1632 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
1633 break;
1634 }
1635 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
1636 pAC->Pnmi.VctStatus[PhysPortIndex] |=
1637 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
1638
1639 /* Copy results for later use to PNMI struct. */
1640 for (i = 0; i < 4; i++) {
1641 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
1642 if ((pPrt->PMdiPairLen[i] > 35) &&
1643 (pPrt->PMdiPairLen[i] < 0xff)) {
1644 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
1645 }
1646 }
1647 if ((pPrt->PMdiPairLen[i] > 35) &&
1648 (pPrt->PMdiPairLen[i] != 0xff)) {
1649 CableLength = 1000 *
1650 (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
1651 }
1652 else {
1653 CableLength = 0;
1654 }
1655 pVctBackupData->PMdiPairLen[i] = CableLength;
1656 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
1657 }
1658
1659 Param.Para32[0] = PhysPortIndex;
1660 Param.Para32[1] = -1;
1661 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
1662 SkEventDispatcher(pAC, IoC);
1663 }
1664
1665 break;
1666
1667 default:
1668 break;
1669 }
1670
1671 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1672 return (0);
1673 }
1674
1675
1676 /******************************************************************************
1677 *
1678 * Private functions
1679 *
1680 */
1681
1682 /*****************************************************************************
1683 *
1684 * PnmiVar - Gets, presets, and sets single OIDs
1685 *
1686 * Description:
1687 * Looks up the requested OID, calls the corresponding handler
1688 * function, and passes the parameters with the get, preset, or
1689 * set command. The function is called by SkGePnmiGetVar,
1690 * SkGePnmiPreSetVar, or SkGePnmiSetVar.
1691 *
1692 * Returns:
1693 * SK_PNMI_ERR_XXX. For details have a look at the description of the
1694 * calling functions.
1695 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
1696 */
PnmiVar(SK_AC * pAC,SK_IOC IoC,int Action,SK_U32 Id,char * pBuf,unsigned int * pLen,SK_U32 Instance,SK_U32 NetIndex)1697 PNMI_STATIC int PnmiVar(
1698 SK_AC *pAC, /* Pointer to adapter context */
1699 SK_IOC IoC, /* IO context handle */
1700 int Action, /* GET/PRESET/SET action */
1701 SK_U32 Id, /* Object ID that is to be processed */
1702 char *pBuf, /* Buffer used for the management data transfer */
1703 unsigned int *pLen, /* Total length of pBuf management data */
1704 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
1705 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1706 {
1707 unsigned int TableIndex;
1708 int Ret;
1709
1710
1711 if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
1712
1713 *pLen = 0;
1714 return (SK_PNMI_ERR_UNKNOWN_OID);
1715 }
1716
1717 /* Check NetIndex */
1718 if (NetIndex >= pAC->Rlmt.NumNets) {
1719 return (SK_PNMI_ERR_UNKNOWN_NET);
1720 }
1721
1722 SK_PNMI_CHECKFLAGS("PnmiVar: On call");
1723
1724 Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
1725 Instance, TableIndex, NetIndex);
1726
1727 SK_PNMI_CHECKFLAGS("PnmiVar: On return");
1728
1729 return (Ret);
1730 }
1731
1732 /*****************************************************************************
1733 *
1734 * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA
1735 *
1736 * Description:
1737 * The return value of the function will also be stored in
1738 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
1739 * SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable,
1740 * checks which OIDs are able to set, and calls the handler function of
1741 * the OID to perform the set. The return value of the function will
1742 * also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
1743 * minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called
1744 * by SkGePnmiPreSetStruct and SkGePnmiSetStruct.
1745 *
1746 * Returns:
1747 * SK_PNMI_ERR_XXX. The codes are described in the calling functions.
1748 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
1749 */
PnmiStruct(SK_AC * pAC,SK_IOC IoC,int Action,char * pBuf,unsigned int * pLen,SK_U32 NetIndex)1750 PNMI_STATIC int PnmiStruct(
1751 SK_AC *pAC, /* Pointer to adapter context */
1752 SK_IOC IoC, /* IO context handle */
1753 int Action, /* PRESET/SET action to be performed */
1754 char *pBuf, /* Buffer used for the management data transfer */
1755 unsigned int *pLen, /* Length of pBuf management data buffer */
1756 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1757 {
1758 int Ret;
1759 unsigned int TableIndex;
1760 unsigned int DstOffset;
1761 unsigned int Len;
1762 unsigned int InstanceNo;
1763 unsigned int InstanceCnt;
1764 SK_U32 Instance;
1765 SK_U32 Id;
1766
1767
1768 /* Check if the passed buffer has the right size */
1769 if (*pLen < SK_PNMI_STRUCT_SIZE) {
1770
1771 /* Check if we can return the error within the buffer */
1772 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
1773
1774 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
1775 (SK_U32)(-1));
1776 }
1777
1778 *pLen = SK_PNMI_STRUCT_SIZE;
1779 return (SK_PNMI_ERR_TOO_SHORT);
1780 }
1781
1782 /* Check NetIndex */
1783 if (NetIndex >= pAC->Rlmt.NumNets) {
1784 return (SK_PNMI_ERR_UNKNOWN_NET);
1785 }
1786
1787 SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
1788
1789 /*
1790 * Update the values of RLMT and SIRQ and increment semaphores to
1791 * indicate that an update was already done.
1792 */
1793 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
1794
1795 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1796 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1797 return (Ret);
1798 }
1799
1800 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
1801
1802 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1803 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1804 return (Ret);
1805 }
1806
1807 pAC->Pnmi.RlmtUpdatedFlag ++;
1808 pAC->Pnmi.SirqUpdatedFlag ++;
1809
1810 /* Preset/Set values */
1811 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
1812
1813 if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
1814 (IdTable[TableIndex].Access != SK_PNMI_WO)) {
1815
1816 continue;
1817 }
1818
1819 InstanceNo = IdTable[TableIndex].InstanceNo;
1820 Id = IdTable[TableIndex].Id;
1821
1822 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
1823 InstanceCnt ++) {
1824
1825 DstOffset = IdTable[TableIndex].Offset +
1826 (InstanceCnt - 1) *
1827 IdTable[TableIndex].StructSize;
1828
1829 /*
1830 * Because VPD multiple instance variables are
1831 * not setable we do not need to evaluate VPD
1832 * instances. Have a look to VPD instance
1833 * calculation in SkPnmiGetStruct().
1834 */
1835 Instance = (SK_U32)InstanceCnt;
1836
1837 /*
1838 * Evaluate needed buffer length
1839 */
1840 Len = 0;
1841 Ret = IdTable[TableIndex].Func(pAC, IoC,
1842 SK_PNMI_GET, IdTable[TableIndex].Id,
1843 NULL, &Len, Instance, TableIndex, NetIndex);
1844
1845 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
1846
1847 break;
1848 }
1849 if (Ret != SK_PNMI_ERR_TOO_SHORT) {
1850
1851 pAC->Pnmi.RlmtUpdatedFlag --;
1852 pAC->Pnmi.SirqUpdatedFlag --;
1853
1854 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1855 SK_PNMI_SET_STAT(pBuf,
1856 SK_PNMI_ERR_GENERAL, DstOffset);
1857 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1858 return (SK_PNMI_ERR_GENERAL);
1859 }
1860 if (Id == OID_SKGE_VPD_ACTION) {
1861
1862 switch (*(pBuf + DstOffset)) {
1863
1864 case SK_PNMI_VPD_CREATE:
1865 Len = 3 + *(pBuf + DstOffset + 3);
1866 break;
1867
1868 case SK_PNMI_VPD_DELETE:
1869 Len = 3;
1870 break;
1871
1872 default:
1873 Len = 1;
1874 break;
1875 }
1876 }
1877
1878 /* Call the OID handler function */
1879 Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
1880 IdTable[TableIndex].Id, pBuf + DstOffset,
1881 &Len, Instance, TableIndex, NetIndex);
1882
1883 if (Ret != SK_PNMI_ERR_OK) {
1884
1885 pAC->Pnmi.RlmtUpdatedFlag --;
1886 pAC->Pnmi.SirqUpdatedFlag --;
1887
1888 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1889 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
1890 DstOffset);
1891 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1892 return (SK_PNMI_ERR_BAD_VALUE);
1893 }
1894 }
1895 }
1896
1897 pAC->Pnmi.RlmtUpdatedFlag --;
1898 pAC->Pnmi.SirqUpdatedFlag --;
1899
1900 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1901 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
1902 return (SK_PNMI_ERR_OK);
1903 }
1904
1905 /*****************************************************************************
1906 *
1907 * LookupId - Lookup an OID in the IdTable
1908 *
1909 * Description:
1910 * Scans the IdTable to find the table entry of an OID.
1911 *
1912 * Returns:
1913 * The table index or -1 if not found.
1914 */
LookupId(SK_U32 Id)1915 PNMI_STATIC int LookupId(
1916 SK_U32 Id) /* Object identifier to be searched */
1917 {
1918 int i;
1919
1920 for (i = 0; i < ID_TABLE_SIZE; i++) {
1921
1922 if (IdTable[i].Id == Id) {
1923
1924 return i;
1925 }
1926 }
1927
1928 return (-1);
1929 }
1930
1931 /*****************************************************************************
1932 *
1933 * OidStruct - Handler of OID_SKGE_ALL_DATA
1934 *
1935 * Description:
1936 * This OID performs a Get/Preset/SetStruct call and returns all data
1937 * in a SK_PNMI_STRUCT_DATA structure.
1938 *
1939 * Returns:
1940 * SK_PNMI_ERR_OK The request was successfully performed.
1941 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1942 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1943 * the correct data (e.g. a 32bit value is
1944 * needed, but a 16 bit value was passed).
1945 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1946 * value range.
1947 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
1948 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1949 * exist (e.g. port instance 3 on a two port
1950 * adapter.
1951 */
OidStruct(SK_AC * pAC,SK_IOC IoC,int Action,SK_U32 Id,char * pBuf,unsigned int * pLen,SK_U32 Instance,unsigned int TableIndex,SK_U32 NetIndex)1952 PNMI_STATIC int OidStruct(
1953 SK_AC *pAC, /* Pointer to adapter context */
1954 SK_IOC IoC, /* IO context handle */
1955 int Action, /* GET/PRESET/SET action */
1956 SK_U32 Id, /* Object ID that is to be processed */
1957 char *pBuf, /* Buffer used for the management data transfer */
1958 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
1959 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
1960 unsigned int TableIndex, /* Index to the Id table */
1961 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1962 {
1963 if (Id != OID_SKGE_ALL_DATA) {
1964
1965 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
1966 SK_PNMI_ERR003MSG);
1967
1968 *pLen = 0;
1969 return (SK_PNMI_ERR_GENERAL);
1970 }
1971
1972 /*
1973 * Check instance. We only handle single instance variables
1974 */
1975 if (Instance != (SK_U32)(-1) && Instance != 1) {
1976
1977 *pLen = 0;
1978 return (SK_PNMI_ERR_UNKNOWN_INST);
1979 }
1980
1981 switch (Action) {
1982
1983 case SK_PNMI_GET:
1984 return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1985
1986 case SK_PNMI_PRESET:
1987 return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1988
1989 case SK_PNMI_SET:
1990 return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1991 }
1992
1993 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
1994
1995 *pLen = 0;
1996 return (SK_PNMI_ERR_GENERAL);
1997 }
1998
1999 /*****************************************************************************
2000 *
2001 * Perform - OID handler of OID_SKGE_ACTION
2002 *
2003 * Description:
2004 * None.
2005 *
2006 * Returns:
2007 * SK_PNMI_ERR_OK The request was successfully performed.
2008 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2009 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2010 * the correct data (e.g. a 32bit value is
2011 * needed, but a 16 bit value was passed).
2012 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2013 * value range.
2014 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2015 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2016 * exist (e.g. port instance 3 on a two port
2017 * adapter.
2018 */
Perform(SK_AC * pAC,SK_IOC IoC,int Action,SK_U32 Id,char * pBuf,unsigned int * pLen,SK_U32 Instance,unsigned int TableIndex,SK_U32 NetIndex)2019 PNMI_STATIC int Perform(
2020 SK_AC *pAC, /* Pointer to adapter context */
2021 SK_IOC IoC, /* IO context handle */
2022 int Action, /* GET/PRESET/SET action */
2023 SK_U32 Id, /* Object ID that is to be processed */
2024 char *pBuf, /* Buffer used for the management data transfer */
2025 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2026 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2027 unsigned int TableIndex, /* Index to the Id table */
2028 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2029 {
2030 int Ret;
2031 SK_U32 ActionOp;
2032
2033
2034 /*
2035 * Check instance. We only handle single instance variables
2036 */
2037 if (Instance != (SK_U32)(-1) && Instance != 1) {
2038
2039 *pLen = 0;
2040 return (SK_PNMI_ERR_UNKNOWN_INST);
2041 }
2042
2043 if (*pLen < sizeof(SK_U32)) {
2044
2045 *pLen = sizeof(SK_U32);
2046 return (SK_PNMI_ERR_TOO_SHORT);
2047 }
2048
2049 /* Check if a get should be performed */
2050 if (Action == SK_PNMI_GET) {
2051
2052 /* A get is easy. We always return the same value */
2053 ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
2054 SK_PNMI_STORE_U32(pBuf, ActionOp);
2055 *pLen = sizeof(SK_U32);
2056
2057 return (SK_PNMI_ERR_OK);
2058 }
2059
2060 /* Continue with PRESET/SET action */
2061 if (*pLen > sizeof(SK_U32)) {
2062
2063 return (SK_PNMI_ERR_BAD_VALUE);
2064 }
2065
2066 /* Check if the command is a known one */
2067 SK_PNMI_READ_U32(pBuf, ActionOp);
2068 if (*pLen > sizeof(SK_U32) ||
2069 (ActionOp != SK_PNMI_ACT_IDLE &&
2070 ActionOp != SK_PNMI_ACT_RESET &&
2071 ActionOp != SK_PNMI_ACT_SELFTEST &&
2072 ActionOp != SK_PNMI_ACT_RESETCNT)) {
2073
2074 *pLen = 0;
2075 return (SK_PNMI_ERR_BAD_VALUE);
2076 }
2077
2078 /* A preset ends here */
2079 if (Action == SK_PNMI_PRESET) {
2080
2081 return (SK_PNMI_ERR_OK);
2082 }
2083
2084 switch (ActionOp) {
2085
2086 case SK_PNMI_ACT_IDLE:
2087 /* Nothing to do */
2088 break;
2089
2090 case SK_PNMI_ACT_RESET:
2091 /*
2092 * Perform a driver reset or something that comes near
2093 * to this.
2094 */
2095 Ret = SK_DRIVER_RESET(pAC, IoC);
2096 if (Ret != 0) {
2097
2098 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
2099 SK_PNMI_ERR005MSG);
2100
2101 return (SK_PNMI_ERR_GENERAL);
2102 }
2103 break;
2104
2105 case SK_PNMI_ACT_SELFTEST:
2106 /*
2107 * Perform a driver selftest or something similar to this.
2108 * Currently this feature is not used and will probably
2109 * implemented in another way.
2110 */
2111 Ret = SK_DRIVER_SELFTEST(pAC, IoC);
2112 pAC->Pnmi.TestResult = Ret;
2113 break;
2114
2115 case SK_PNMI_ACT_RESETCNT:
2116 /* Set all counters and timestamps to zero */
2117 ResetCounter(pAC, IoC, NetIndex);
2118 break;
2119
2120 default:
2121 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
2122 SK_PNMI_ERR006MSG);
2123
2124 return (SK_PNMI_ERR_GENERAL);
2125 }
2126
2127 return (SK_PNMI_ERR_OK);
2128 }
2129
2130 /*****************************************************************************
2131 *
2132 * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX
2133 *
2134 * Description:
2135 * Retrieves the statistic values of the virtual port (logical
2136 * index 0). Only special OIDs of NDIS are handled which consist
2137 * of a 32 bit instead of a 64 bit value. The OIDs are public
2138 * because perhaps some other platform can use them too.
2139 *
2140 * Returns:
2141 * SK_PNMI_ERR_OK The request was successfully performed.
2142 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2143 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2144 * the correct data (e.g. a 32bit value is
2145 * needed, but a 16 bit value was passed).
2146 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2147 * exist (e.g. port instance 3 on a two port
2148 * adapter.
2149 */
Mac8023Stat(SK_AC * pAC,SK_IOC IoC,int Action,SK_U32 Id,char * pBuf,unsigned int * pLen,SK_U32 Instance,unsigned int TableIndex,SK_U32 NetIndex)2150 PNMI_STATIC int Mac8023Stat(
2151 SK_AC *pAC, /* Pointer to adapter context */
2152 SK_IOC IoC, /* IO context handle */
2153 int Action, /* GET/PRESET/SET action */
2154 SK_U32 Id, /* Object ID that is to be processed */
2155 char *pBuf, /* Buffer used for the management data transfer */
2156 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2157 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2158 unsigned int TableIndex, /* Index to the Id table */
2159 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2160 {
2161 int Ret;
2162 SK_U64 StatVal;
2163 SK_U32 StatVal32;
2164 SK_BOOL Is64BitReq = SK_FALSE;
2165
2166 /*
2167 * Only the active Mac is returned
2168 */
2169 if (Instance != (SK_U32)(-1) && Instance != 1) {
2170
2171 *pLen = 0;
2172 return (SK_PNMI_ERR_UNKNOWN_INST);
2173 }
2174
2175 /*
2176 * Check action type
2177 */
2178 if (Action != SK_PNMI_GET) {
2179
2180 *pLen = 0;
2181 return (SK_PNMI_ERR_READ_ONLY);
2182 }
2183
2184 /* Check length */
2185 switch (Id) {
2186
2187 case OID_802_3_PERMANENT_ADDRESS:
2188 case OID_802_3_CURRENT_ADDRESS:
2189 if (*pLen < sizeof(SK_MAC_ADDR)) {
2190
2191 *pLen = sizeof(SK_MAC_ADDR);
2192 return (SK_PNMI_ERR_TOO_SHORT);
2193 }
2194 break;
2195
2196 default:
2197 #ifndef SK_NDIS_64BIT_CTR
2198 if (*pLen < sizeof(SK_U32)) {
2199 *pLen = sizeof(SK_U32);
2200 return (SK_PNMI_ERR_TOO_SHORT);
2201 }
2202
2203 #else /* SK_NDIS_64BIT_CTR */
2204
2205 /* for compatibility, at least 32bit are required for OID */
2206 if (*pLen < sizeof(SK_U32)) {
2207 /*
2208 * but indicate handling for 64bit values,
2209 * if insufficient space is provided
2210 */
2211 *pLen = sizeof(SK_U64);
2212 return (SK_PNMI_ERR_TOO_SHORT);
2213 }
2214
2215 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
2216 #endif /* SK_NDIS_64BIT_CTR */
2217 break;
2218 }
2219
2220 /*
2221 * Update all statistics, because we retrieve virtual MAC, which
2222 * consists of multiple physical statistics and increment semaphore
2223 * to indicate that an update was already done.
2224 */
2225 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2226 if ( Ret != SK_PNMI_ERR_OK) {
2227
2228 *pLen = 0;
2229 return (Ret);
2230 }
2231 pAC->Pnmi.MacUpdatedFlag ++;
2232
2233 /*
2234 * Get value (MAC Index 0 identifies the virtual MAC)
2235 */
2236 switch (Id) {
2237
2238 case OID_802_3_PERMANENT_ADDRESS:
2239 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2240 *pLen = sizeof(SK_MAC_ADDR);
2241 break;
2242
2243 case OID_802_3_CURRENT_ADDRESS:
2244 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2245 *pLen = sizeof(SK_MAC_ADDR);
2246 break;
2247
2248 default:
2249 StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
2250
2251 /* by default 32bit values are evaluated */
2252 if (!Is64BitReq) {
2253 StatVal32 = (SK_U32)StatVal;
2254 SK_PNMI_STORE_U32(pBuf, StatVal32);
2255 *pLen = sizeof(SK_U32);
2256 }
2257 else {
2258 SK_PNMI_STORE_U64(pBuf, StatVal);
2259 *pLen = sizeof(SK_U64);
2260 }
2261 break;
2262 }
2263
2264 pAC->Pnmi.MacUpdatedFlag --;
2265
2266 return (SK_PNMI_ERR_OK);
2267 }
2268
2269 /*****************************************************************************
2270 *
2271 * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX
2272 *
2273 * Description:
2274 * Retrieves the MAC statistic data.
2275 *
2276 * Returns:
2277 * SK_PNMI_ERR_OK The request was successfully performed.
2278 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2279 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2280 * the correct data (e.g. a 32bit value is
2281 * needed, but a 16 bit value was passed).
2282 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2283 * exist (e.g. port instance 3 on a two port
2284 * adapter.
2285 */
MacPrivateStat(SK_AC * pAC,SK_IOC IoC,int Action,SK_U32 Id,char * pBuf,unsigned int * pLen,SK_U32 Instance,unsigned int TableIndex,SK_U32 NetIndex)2286 PNMI_STATIC int MacPrivateStat(
2287 SK_AC *pAC, /* Pointer to adapter context */
2288 SK_IOC IoC, /* IO context handle */
2289 int Action, /* GET/PRESET/SET action */
2290 SK_U32 Id, /* Object ID that is to be processed */
2291 char *pBuf, /* Buffer used for the management data transfer */
2292 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2293 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2294 unsigned int TableIndex, /* Index to the Id table */
2295 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2296 {
2297 unsigned int LogPortMax;
2298 unsigned int LogPortIndex;
2299 unsigned int PhysPortMax;
2300 unsigned int Limit;
2301 unsigned int Offset;
2302 int MacType;
2303 int Ret;
2304 SK_U64 StatVal;
2305
2306
2307
2308 /* Calculate instance if wished. MAC index 0 is the virtual MAC */
2309 PhysPortMax = pAC->GIni.GIMacsFound;
2310 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2311
2312 MacType = pAC->GIni.GIMacType;
2313
2314 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2315 LogPortMax--;
2316 }
2317
2318 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2319 /* Check instance range */
2320 if ((Instance < 1) || (Instance > LogPortMax)) {
2321
2322 *pLen = 0;
2323 return (SK_PNMI_ERR_UNKNOWN_INST);
2324 }
2325 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2326 Limit = LogPortIndex + 1;
2327 }
2328
2329 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2330
2331 LogPortIndex = 0;
2332 Limit = LogPortMax;
2333 }
2334
2335 /* Check action */
2336 if (Action != SK_PNMI_GET) {
2337
2338 *pLen = 0;
2339 return (SK_PNMI_ERR_READ_ONLY);
2340 }
2341
2342 /* Check length */
2343 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
2344
2345 *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
2346 return (SK_PNMI_ERR_TOO_SHORT);
2347 }
2348
2349 /*
2350 * Update MAC statistic and increment semaphore to indicate that
2351 * an update was already done.
2352 */
2353 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2354 if (Ret != SK_PNMI_ERR_OK) {
2355
2356 *pLen = 0;
2357 return (Ret);
2358 }
2359 pAC->Pnmi.MacUpdatedFlag ++;
2360
2361 /* Get value */
2362 Offset = 0;
2363 for (; LogPortIndex < Limit; LogPortIndex ++) {
2364
2365 switch (Id) {
2366
2367 /* XXX not yet implemented due to XMAC problems
2368 case OID_SKGE_STAT_TX_UTIL:
2369 return (SK_PNMI_ERR_GENERAL);
2370 */
2371 /* XXX not yet implemented due to XMAC problems
2372 case OID_SKGE_STAT_RX_UTIL:
2373 return (SK_PNMI_ERR_GENERAL);
2374 */
2375 case OID_SKGE_STAT_RX:
2376 if (MacType == SK_MAC_GMAC) {
2377 StatVal =
2378 GetStatVal(pAC, IoC, LogPortIndex,
2379 SK_PNMI_HRX_BROADCAST, NetIndex) +
2380 GetStatVal(pAC, IoC, LogPortIndex,
2381 SK_PNMI_HRX_MULTICAST, NetIndex) +
2382 GetStatVal(pAC, IoC, LogPortIndex,
2383 SK_PNMI_HRX_UNICAST, NetIndex) +
2384 GetStatVal(pAC, IoC, LogPortIndex,
2385 SK_PNMI_HRX_UNDERSIZE, NetIndex);
2386 }
2387 else {
2388 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2389 IdTable[TableIndex].Param, NetIndex);
2390 }
2391 break;
2392
2393 case OID_SKGE_STAT_TX:
2394 if (MacType == SK_MAC_GMAC) {
2395 StatVal =
2396 GetStatVal(pAC, IoC, LogPortIndex,
2397 SK_PNMI_HTX_BROADCAST, NetIndex) +
2398 GetStatVal(pAC, IoC, LogPortIndex,
2399 SK_PNMI_HTX_MULTICAST, NetIndex) +
2400 GetStatVal(pAC, IoC, LogPortIndex,
2401 SK_PNMI_HTX_UNICAST, NetIndex);
2402 }
2403 else {
2404 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2405 IdTable[TableIndex].Param, NetIndex);
2406 }
2407 break;
2408
2409 default:
2410 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2411 IdTable[TableIndex].Param, NetIndex);
2412 }
2413 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2414
2415 Offset += sizeof(SK_U64);
2416 }
2417 *pLen = Offset;
2418
2419 pAC->Pnmi.MacUpdatedFlag --;
2420
2421 return (SK_PNMI_ERR_OK);
2422 }
2423
2424 /*****************************************************************************
2425 *
2426 * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR
2427 *
2428 * Description:
2429 * Get/Presets/Sets the current and factory MAC address. The MAC
2430 * address of the virtual port, which is reported to the OS, may
2431 * not be changed, but the physical ones. A set to the virtual port
2432 * will be ignored. No error should be reported because otherwise
2433 * a multiple instance set (-1) would always fail.
2434 *
2435 * Returns:
2436 * SK_PNMI_ERR_OK The request was successfully performed.
2437 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2438 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2439 * the correct data (e.g. a 32bit value is
2440 * needed, but a 16 bit value was passed).
2441 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2442 * value range.
2443 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2444 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2445 * exist (e.g. port instance 3 on a two port
2446 * adapter.
2447 */
Addr(SK_AC * pAC,SK_IOC IoC,int Action,SK_U32 Id,char * pBuf,unsigned int * pLen,SK_U32 Instance,unsigned int TableIndex,SK_U32 NetIndex)2448 PNMI_STATIC int Addr(
2449 SK_AC *pAC, /* Pointer to adapter context */
2450 SK_IOC IoC, /* IO context handle */
2451 int Action, /* GET/PRESET/SET action */
2452 SK_U32 Id, /* Object ID that is to be processed */
2453 char *pBuf, /* Buffer used for the management data transfer */
2454 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2455 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2456 unsigned int TableIndex, /* Index to the Id table */
2457 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2458 {
2459 int Ret;
2460 unsigned int LogPortMax;
2461 unsigned int PhysPortMax;
2462 unsigned int LogPortIndex;
2463 unsigned int PhysPortIndex;
2464 unsigned int Limit;
2465 unsigned int Offset = 0;
2466
2467 /*
2468 * Calculate instance if wished. MAC index 0 is the virtual
2469 * MAC.
2470 */
2471 PhysPortMax = pAC->GIni.GIMacsFound;
2472 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2473
2474 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2475 LogPortMax--;
2476 }
2477
2478 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2479 /* Check instance range */
2480 if ((Instance < 1) || (Instance > LogPortMax)) {
2481
2482 *pLen = 0;
2483 return (SK_PNMI_ERR_UNKNOWN_INST);
2484 }
2485 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2486 Limit = LogPortIndex + 1;
2487 }
2488 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2489
2490 LogPortIndex = 0;
2491 Limit = LogPortMax;
2492 }
2493
2494 /*
2495 * Perform Action
2496 */
2497 if (Action == SK_PNMI_GET) {
2498
2499 /* Check length */
2500 if (*pLen < (Limit - LogPortIndex) * 6) {
2501
2502 *pLen = (Limit - LogPortIndex) * 6;
2503 return (SK_PNMI_ERR_TOO_SHORT);
2504 }
2505
2506 /*
2507 * Get value
2508 */
2509 for (; LogPortIndex < Limit; LogPortIndex ++) {
2510
2511 switch (Id) {
2512
2513 case OID_SKGE_PHYS_CUR_ADDR:
2514 if (LogPortIndex == 0) {
2515 CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2516 }
2517 else {
2518 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
2519
2520 CopyMac(pBuf + Offset,
2521 &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
2522 }
2523 Offset += 6;
2524 break;
2525
2526 case OID_SKGE_PHYS_FAC_ADDR:
2527 if (LogPortIndex == 0) {
2528 CopyMac(pBuf + Offset,
2529 &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2530 }
2531 else {
2532 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
2533 pAC, LogPortIndex);
2534
2535 CopyMac(pBuf + Offset,
2536 &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
2537 }
2538 Offset += 6;
2539 break;
2540
2541 default:
2542 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
2543 SK_PNMI_ERR008MSG);
2544
2545 *pLen = 0;
2546 return (SK_PNMI_ERR_GENERAL);
2547 }
2548 }
2549
2550 *pLen = Offset;
2551 }
2552 else {
2553 /*
2554 * The logical MAC address may not be changed only
2555 * the physical ones
2556 */
2557 if (Id == OID_SKGE_PHYS_FAC_ADDR) {
2558
2559 *pLen = 0;
2560 return (SK_PNMI_ERR_READ_ONLY);
2561 }
2562
2563 /*
2564 * Only the current address may be changed
2565 */
2566 if (Id != OID_SKGE_PHYS_CUR_ADDR) {
2567
2568 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
2569 SK_PNMI_ERR009MSG);
2570
2571 *pLen = 0;
2572 return (SK_PNMI_ERR_GENERAL);
2573 }
2574
2575 /* Check length */
2576 if (*pLen < (Limit - LogPortIndex) * 6) {
2577
2578 *pLen = (Limit - LogPortIndex) * 6;
2579 return (SK_PNMI_ERR_TOO_SHORT);
2580 }
2581 if (*pLen > (Limit - LogPortIndex) * 6) {
2582
2583 *pLen = 0;
2584 return (SK_PNMI_ERR_BAD_VALUE);
2585 }
2586
2587 /*
2588 * Check Action
2589 */
2590 if (Action == SK_PNMI_PRESET) {
2591
2592 *pLen = 0;
2593 return (SK_PNMI_ERR_OK);
2594 }
2595
2596 /*
2597 * Set OID_SKGE_MAC_CUR_ADDR
2598 */
2599 for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
2600
2601 /*
2602 * A set to virtual port and set of broadcast
2603 * address will be ignored
2604 */
2605 if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
2606 "\xff\xff\xff\xff\xff\xff", 6) == 0) {
2607
2608 continue;
2609 }
2610
2611 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
2612 LogPortIndex);
2613
2614 Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
2615 (SK_MAC_ADDR *)(pBuf + Offset),
2616 (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
2617 SK_ADDR_PHYSICAL_ADDRESS));
2618 if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {
2619
2620 return (SK_PNMI_ERR_GENERAL);
2621 }
2622 }
2623 *pLen = Offset;
2624 }
2625
2626 return (SK_PNMI_ERR_OK);
2627 }
2628
2629 /*****************************************************************************
2630 *
2631 * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
2632 *
2633 * Description:
2634 * Retrieves the statistic values of the CSUM module. The CSUM data
2635 * structure must be available in the SK_AC even if the CSUM module
2636 * is not included, because PNMI reads the statistic data from the
2637 * CSUM part of SK_AC directly.
2638 *
2639 * Returns:
2640 * SK_PNMI_ERR_OK The request was successfully performed.
2641 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2642 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2643 * the correct data (e.g. a 32bit value is
2644 * needed, but a 16 bit value was passed).
2645 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2646 * exist (e.g. port instance 3 on a two port
2647 * adapter.
2648 */
CsumStat(SK_AC * pAC,SK_IOC IoC,int Action,SK_U32 Id,char * pBuf,unsigned int * pLen,SK_U32 Instance,unsigned int TableIndex,SK_U32 NetIndex)2649 PNMI_STATIC int CsumStat(
2650 SK_AC *pAC, /* Pointer to adapter context */
2651 SK_IOC IoC, /* IO context handle */
2652 int Action, /* GET/PRESET/SET action */
2653 SK_U32 Id, /* Object ID that is to be processed */
2654 char *pBuf, /* Buffer used for the management data transfer */
2655 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2656 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2657 unsigned int TableIndex, /* Index to the Id table */
2658 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2659 {
2660 unsigned int Index;
2661 unsigned int Limit;
2662 unsigned int Offset = 0;
2663 SK_U64 StatVal;
2664
2665
2666 /*
2667 * Calculate instance if wished
2668 */
2669 if (Instance != (SK_U32)(-1)) {
2670
2671 if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
2672
2673 *pLen = 0;
2674 return (SK_PNMI_ERR_UNKNOWN_INST);
2675 }
2676 Index = (unsigned int)Instance - 1;
2677 Limit = Index + 1;
2678 }
2679 else {
2680 Index = 0;
2681 Limit = SKCS_NUM_PROTOCOLS;
2682 }
2683
2684 /*
2685 * Check action
2686 */
2687 if (Action != SK_PNMI_GET) {
2688
2689 *pLen = 0;
2690 return (SK_PNMI_ERR_READ_ONLY);
2691 }
2692
2693 /* Check length */
2694 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
2695
2696 *pLen = (Limit - Index) * sizeof(SK_U64);
2697 return (SK_PNMI_ERR_TOO_SHORT);
2698 }
2699
2700 /*
2701 * Get value
2702 */
2703 for (; Index < Limit; Index ++) {
2704
2705 switch (Id) {
2706
2707 case OID_SKGE_CHKSM_RX_OK_CTS:
2708 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
2709 break;
2710
2711 case OID_SKGE_CHKSM_RX_UNABLE_CTS:
2712 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
2713 break;
2714
2715 case OID_SKGE_CHKSM_RX_ERR_CTS:
2716 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
2717 break;
2718
2719 case OID_SKGE_CHKSM_TX_OK_CTS:
2720 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
2721 break;
2722
2723 case OID_SKGE_CHKSM_TX_UNABLE_CTS:
2724 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
2725 break;
2726
2727 default:
2728 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
2729 SK_PNMI_ERR010MSG);
2730
2731 *pLen = 0;
2732 return (SK_PNMI_ERR_GENERAL);
2733 }
2734
2735 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2736 Offset += sizeof(SK_U64);
2737 }
2738
2739 /*
2740 * Store used buffer space
2741 */
2742 *pLen = Offset;
2743
2744 return (SK_PNMI_ERR_OK);
2745 }
2746
2747 /*****************************************************************************
2748 *
2749 * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
2750 *
2751 * Description:
2752 * Retrieves the statistic values of the I2C module, which handles
2753 * the temperature and voltage sensors.
2754 *
2755 * Returns:
2756 * SK_PNMI_ERR_OK The request was successfully performed.
2757 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2758 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2759 * the correct data (e.g. a 32bit value is
2760 * needed, but a 16 bit value was passed).
2761 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2762 * exist (e.g. port instance 3 on a two port
2763 * adapter.
2764 */
SensorStat(SK_AC * pAC,SK_IOC IoC,int Action,SK_U32 Id,char * pBuf,unsigned int * pLen,SK_U32 Instance,unsigned int TableIndex,SK_U32 NetIndex)2765 PNMI_STATIC int SensorStat(
2766 SK_AC *pAC, /* Pointer to adapter context */
2767 SK_IOC IoC, /* IO context handle */
2768 int Action, /* GET/PRESET/SET action */
2769 SK_U32 Id, /* Object ID that is to be processed */
2770 char *pBuf, /* Buffer used for the management data transfer */
2771 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2772 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2773 unsigned int TableIndex, /* Index to the Id table */
2774 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2775 {
2776 unsigned int i;
2777 unsigned int Index;
2778 unsigned int Limit;
2779 unsigned int Offset;
2780 unsigned int Len;
2781 SK_U32 Val32;
2782 SK_U64 Val64;
2783
2784
2785 /*
2786 * Calculate instance if wished
2787 */
2788 if ((Instance != (SK_U32)(-1))) {
2789
2790 if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
2791
2792 *pLen = 0;
2793 return (SK_PNMI_ERR_UNKNOWN_INST);
2794 }
2795
2796 Index = (unsigned int)Instance -1;
2797 Limit = (unsigned int)Instance;
2798 }
2799 else {
2800 Index = 0;
2801 Limit = (unsigned int) pAC->I2c.MaxSens;
2802 }
2803
2804 /*
2805 * Check action
2806 */
2807 if (Action != SK_PNMI_GET) {
2808
2809 *pLen = 0;
2810 return (SK_PNMI_ERR_READ_ONLY);
2811 }
2812
2813 /* Check length */
2814 switch (Id) {
2815
2816 case OID_SKGE_SENSOR_VALUE:
2817 case OID_SKGE_SENSOR_WAR_THRES_LOW:
2818 case OID_SKGE_SENSOR_WAR_THRES_UPP:
2819 case OID_SKGE_SENSOR_ERR_THRES_LOW:
2820 case OID_SKGE_SENSOR_ERR_THRES_UPP:
2821 if (*pLen < (Limit - Index) * sizeof(SK_U32)) {
2822
2823 *pLen = (Limit - Index) * sizeof(SK_U32);
2824 return (SK_PNMI_ERR_TOO_SHORT);
2825 }
2826 break;
2827
2828 case OID_SKGE_SENSOR_DESCR:
2829 for (Offset = 0, i = Index; i < Limit; i ++) {
2830
2831 Len = (unsigned int)
2832 SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1;
2833 if (Len >= SK_PNMI_STRINGLEN2) {
2834
2835 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011,
2836 SK_PNMI_ERR011MSG);
2837
2838 *pLen = 0;
2839 return (SK_PNMI_ERR_GENERAL);
2840 }
2841 Offset += Len;
2842 }
2843 if (*pLen < Offset) {
2844
2845 *pLen = Offset;
2846 return (SK_PNMI_ERR_TOO_SHORT);
2847 }
2848 break;
2849
2850 case OID_SKGE_SENSOR_INDEX:
2851 case OID_SKGE_SENSOR_TYPE:
2852 case OID_SKGE_SENSOR_STATUS:
2853 if (*pLen < Limit - Index) {
2854
2855 *pLen = Limit - Index;
2856 return (SK_PNMI_ERR_TOO_SHORT);
2857 }
2858 break;
2859
2860 case OID_SKGE_SENSOR_WAR_CTS:
2861 case OID_SKGE_SENSOR_WAR_TIME:
2862 case OID_SKGE_SENSOR_ERR_CTS:
2863 case OID_SKGE_SENSOR_ERR_TIME:
2864 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
2865
2866 *pLen = (Limit - Index) * sizeof(SK_U64);
2867 return (SK_PNMI_ERR_TOO_SHORT);
2868 }
2869 break;
2870
2871 default:
2872 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
2873 SK_PNMI_ERR012MSG);
2874
2875 *pLen = 0;
2876 return (SK_PNMI_ERR_GENERAL);
2877
2878 }
2879
2880 /*
2881 * Get value
2882 */
2883 for (Offset = 0; Index < Limit; Index ++) {
2884
2885 switch (Id) {
2886
2887 case OID_SKGE_SENSOR_INDEX:
2888 *(pBuf + Offset) = (char)Index;
2889 Offset += sizeof(char);
2890 break;
2891
2892 case OID_SKGE_SENSOR_DESCR:
2893 Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
2894 SK_MEMCPY(pBuf + Offset + 1,
2895 pAC->I2c.SenTable[Index].SenDesc, Len);
2896 *(pBuf + Offset) = (char)Len;
2897 Offset += Len + 1;
2898 break;
2899
2900 case OID_SKGE_SENSOR_TYPE:
2901 *(pBuf + Offset) =
2902 (char)pAC->I2c.SenTable[Index].SenType;
2903 Offset += sizeof(char);
2904 break;
2905
2906 case OID_SKGE_SENSOR_VALUE:
2907 Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
2908 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2909 Offset += sizeof(SK_U32);
2910 break;
2911
2912 case OID_SKGE_SENSOR_WAR_THRES_LOW:
2913 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2914 SenThreWarnLow;
2915 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2916 Offset += sizeof(SK_U32);
2917 break;
2918
2919 case OID_SKGE_SENSOR_WAR_THRES_UPP:
2920 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2921 SenThreWarnHigh;
2922 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2923 Offset += sizeof(SK_U32);
2924 break;
2925
2926 case OID_SKGE_SENSOR_ERR_THRES_LOW:
2927 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2928 SenThreErrLow;
2929 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2930 Offset += sizeof(SK_U32);
2931 break;
2932
2933 case OID_SKGE_SENSOR_ERR_THRES_UPP:
2934 Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
2935 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2936 Offset += sizeof(SK_U32);
2937 break;
2938
2939 case OID_SKGE_SENSOR_STATUS:
2940 *(pBuf + Offset) =
2941 (char)pAC->I2c.SenTable[Index].SenErrFlag;
2942 Offset += sizeof(char);
2943 break;
2944
2945 case OID_SKGE_SENSOR_WAR_CTS:
2946 Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
2947 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2948 Offset += sizeof(SK_U64);
2949 break;
2950
2951 case OID_SKGE_SENSOR_ERR_CTS:
2952 Val64 = pAC->I2c.SenTable[Index].SenErrCts;
2953 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2954 Offset += sizeof(SK_U64);
2955 break;
2956
2957 case OID_SKGE_SENSOR_WAR_TIME:
2958 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
2959 SenBegWarnTS);
2960 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2961 Offset += sizeof(SK_U64);
2962 break;
2963
2964 case OID_SKGE_SENSOR_ERR_TIME:
2965 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
2966 SenBegErrTS);
2967 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2968 Offset += sizeof(SK_U64);
2969 break;
2970
2971 default:
2972 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
2973 ("SensorStat: Unknown OID should be handled before"));
2974
2975 return (SK_PNMI_ERR_GENERAL);
2976 }
2977 }
2978
2979 /*
2980 * Store used buffer space
2981 */
2982 *pLen = Offset;
2983
2984 return (SK_PNMI_ERR_OK);
2985 }
2986
2987 /*****************************************************************************
2988 *
2989 * Vpd - OID handler function of OID_SKGE_VPD_XXX
2990 *
2991 * Description:
2992 * Get/preset/set of VPD data. As instance the name of a VPD key
2993 * can be passed. The Instance parameter is a SK_U32 and can be
2994 * used as a string buffer for the VPD key, because their maximum
2995 * length is 4 byte.
2996 *
2997 * Returns:
2998 * SK_PNMI_ERR_OK The request was successfully performed.
2999 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3000 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3001 * the correct data (e.g. a 32bit value is
3002 * needed, but a 16 bit value was passed).
3003 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
3004 * value range.
3005 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
3006 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3007 * exist (e.g. port instance 3 on a two port
3008 * adapter.
3009 */
Vpd(SK_AC * pAC,SK_IOC IoC,int Action,SK_U32 Id,char * pBuf,unsigned int * pLen,SK_U32 Instance,unsigned int TableIndex,SK_U32 NetIndex)3010 PNMI_STATIC int Vpd(
3011 SK_AC *pAC, /* Pointer to adapter context */
3012 SK_IOC IoC, /* IO context handle */
3013 int Action, /* GET/PRESET/SET action */
3014 SK_U32 Id, /* Object ID that is to be processed */
3015 char *pBuf, /* Buffer used for the management data transfer */
3016 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
3017 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3018 unsigned int TableIndex, /* Index to the Id table */
3019 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
3020 {
3021 SK_VPD_STATUS *pVpdStatus;
3022 unsigned int BufLen;
3023 char Buf[256];
3024 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
3025 char KeyStr[SK_PNMI_VPD_KEY_SIZE];
3026 unsigned int KeyNo;
3027 unsigned int Offset;
3028 unsigned int Index;
3029 unsigned int FirstIndex;
3030 unsigned int LastIndex;
3031 unsigned int Len;
3032 int Ret;
3033 SK_U32 Val32;
3034
3035 /*
3036 * Get array of all currently stored VPD keys
3037 */
3038 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &KeyNo);
3039 if (Ret != SK_PNMI_ERR_OK) {
3040 *pLen = 0;
3041 return (Ret);
3042 }
3043
3044 /*
3045 * If instance is not -1, try to find the requested VPD key for
3046 * the multiple instance variables. The other OIDs as for example
3047 * OID VPD_ACTION are single instance variables and must be
3048 * handled separatly.
3049 */
3050 FirstIndex = 0;
3051 LastIndex = KeyNo;
3052
3053 if ((Instance != (SK_U32)(-1))) {
3054
3055 if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
3056 Id == OID_SKGE_VPD_ACCESS) {
3057
3058 SK_STRNCPY(KeyStr, (char *)&Instance, 4);
3059 KeyStr[4] = 0;
3060
3061 for (Index = 0; Index < KeyNo; Index ++) {
3062
3063 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3064 FirstIndex = Index;
3065 LastIndex = Index+1;
3066 break;
3067 }
3068 }
3069 if (Index == KeyNo) {
3070
3071 *pLen = 0;
3072 return (SK_PNMI_ERR_UNKNOWN_INST);
3073 }
3074 }
3075 else if (Instance != 1) {
3076
3077 *pLen = 0;
3078 return (SK_PNMI_ERR_UNKNOWN_INST);
3079 }
3080 }
3081
3082 /*
3083 * Get value, if a query should be performed
3084 */
3085 if (Action == SK_PNMI_GET) {
3086
3087 switch (Id) {
3088
3089 case OID_SKGE_VPD_FREE_BYTES:
3090 /* Check length of buffer */
3091 if (*pLen < sizeof(SK_U32)) {
3092
3093 *pLen = sizeof(SK_U32);
3094 return (SK_PNMI_ERR_TOO_SHORT);
3095 }
3096 /* Get number of free bytes */
3097 pVpdStatus = VpdStat(pAC, IoC);
3098 if (pVpdStatus == NULL) {
3099
3100 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
3101 SK_PNMI_ERR017MSG);
3102
3103 *pLen = 0;
3104 return (SK_PNMI_ERR_GENERAL);
3105 }
3106 if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
3107
3108 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
3109 SK_PNMI_ERR018MSG);
3110
3111 *pLen = 0;
3112 return (SK_PNMI_ERR_GENERAL);
3113 }
3114
3115 Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
3116 SK_PNMI_STORE_U32(pBuf, Val32);
3117 *pLen = sizeof(SK_U32);
3118 break;
3119
3120 case OID_SKGE_VPD_ENTRIES_LIST:
3121 /* Check length */
3122 for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
3123
3124 Len += SK_STRLEN(KeyArr[Index]) + 1;
3125 }
3126 if (*pLen < Len) {
3127
3128 *pLen = Len;
3129 return (SK_PNMI_ERR_TOO_SHORT);
3130 }
3131
3132 /* Get value */
3133 *(pBuf) = (char)Len - 1;
3134 for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
3135
3136 Len = SK_STRLEN(KeyArr[Index]);
3137 SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
3138
3139 Offset += Len;
3140
3141 if (Index < KeyNo - 1) {
3142
3143 *(pBuf + Offset) = ' ';
3144 Offset ++;
3145 }
3146 }
3147 *pLen = Offset;
3148 break;
3149
3150 case OID_SKGE_VPD_ENTRIES_NUMBER:
3151 /* Check length */
3152 if (*pLen < sizeof(SK_U32)) {
3153
3154 *pLen = sizeof(SK_U32);
3155 return (SK_PNMI_ERR_TOO_SHORT);
3156 }
3157
3158 Val32 = (SK_U32)KeyNo;
3159 SK_PNMI_STORE_U32(pBuf, Val32);
3160 *pLen = sizeof(SK_U32);
3161 break;
3162
3163 case OID_SKGE_VPD_KEY:
3164 /* Check buffer length, if it is large enough */
3165 for (Len = 0, Index = FirstIndex;
3166 Index < LastIndex; Index ++) {
3167
3168 Len += SK_STRLEN(KeyArr[Index]) + 1;
3169 }
3170 if (*pLen < Len) {
3171
3172 *pLen = Len;
3173 return (SK_PNMI_ERR_TOO_SHORT);
3174 }
3175
3176 /*
3177 * Get the key to an intermediate buffer, because
3178 * we have to prepend a length byte.
3179 */
3180 for (Offset = 0, Index = FirstIndex;
3181 Index < LastIndex; Index ++) {
3182
3183 Len = SK_STRLEN(KeyArr[Index]);
3184
3185 *(pBuf + Offset) = (char)Len;
3186 SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
3187 Len);
3188 Offset += Len + 1;
3189 }
3190 *pLen = Offset;
3191 break;
3192
3193 case OID_SKGE_VPD_VALUE:
3194 /* Check the buffer length if it is large enough */
3195 for (Offset = 0, Index = FirstIndex;
3196 Index < LastIndex; Index ++) {
3197
3198 BufLen = 256;
3199 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3200 (int *)&BufLen) > 0 ||
3201 BufLen >= SK_PNMI_VPD_DATALEN) {
3202
3203 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3204 SK_PNMI_ERR021,
3205 SK_PNMI_ERR021MSG);
3206
3207 return (SK_PNMI_ERR_GENERAL);
3208 }
3209 Offset += BufLen + 1;
3210 }
3211 if (*pLen < Offset) {
3212
3213 *pLen = Offset;
3214 return (SK_PNMI_ERR_TOO_SHORT);
3215 }
3216
3217 /*
3218 * Get the value to an intermediate buffer, because
3219 * we have to prepend a length byte.
3220 */
3221 for (Offset = 0, Index = FirstIndex;
3222 Index < LastIndex; Index ++) {
3223
3224 BufLen = 256;
3225 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3226 (int *)&BufLen) > 0 ||
3227 BufLen >= SK_PNMI_VPD_DATALEN) {
3228
3229 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3230 SK_PNMI_ERR022,
3231 SK_PNMI_ERR022MSG);
3232
3233 *pLen = 0;
3234 return (SK_PNMI_ERR_GENERAL);
3235 }
3236
3237 *(pBuf + Offset) = (char)BufLen;
3238 SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
3239 Offset += BufLen + 1;
3240 }
3241 *pLen = Offset;
3242 break;
3243
3244 case OID_SKGE_VPD_ACCESS:
3245 if (*pLen < LastIndex - FirstIndex) {
3246
3247 *pLen = LastIndex - FirstIndex;
3248 return (SK_PNMI_ERR_TOO_SHORT);
3249 }
3250
3251 for (Offset = 0, Index = FirstIndex;
3252 Index < LastIndex; Index ++) {
3253
3254 if (VpdMayWrite(KeyArr[Index])) {
3255
3256 *(pBuf + Offset) = SK_PNMI_VPD_RW;
3257 }
3258 else {
3259 *(pBuf + Offset) = SK_PNMI_VPD_RO;
3260 }
3261 Offset ++;
3262 }
3263 *pLen = Offset;
3264 break;
3265
3266 case OID_SKGE_VPD_ACTION:
3267 Offset = LastIndex - FirstIndex;
3268 if (*pLen < Offset) {
3269
3270 *pLen = Offset;
3271 return (SK_PNMI_ERR_TOO_SHORT);
3272 }
3273 SK_MEMSET(pBuf, 0, Offset);
3274 *pLen = Offset;
3275 break;
3276
3277 default:
3278 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
3279 SK_PNMI_ERR023MSG);
3280
3281 *pLen = 0;
3282 return (SK_PNMI_ERR_GENERAL);
3283 }
3284 }
3285 else {
3286 /* The only OID which can be set is VPD_ACTION */
3287 if (Id != OID_SKGE_VPD_ACTION) {
3288
3289 if (Id == OID_SKGE_VPD_FREE_BYTES ||
3290 Id == OID_SKGE_VPD_ENTRIES_LIST ||
3291 Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
3292 Id == OID_SKGE_VPD_KEY ||
3293 Id == OID_SKGE_VPD_VALUE ||
3294 Id == OID_SKGE_VPD_ACCESS) {
3295
3296 *pLen = 0;
3297 return (SK_PNMI_ERR_READ_ONLY);
3298 }
3299
3300 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
3301 SK_PNMI_ERR024MSG);
3302
3303 *pLen = 0;
3304 return (SK_PNMI_ERR_GENERAL);
3305 }
3306
3307 /*
3308 * From this point we handle VPD_ACTION. Check the buffer
3309 * length. It should at least have the size of one byte.
3310 */
3311 if (*pLen < 1) {
3312
3313 *pLen = 1;
3314 return (SK_PNMI_ERR_TOO_SHORT);
3315 }
3316
3317 /*
3318 * The first byte contains the VPD action type we should
3319 * perform.
3320 */
3321 switch (*pBuf) {
3322
3323 case SK_PNMI_VPD_IGNORE:
3324 /* Nothing to do */
3325 break;
3326
3327 case SK_PNMI_VPD_CREATE:
3328 /*
3329 * We have to create a new VPD entry or we modify
3330 * an existing one. Check first the buffer length.
3331 */
3332 if (*pLen < 4) {
3333
3334 *pLen = 4;
3335 return (SK_PNMI_ERR_TOO_SHORT);
3336 }
3337 KeyStr[0] = pBuf[1];
3338 KeyStr[1] = pBuf[2];
3339 KeyStr[2] = 0;
3340
3341 /*
3342 * Is the entry writable or does it belong to the
3343 * read-only area?
3344 */
3345 if (!VpdMayWrite(KeyStr)) {
3346
3347 *pLen = 0;
3348 return (SK_PNMI_ERR_BAD_VALUE);
3349 }
3350
3351 Offset = (int)pBuf[3] & 0xFF;
3352
3353 SK_MEMCPY(Buf, pBuf + 4, Offset);
3354 Buf[Offset] = 0;
3355
3356 /* A preset ends here */
3357 if (Action == SK_PNMI_PRESET) {
3358
3359 return (SK_PNMI_ERR_OK);
3360 }
3361
3362 /* Write the new entry or modify an existing one */
3363 Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
3364 if (Ret == SK_PNMI_VPD_NOWRITE ) {
3365
3366 *pLen = 0;
3367 return (SK_PNMI_ERR_BAD_VALUE);
3368 }
3369 else if (Ret != SK_PNMI_VPD_OK) {
3370
3371 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
3372 SK_PNMI_ERR025MSG);
3373
3374 *pLen = 0;
3375 return (SK_PNMI_ERR_GENERAL);
3376 }
3377
3378 /*
3379 * Perform an update of the VPD data. This is
3380 * not mandantory, but just to be sure.
3381 */
3382 Ret = VpdUpdate(pAC, IoC);
3383 if (Ret != SK_PNMI_VPD_OK) {
3384
3385 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
3386 SK_PNMI_ERR026MSG);
3387
3388 *pLen = 0;
3389 return (SK_PNMI_ERR_GENERAL);
3390 }
3391 break;
3392
3393 case SK_PNMI_VPD_DELETE:
3394 /* Check if the buffer size is plausible */
3395 if (*pLen < 3) {
3396
3397 *pLen = 3;
3398 return (SK_PNMI_ERR_TOO_SHORT);
3399 }
3400 if (*pLen > 3) {
3401
3402 *pLen = 0;
3403 return (SK_PNMI_ERR_BAD_VALUE);
3404 }
3405 KeyStr[0] = pBuf[1];
3406 KeyStr[1] = pBuf[2];
3407 KeyStr[2] = 0;
3408
3409 /* Find the passed key in the array */
3410 for (Index = 0; Index < KeyNo; Index ++) {
3411
3412 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3413
3414 break;
3415 }
3416 }
3417 /*
3418 * If we cannot find the key it is wrong, so we
3419 * return an appropriate error value.
3420 */
3421 if (Index == KeyNo) {
3422
3423 *pLen = 0;
3424 return (SK_PNMI_ERR_BAD_VALUE);
3425 }
3426
3427 if (Action == SK_PNMI_PRESET) {
3428
3429 return (SK_PNMI_ERR_OK);
3430 }
3431
3432 /* Ok, you wanted it and you will get it */
3433 Ret = VpdDelete(pAC, IoC, KeyStr);
3434 if (Ret != SK_PNMI_VPD_OK) {
3435
3436 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
3437 SK_PNMI_ERR027MSG);
3438
3439 *pLen = 0;
3440 return (SK_PNMI_ERR_GENERAL);
3441 }
3442
3443 /*
3444 * Perform an update of the VPD data. This is
3445 * not mandantory, but just to be sure.
3446 */
3447 Ret = VpdUpdate(pAC, IoC);
3448 if (Ret != SK_PNMI_VPD_OK) {
3449
3450 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
3451 SK_PNMI_ERR028MSG);
3452
3453 *pLen = 0;
3454 return (SK_PNMI_ERR_GENERAL);
3455 }
3456 break;
3457
3458 default:
3459 *pLen = 0;
3460 return (SK_PNMI_ERR_BAD_VALUE);
3461 }
3462 }
3463
3464 return (SK_PNMI_ERR_OK);
3465 }
3466
3467 /*****************************************************************************
3468 *
3469 * General - OID handler function of various single instance OIDs
3470 *
3471 * Description:
3472 * The code is simple. No description necessary.
3473 *
3474 * Returns:
3475 * SK_PNMI_ERR_OK The request was successfully performed.
3476 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3477 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3478 * the correct data (e.g. a 32bit value is
3479 * needed, but a 16 bit value was passed).
3480 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3481 * exist (e.g. port instance 3 on a two port
3482 * adapter.
3483 */
General(SK_AC * pAC,SK_IOC IoC,int Action,SK_U32 Id,char * pBuf,unsigned int * pLen,SK_U32 Instance,unsigned int TableIndex,SK_U32 NetIndex)3484 PNMI_STATIC int General(
3485 SK_AC *pAC, /* Pointer to adapter context */
3486 SK_IOC IoC, /* IO context handle */
3487 int Action, /* GET/PRESET/SET action */
3488 SK_U32 Id, /* Object ID that is to be processed */
3489 char *pBuf, /* Buffer used for the management data transfer */
3490 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3491 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3492 unsigned int TableIndex, /* Index to the Id table */
3493 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
3494 {
3495 int Ret;
3496 unsigned int Index;
3497 unsigned int Len;
3498 unsigned int Offset;
3499 unsigned int Val;
3500 SK_U8 Val8;
3501 SK_U16 Val16;
3502 SK_U32 Val32;
3503 SK_U64 Val64;
3504 SK_U64 Val64RxHwErrs = 0;
3505 SK_U64 Val64TxHwErrs = 0;
3506 SK_BOOL Is64BitReq = SK_FALSE;
3507 char Buf[256];
3508 int MacType;
3509
3510 /*
3511 * Check instance. We only handle single instance variables.
3512 */
3513 if (Instance != (SK_U32)(-1) && Instance != 1) {
3514
3515 *pLen = 0;
3516 return (SK_PNMI_ERR_UNKNOWN_INST);
3517 }
3518
3519 /*
3520 * Check action. We only allow get requests.
3521 */
3522 if (Action != SK_PNMI_GET) {
3523
3524 *pLen = 0;
3525 return (SK_PNMI_ERR_READ_ONLY);
3526 }
3527
3528 MacType = pAC->GIni.GIMacType;
3529
3530 /*
3531 * Check length for the various supported OIDs
3532 */
3533 switch (Id) {
3534
3535 case OID_GEN_XMIT_ERROR:
3536 case OID_GEN_RCV_ERROR:
3537 case OID_GEN_RCV_NO_BUFFER:
3538 #ifndef SK_NDIS_64BIT_CTR
3539 if (*pLen < sizeof(SK_U32)) {
3540 *pLen = sizeof(SK_U32);
3541 return (SK_PNMI_ERR_TOO_SHORT);
3542 }
3543
3544 #else /* SK_NDIS_64BIT_CTR */
3545
3546 /*
3547 * for compatibility, at least 32bit are required for oid
3548 */
3549 if (*pLen < sizeof(SK_U32)) {
3550 /*
3551 * but indicate handling for 64bit values,
3552 * if insufficient space is provided
3553 */
3554 *pLen = sizeof(SK_U64);
3555 return (SK_PNMI_ERR_TOO_SHORT);
3556 }
3557
3558 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
3559 #endif /* SK_NDIS_64BIT_CTR */
3560 break;
3561
3562 case OID_SKGE_PORT_NUMBER:
3563 case OID_SKGE_DEVICE_TYPE:
3564 case OID_SKGE_RESULT:
3565 case OID_SKGE_RLMT_MONITOR_NUMBER:
3566 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
3567 case OID_SKGE_TRAP_NUMBER:
3568 case OID_SKGE_MDB_VERSION:
3569 case OID_SKGE_BOARDLEVEL:
3570 case OID_SKGE_CHIPID:
3571 case OID_SKGE_RAMSIZE:
3572 if (*pLen < sizeof(SK_U32)) {
3573
3574 *pLen = sizeof(SK_U32);
3575 return (SK_PNMI_ERR_TOO_SHORT);
3576 }
3577 break;
3578
3579 case OID_SKGE_CHIPSET:
3580 if (*pLen < sizeof(SK_U16)) {
3581
3582 *pLen = sizeof(SK_U16);
3583 return (SK_PNMI_ERR_TOO_SHORT);
3584 }
3585 break;
3586
3587 case OID_SKGE_BUS_TYPE:
3588 case OID_SKGE_BUS_SPEED:
3589 case OID_SKGE_BUS_WIDTH:
3590 case OID_SKGE_SENSOR_NUMBER:
3591 case OID_SKGE_CHKSM_NUMBER:
3592 case OID_SKGE_VAUXAVAIL:
3593 if (*pLen < sizeof(SK_U8)) {
3594
3595 *pLen = sizeof(SK_U8);
3596 return (SK_PNMI_ERR_TOO_SHORT);
3597 }
3598 break;
3599
3600 case OID_SKGE_TX_SW_QUEUE_LEN:
3601 case OID_SKGE_TX_SW_QUEUE_MAX:
3602 case OID_SKGE_TX_RETRY:
3603 case OID_SKGE_RX_INTR_CTS:
3604 case OID_SKGE_TX_INTR_CTS:
3605 case OID_SKGE_RX_NO_BUF_CTS:
3606 case OID_SKGE_TX_NO_BUF_CTS:
3607 case OID_SKGE_TX_USED_DESCR_NO:
3608 case OID_SKGE_RX_DELIVERED_CTS:
3609 case OID_SKGE_RX_OCTETS_DELIV_CTS:
3610 case OID_SKGE_RX_HW_ERROR_CTS:
3611 case OID_SKGE_TX_HW_ERROR_CTS:
3612 case OID_SKGE_IN_ERRORS_CTS:
3613 case OID_SKGE_OUT_ERROR_CTS:
3614 case OID_SKGE_ERR_RECOVERY_CTS:
3615 case OID_SKGE_SYSUPTIME:
3616 if (*pLen < sizeof(SK_U64)) {
3617
3618 *pLen = sizeof(SK_U64);
3619 return (SK_PNMI_ERR_TOO_SHORT);
3620 }
3621 break;
3622
3623 default:
3624 /* Checked later */
3625 break;
3626 }
3627
3628 /* Update statistic */
3629 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
3630 Id == OID_SKGE_TX_HW_ERROR_CTS ||
3631 Id == OID_SKGE_IN_ERRORS_CTS ||
3632 Id == OID_SKGE_OUT_ERROR_CTS ||
3633 Id == OID_GEN_XMIT_ERROR ||
3634 Id == OID_GEN_RCV_ERROR) {
3635
3636 /* Force the XMAC to update its statistic counters and
3637 * Increment semaphore to indicate that an update was
3638 * already done.
3639 */
3640 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
3641 if (Ret != SK_PNMI_ERR_OK) {
3642
3643 *pLen = 0;
3644 return (Ret);
3645 }
3646 pAC->Pnmi.MacUpdatedFlag ++;
3647
3648 /*
3649 * Some OIDs consist of multiple hardware counters. Those
3650 * values which are contained in all of them will be added
3651 * now.
3652 */
3653 switch (Id) {
3654
3655 case OID_SKGE_RX_HW_ERROR_CTS:
3656 case OID_SKGE_IN_ERRORS_CTS:
3657 case OID_GEN_RCV_ERROR:
3658 Val64RxHwErrs =
3659 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
3660 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
3661 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex) +
3662 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
3663 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
3664 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex) +
3665 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
3666 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
3667 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
3668 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
3669 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
3670 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
3671 break;
3672
3673 case OID_SKGE_TX_HW_ERROR_CTS:
3674 case OID_SKGE_OUT_ERROR_CTS:
3675 case OID_GEN_XMIT_ERROR:
3676 Val64TxHwErrs =
3677 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
3678 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex) +
3679 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex) +
3680 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex);
3681 break;
3682 }
3683 }
3684
3685 /*
3686 * Retrieve value
3687 */
3688 switch (Id) {
3689
3690 case OID_SKGE_SUPPORTED_LIST:
3691 Len = ID_TABLE_SIZE * sizeof(SK_U32);
3692 if (*pLen < Len) {
3693
3694 *pLen = Len;
3695 return (SK_PNMI_ERR_TOO_SHORT);
3696 }
3697 for (Offset = 0, Index = 0; Offset < Len;
3698 Offset += sizeof(SK_U32), Index ++) {
3699
3700 Val32 = (SK_U32)IdTable[Index].Id;
3701 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3702 }
3703 *pLen = Len;
3704 break;
3705
3706 case OID_SKGE_BOARDLEVEL:
3707 Val32 = (SK_U32)pAC->GIni.GILevel;
3708 SK_PNMI_STORE_U32(pBuf, Val32);
3709 *pLen = sizeof(SK_U32);
3710 break;
3711
3712 case OID_SKGE_PORT_NUMBER:
3713 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
3714 SK_PNMI_STORE_U32(pBuf, Val32);
3715 *pLen = sizeof(SK_U32);
3716 break;
3717
3718 case OID_SKGE_DEVICE_TYPE:
3719 Val32 = (SK_U32)pAC->Pnmi.DeviceType;
3720 SK_PNMI_STORE_U32(pBuf, Val32);
3721 *pLen = sizeof(SK_U32);
3722 break;
3723
3724 case OID_SKGE_DRIVER_DESCR:
3725 if (pAC->Pnmi.pDriverDescription == NULL) {
3726
3727 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
3728 SK_PNMI_ERR007MSG);
3729
3730 *pLen = 0;
3731 return (SK_PNMI_ERR_GENERAL);
3732 }
3733
3734 Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
3735 if (Len > SK_PNMI_STRINGLEN1) {
3736
3737 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
3738 SK_PNMI_ERR029MSG);
3739
3740 *pLen = 0;
3741 return (SK_PNMI_ERR_GENERAL);
3742 }
3743
3744 if (*pLen < Len) {
3745
3746 *pLen = Len;
3747 return (SK_PNMI_ERR_TOO_SHORT);
3748 }
3749 *pBuf = (char)(Len - 1);
3750 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
3751 *pLen = Len;
3752 break;
3753
3754 case OID_SKGE_DRIVER_VERSION:
3755 if (pAC->Pnmi.pDriverVersion == NULL) {
3756
3757 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3758 SK_PNMI_ERR030MSG);
3759
3760 *pLen = 0;
3761 return (SK_PNMI_ERR_GENERAL);
3762 }
3763
3764 Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
3765 if (Len > SK_PNMI_STRINGLEN1) {
3766
3767 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3768 SK_PNMI_ERR031MSG);
3769
3770 *pLen = 0;
3771 return (SK_PNMI_ERR_GENERAL);
3772 }
3773
3774 if (*pLen < Len) {
3775
3776 *pLen = Len;
3777 return (SK_PNMI_ERR_TOO_SHORT);
3778 }
3779 *pBuf = (char)(Len - 1);
3780 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
3781 *pLen = Len;
3782 break;
3783
3784 case OID_SKGE_DRIVER_RELDATE:
3785 if (pAC->Pnmi.pDriverReleaseDate == NULL) {
3786
3787 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3788 SK_PNMI_ERR053MSG);
3789
3790 *pLen = 0;
3791 return (SK_PNMI_ERR_GENERAL);
3792 }
3793
3794 Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1;
3795 if (Len > SK_PNMI_STRINGLEN1) {
3796
3797 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3798 SK_PNMI_ERR054MSG);
3799
3800 *pLen = 0;
3801 return (SK_PNMI_ERR_GENERAL);
3802 }
3803
3804 if (*pLen < Len) {
3805
3806 *pLen = Len;
3807 return (SK_PNMI_ERR_TOO_SHORT);
3808 }
3809 *pBuf = (char)(Len - 1);
3810 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverReleaseDate, Len - 1);
3811 *pLen = Len;
3812 break;
3813
3814 case OID_SKGE_DRIVER_FILENAME:
3815 if (pAC->Pnmi.pDriverFileName == NULL) {
3816
3817 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3818 SK_PNMI_ERR055MSG);
3819
3820 *pLen = 0;
3821 return (SK_PNMI_ERR_GENERAL);
3822 }
3823
3824 Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1;
3825 if (Len > SK_PNMI_STRINGLEN1) {
3826
3827 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3828 SK_PNMI_ERR056MSG);
3829
3830 *pLen = 0;
3831 return (SK_PNMI_ERR_GENERAL);
3832 }
3833
3834 if (*pLen < Len) {
3835
3836 *pLen = Len;
3837 return (SK_PNMI_ERR_TOO_SHORT);
3838 }
3839 *pBuf = (char)(Len - 1);
3840 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverFileName, Len - 1);
3841 *pLen = Len;
3842 break;
3843
3844 case OID_SKGE_HW_DESCR:
3845 /*
3846 * The hardware description is located in the VPD. This
3847 * query may move to the initialisation routine. But
3848 * the VPD data is cached and therefore a call here
3849 * will not make much difference.
3850 */
3851 Len = 256;
3852 if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
3853
3854 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
3855 SK_PNMI_ERR032MSG);
3856
3857 *pLen = 0;
3858 return (SK_PNMI_ERR_GENERAL);
3859 }
3860 Len ++;
3861 if (Len > SK_PNMI_STRINGLEN1) {
3862
3863 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
3864 SK_PNMI_ERR033MSG);
3865
3866 *pLen = 0;
3867 return (SK_PNMI_ERR_GENERAL);
3868 }
3869 if (*pLen < Len) {
3870
3871 *pLen = Len;
3872 return (SK_PNMI_ERR_TOO_SHORT);
3873 }
3874 *pBuf = (char)(Len - 1);
3875 SK_MEMCPY(pBuf + 1, Buf, Len - 1);
3876 *pLen = Len;
3877 break;
3878
3879 case OID_SKGE_HW_VERSION:
3880 /* Oh, I love to do some string manipulation */
3881 if (*pLen < 5) {
3882
3883 *pLen = 5;
3884 return (SK_PNMI_ERR_TOO_SHORT);
3885 }
3886 Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
3887 pBuf[0] = 4;
3888 pBuf[1] = 'v';
3889 pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
3890 pBuf[3] = '.';
3891 pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
3892 *pLen = 5;
3893 break;
3894
3895 case OID_SKGE_CHIPSET:
3896 Val16 = pAC->Pnmi.Chipset;
3897 SK_PNMI_STORE_U16(pBuf, Val16);
3898 *pLen = sizeof(SK_U16);
3899 break;
3900
3901 case OID_SKGE_CHIPID:
3902 Val32 = pAC->GIni.GIChipId;
3903 SK_PNMI_STORE_U32(pBuf, Val32);
3904 *pLen = sizeof(SK_U32);
3905 break;
3906
3907 case OID_SKGE_RAMSIZE:
3908 Val32 = pAC->GIni.GIRamSize;
3909 SK_PNMI_STORE_U32(pBuf, Val32);
3910 *pLen = sizeof(SK_U32);
3911 break;
3912
3913 case OID_SKGE_VAUXAVAIL:
3914 *pBuf = (char) pAC->GIni.GIVauxAvail;
3915 *pLen = sizeof(char);
3916 break;
3917
3918 case OID_SKGE_BUS_TYPE:
3919 *pBuf = (char) SK_PNMI_BUS_PCI;
3920 *pLen = sizeof(char);
3921 break;
3922
3923 case OID_SKGE_BUS_SPEED:
3924 *pBuf = pAC->Pnmi.PciBusSpeed;
3925 *pLen = sizeof(char);
3926 break;
3927
3928 case OID_SKGE_BUS_WIDTH:
3929 *pBuf = pAC->Pnmi.PciBusWidth;
3930 *pLen = sizeof(char);
3931 break;
3932
3933 case OID_SKGE_RESULT:
3934 Val32 = pAC->Pnmi.TestResult;
3935 SK_PNMI_STORE_U32(pBuf, Val32);
3936 *pLen = sizeof(SK_U32);
3937 break;
3938
3939 case OID_SKGE_SENSOR_NUMBER:
3940 *pBuf = (char)pAC->I2c.MaxSens;
3941 *pLen = sizeof(char);
3942 break;
3943
3944 case OID_SKGE_CHKSM_NUMBER:
3945 *pBuf = SKCS_NUM_PROTOCOLS;
3946 *pLen = sizeof(char);
3947 break;
3948
3949 case OID_SKGE_TRAP_NUMBER:
3950 GetTrapQueueLen(pAC, &Len, &Val);
3951 Val32 = (SK_U32)Val;
3952 SK_PNMI_STORE_U32(pBuf, Val32);
3953 *pLen = sizeof(SK_U32);
3954 break;
3955
3956 case OID_SKGE_TRAP:
3957 GetTrapQueueLen(pAC, &Len, &Val);
3958 if (*pLen < Len) {
3959
3960 *pLen = Len;
3961 return (SK_PNMI_ERR_TOO_SHORT);
3962 }
3963 CopyTrapQueue(pAC, pBuf);
3964 *pLen = Len;
3965 break;
3966
3967 case OID_SKGE_RLMT_MONITOR_NUMBER:
3968 /* XXX Not yet implemented by RLMT therefore we return zero elements */
3969 Val32 = 0;
3970 SK_PNMI_STORE_U32(pBuf, Val32);
3971 *pLen = sizeof(SK_U32);
3972 break;
3973
3974 case OID_SKGE_TX_SW_QUEUE_LEN:
3975 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
3976 if (MacType == SK_MAC_XMAC) {
3977 /* Dual net mode */
3978 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
3979 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
3980 }
3981 /* Single net mode */
3982 else {
3983 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
3984 pAC->Pnmi.BufPort[1].TxSwQueueLen;
3985 }
3986 }
3987 else {
3988 /* Dual net mode */
3989 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
3990 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
3991 }
3992 /* Single net mode */
3993 else {
3994 Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
3995 pAC->Pnmi.Port[1].TxSwQueueLen;
3996 }
3997 }
3998 SK_PNMI_STORE_U64(pBuf, Val64);
3999 *pLen = sizeof(SK_U64);
4000 break;
4001
4002
4003 case OID_SKGE_TX_SW_QUEUE_MAX:
4004 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4005 if (MacType == SK_MAC_XMAC) {
4006 /* Dual net mode */
4007 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4008 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
4009 }
4010 /* Single net mode */
4011 else {
4012 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
4013 pAC->Pnmi.BufPort[1].TxSwQueueMax;
4014 }
4015 }
4016 else {
4017 /* Dual net mode */
4018 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4019 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
4020 }
4021 /* Single net mode */
4022 else {
4023 Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
4024 pAC->Pnmi.Port[1].TxSwQueueMax;
4025 }
4026 }
4027 SK_PNMI_STORE_U64(pBuf, Val64);
4028 *pLen = sizeof(SK_U64);
4029 break;
4030
4031 case OID_SKGE_TX_RETRY:
4032 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4033 if (MacType == SK_MAC_XMAC) {
4034 /* Dual net mode */
4035 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4036 Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
4037 }
4038 /* Single net mode */
4039 else {
4040 Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
4041 pAC->Pnmi.BufPort[1].TxRetryCts;
4042 }
4043 }
4044 else {
4045 /* Dual net mode */
4046 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4047 Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
4048 }
4049 /* Single net mode */
4050 else {
4051 Val64 = pAC->Pnmi.Port[0].TxRetryCts +
4052 pAC->Pnmi.Port[1].TxRetryCts;
4053 }
4054 }
4055 SK_PNMI_STORE_U64(pBuf, Val64);
4056 *pLen = sizeof(SK_U64);
4057 break;
4058
4059 case OID_SKGE_RX_INTR_CTS:
4060 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4061 if (MacType == SK_MAC_XMAC) {
4062 /* Dual net mode */
4063 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4064 Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
4065 }
4066 /* Single net mode */
4067 else {
4068 Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
4069 pAC->Pnmi.BufPort[1].RxIntrCts;
4070 }
4071 }
4072 else {
4073 /* Dual net mode */
4074 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4075 Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
4076 }
4077 /* Single net mode */
4078 else {
4079 Val64 = pAC->Pnmi.Port[0].RxIntrCts +
4080 pAC->Pnmi.Port[1].RxIntrCts;
4081 }
4082 }
4083 SK_PNMI_STORE_U64(pBuf, Val64);
4084 *pLen = sizeof(SK_U64);
4085 break;
4086
4087 case OID_SKGE_TX_INTR_CTS:
4088 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4089 if (MacType == SK_MAC_XMAC) {
4090 /* Dual net mode */
4091 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4092 Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
4093 }
4094 /* Single net mode */
4095 else {
4096 Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
4097 pAC->Pnmi.BufPort[1].TxIntrCts;
4098 }
4099 }
4100 else {
4101 /* Dual net mode */
4102 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4103 Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
4104 }
4105 /* Single net mode */
4106 else {
4107 Val64 = pAC->Pnmi.Port[0].TxIntrCts +
4108 pAC->Pnmi.Port[1].TxIntrCts;
4109 }
4110 }
4111 SK_PNMI_STORE_U64(pBuf, Val64);
4112 *pLen = sizeof(SK_U64);
4113 break;
4114
4115 case OID_SKGE_RX_NO_BUF_CTS:
4116 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4117 if (MacType == SK_MAC_XMAC) {
4118 /* Dual net mode */
4119 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4120 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4121 }
4122 /* Single net mode */
4123 else {
4124 Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
4125 pAC->Pnmi.BufPort[1].RxNoBufCts;
4126 }
4127 }
4128 else {
4129 /* Dual net mode */
4130 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4131 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4132 }
4133 /* Single net mode */
4134 else {
4135 Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
4136 pAC->Pnmi.Port[1].RxNoBufCts;
4137 }
4138 }
4139 SK_PNMI_STORE_U64(pBuf, Val64);
4140 *pLen = sizeof(SK_U64);
4141 break;
4142
4143 case OID_SKGE_TX_NO_BUF_CTS:
4144 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4145 if (MacType == SK_MAC_XMAC) {
4146 /* Dual net mode */
4147 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4148 Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4149 }
4150 /* Single net mode */
4151 else {
4152 Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
4153 pAC->Pnmi.BufPort[1].TxNoBufCts;
4154 }
4155 }
4156 else {
4157 /* Dual net mode */
4158 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4159 Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4160 }
4161 /* Single net mode */
4162 else {
4163 Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
4164 pAC->Pnmi.Port[1].TxNoBufCts;
4165 }
4166 }
4167 SK_PNMI_STORE_U64(pBuf, Val64);
4168 *pLen = sizeof(SK_U64);
4169 break;
4170
4171 case OID_SKGE_TX_USED_DESCR_NO:
4172 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4173 if (MacType == SK_MAC_XMAC) {
4174 /* Dual net mode */
4175 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4176 Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
4177 }
4178 /* Single net mode */
4179 else {
4180 Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
4181 pAC->Pnmi.BufPort[1].TxUsedDescrNo;
4182 }
4183 }
4184 else {
4185 /* Dual net mode */
4186 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4187 Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
4188 }
4189 /* Single net mode */
4190 else {
4191 Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
4192 pAC->Pnmi.Port[1].TxUsedDescrNo;
4193 }
4194 }
4195 SK_PNMI_STORE_U64(pBuf, Val64);
4196 *pLen = sizeof(SK_U64);
4197 break;
4198
4199 case OID_SKGE_RX_DELIVERED_CTS:
4200 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4201 if (MacType == SK_MAC_XMAC) {
4202 /* Dual net mode */
4203 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4204 Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
4205 }
4206 /* Single net mode */
4207 else {
4208 Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
4209 pAC->Pnmi.BufPort[1].RxDeliveredCts;
4210 }
4211 }
4212 else {
4213 /* Dual net mode */
4214 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4215 Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
4216 }
4217 /* Single net mode */
4218 else {
4219 Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
4220 pAC->Pnmi.Port[1].RxDeliveredCts;
4221 }
4222 }
4223 SK_PNMI_STORE_U64(pBuf, Val64);
4224 *pLen = sizeof(SK_U64);
4225 break;
4226
4227 case OID_SKGE_RX_OCTETS_DELIV_CTS:
4228 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4229 if (MacType == SK_MAC_XMAC) {
4230 /* Dual net mode */
4231 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4232 Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
4233 }
4234 /* Single net mode */
4235 else {
4236 Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
4237 pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
4238 }
4239 }
4240 else {
4241 /* Dual net mode */
4242 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4243 Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
4244 }
4245 /* Single net mode */
4246 else {
4247 Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
4248 pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
4249 }
4250 }
4251 SK_PNMI_STORE_U64(pBuf, Val64);
4252 *pLen = sizeof(SK_U64);
4253 break;
4254
4255 case OID_SKGE_RX_HW_ERROR_CTS:
4256 SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
4257 *pLen = sizeof(SK_U64);
4258 break;
4259
4260 case OID_SKGE_TX_HW_ERROR_CTS:
4261 SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
4262 *pLen = sizeof(SK_U64);
4263 break;
4264
4265 case OID_SKGE_IN_ERRORS_CTS:
4266 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4267 if (MacType == SK_MAC_XMAC) {
4268 /* Dual net mode */
4269 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4270 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4271 }
4272 /* Single net mode */
4273 else {
4274 Val64 = Val64RxHwErrs +
4275 pAC->Pnmi.BufPort[0].RxNoBufCts +
4276 pAC->Pnmi.BufPort[1].RxNoBufCts;
4277 }
4278 }
4279 else {
4280 /* Dual net mode */
4281 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4282 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4283 }
4284 /* Single net mode */
4285 else {
4286 Val64 = Val64RxHwErrs +
4287 pAC->Pnmi.Port[0].RxNoBufCts +
4288 pAC->Pnmi.Port[1].RxNoBufCts;
4289 }
4290 }
4291 SK_PNMI_STORE_U64(pBuf, Val64);
4292 *pLen = sizeof(SK_U64);
4293 break;
4294
4295 case OID_SKGE_OUT_ERROR_CTS:
4296 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4297 if (MacType == SK_MAC_XMAC) {
4298 /* Dual net mode */
4299 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4300 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4301 }
4302 /* Single net mode */
4303 else {
4304 Val64 = Val64TxHwErrs +
4305 pAC->Pnmi.BufPort[0].TxNoBufCts +
4306 pAC->Pnmi.BufPort[1].TxNoBufCts;
4307 }
4308 }
4309 else {
4310 /* Dual net mode */
4311 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4312 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4313 }
4314 /* Single net mode */
4315 else {
4316 Val64 = Val64TxHwErrs +
4317 pAC->Pnmi.Port[0].TxNoBufCts +
4318 pAC->Pnmi.Port[1].TxNoBufCts;
4319 }
4320 }
4321 SK_PNMI_STORE_U64(pBuf, Val64);
4322 *pLen = sizeof(SK_U64);
4323 break;
4324
4325 case OID_SKGE_ERR_RECOVERY_CTS:
4326 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4327 if (MacType == SK_MAC_XMAC) {
4328 /* Dual net mode */
4329 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4330 Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
4331 }
4332 /* Single net mode */
4333 else {
4334 Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
4335 pAC->Pnmi.BufPort[1].ErrRecoveryCts;
4336 }
4337 }
4338 else {
4339 /* Dual net mode */
4340 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4341 Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
4342 }
4343 /* Single net mode */
4344 else {
4345 Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
4346 pAC->Pnmi.Port[1].ErrRecoveryCts;
4347 }
4348 }
4349 SK_PNMI_STORE_U64(pBuf, Val64);
4350 *pLen = sizeof(SK_U64);
4351 break;
4352
4353 case OID_SKGE_SYSUPTIME:
4354 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
4355 Val64 -= pAC->Pnmi.StartUpTime;
4356 SK_PNMI_STORE_U64(pBuf, Val64);
4357 *pLen = sizeof(SK_U64);
4358 break;
4359
4360 case OID_SKGE_MDB_VERSION:
4361 Val32 = SK_PNMI_MDB_VERSION;
4362 SK_PNMI_STORE_U32(pBuf, Val32);
4363 *pLen = sizeof(SK_U32);
4364 break;
4365
4366 case OID_GEN_RCV_ERROR:
4367 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4368 if (MacType == SK_MAC_XMAC) {
4369 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4370 }
4371 else {
4372 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4373 }
4374
4375 /*
4376 * by default 32bit values are evaluated
4377 */
4378 if (!Is64BitReq) {
4379 Val32 = (SK_U32)Val64;
4380 SK_PNMI_STORE_U32(pBuf, Val32);
4381 *pLen = sizeof(SK_U32);
4382 }
4383 else {
4384 SK_PNMI_STORE_U64(pBuf, Val64);
4385 *pLen = sizeof(SK_U64);
4386 }
4387 break;
4388
4389 case OID_GEN_XMIT_ERROR:
4390 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4391 if (MacType == SK_MAC_XMAC) {
4392 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4393 }
4394 else {
4395 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4396 }
4397
4398 /*
4399 * by default 32bit values are evaluated
4400 */
4401 if (!Is64BitReq) {
4402 Val32 = (SK_U32)Val64;
4403 SK_PNMI_STORE_U32(pBuf, Val32);
4404 *pLen = sizeof(SK_U32);
4405 }
4406 else {
4407 SK_PNMI_STORE_U64(pBuf, Val64);
4408 *pLen = sizeof(SK_U64);
4409 }
4410 break;
4411
4412 case OID_GEN_RCV_NO_BUFFER:
4413 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4414 if (MacType == SK_MAC_XMAC) {
4415 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4416 }
4417 else {
4418 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4419 }
4420
4421 /*
4422 * by default 32bit values are evaluated
4423 */
4424 if (!Is64BitReq) {
4425 Val32 = (SK_U32)Val64;
4426 SK_PNMI_STORE_U32(pBuf, Val32);
4427 *pLen = sizeof(SK_U32);
4428 }
4429 else {
4430 SK_PNMI_STORE_U64(pBuf, Val64);
4431 *pLen = sizeof(SK_U64);
4432 }
4433 break;
4434
4435 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
4436 Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
4437 SK_PNMI_STORE_U32(pBuf, Val32);
4438 *pLen = sizeof(SK_U32);
4439 break;
4440
4441 default:
4442 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
4443 SK_PNMI_ERR034MSG);
4444
4445 *pLen = 0;
4446 return (SK_PNMI_ERR_GENERAL);
4447 }
4448
4449 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
4450 Id == OID_SKGE_TX_HW_ERROR_CTS ||
4451 Id == OID_SKGE_IN_ERRORS_CTS ||
4452 Id == OID_SKGE_OUT_ERROR_CTS ||
4453 Id == OID_GEN_XMIT_ERROR ||
4454 Id == OID_GEN_RCV_ERROR) {
4455
4456 pAC->Pnmi.MacUpdatedFlag --;
4457 }
4458
4459 return (SK_PNMI_ERR_OK);
4460 }
4461
4462 /*****************************************************************************
4463 *
4464 * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
4465 *
4466 * Description:
4467 * Get/Presets/Sets the RLMT OIDs.
4468 *
4469 * Returns:
4470 * SK_PNMI_ERR_OK The request was successfully performed.
4471 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4472 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4473 * the correct data (e.g. a 32bit value is
4474 * needed, but a 16 bit value was passed).
4475 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
4476 * value range.
4477 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
4478 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4479 * exist (e.g. port instance 3 on a two port
4480 * adapter.
4481 */
Rlmt(SK_AC * pAC,SK_IOC IoC,int Action,SK_U32 Id,char * pBuf,unsigned int * pLen,SK_U32 Instance,unsigned int TableIndex,SK_U32 NetIndex)4482 PNMI_STATIC int Rlmt(
4483 SK_AC *pAC, /* Pointer to adapter context */
4484 SK_IOC IoC, /* IO context handle */
4485 int Action, /* GET/PRESET/SET action */
4486 SK_U32 Id, /* Object ID that is to be processed */
4487 char *pBuf, /* Buffer used for the management data transfer */
4488 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4489 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4490 unsigned int TableIndex, /* Index to the Id table */
4491 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
4492 {
4493 int Ret;
4494 unsigned int PhysPortIndex;
4495 unsigned int PhysPortMax;
4496 SK_EVPARA EventParam;
4497 SK_U32 Val32;
4498 SK_U64 Val64;
4499
4500
4501 /*
4502 * Check instance. Only single instance OIDs are allowed here.
4503 */
4504 if (Instance != (SK_U32)(-1) && Instance != 1) {
4505
4506 *pLen = 0;
4507 return (SK_PNMI_ERR_UNKNOWN_INST);
4508 }
4509
4510 /*
4511 * Perform the requested action.
4512 */
4513 if (Action == SK_PNMI_GET) {
4514
4515 /*
4516 * Check if the buffer length is large enough.
4517 */
4518
4519 switch (Id) {
4520
4521 case OID_SKGE_RLMT_MODE:
4522 case OID_SKGE_RLMT_PORT_ACTIVE:
4523 case OID_SKGE_RLMT_PORT_PREFERRED:
4524 if (*pLen < sizeof(SK_U8)) {
4525
4526 *pLen = sizeof(SK_U8);
4527 return (SK_PNMI_ERR_TOO_SHORT);
4528 }
4529 break;
4530
4531 case OID_SKGE_RLMT_PORT_NUMBER:
4532 if (*pLen < sizeof(SK_U32)) {
4533
4534 *pLen = sizeof(SK_U32);
4535 return (SK_PNMI_ERR_TOO_SHORT);
4536 }
4537 break;
4538
4539 case OID_SKGE_RLMT_CHANGE_CTS:
4540 case OID_SKGE_RLMT_CHANGE_TIME:
4541 case OID_SKGE_RLMT_CHANGE_ESTIM:
4542 case OID_SKGE_RLMT_CHANGE_THRES:
4543 if (*pLen < sizeof(SK_U64)) {
4544
4545 *pLen = sizeof(SK_U64);
4546 return (SK_PNMI_ERR_TOO_SHORT);
4547 }
4548 break;
4549
4550 default:
4551 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
4552 SK_PNMI_ERR035MSG);
4553
4554 *pLen = 0;
4555 return (SK_PNMI_ERR_GENERAL);
4556 }
4557
4558 /*
4559 * Update RLMT statistic and increment semaphores to indicate
4560 * that an update was already done. Maybe RLMT will hold its
4561 * statistic always up to date some time. Then we can
4562 * remove this type of call.
4563 */
4564 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4565
4566 *pLen = 0;
4567 return (Ret);
4568 }
4569 pAC->Pnmi.RlmtUpdatedFlag ++;
4570
4571 /*
4572 * Retrieve Value
4573 */
4574 switch (Id) {
4575
4576 case OID_SKGE_RLMT_MODE:
4577 *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
4578 *pLen = sizeof(char);
4579 break;
4580
4581 case OID_SKGE_RLMT_PORT_NUMBER:
4582 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
4583 SK_PNMI_STORE_U32(pBuf, Val32);
4584 *pLen = sizeof(SK_U32);
4585 break;
4586
4587 case OID_SKGE_RLMT_PORT_ACTIVE:
4588 *pBuf = 0;
4589 /*
4590 * If multiple ports may become active this OID
4591 * doesn't make sense any more. A new variable in
4592 * the port structure should be created. However,
4593 * for this variable the first active port is
4594 * returned.
4595 */
4596 PhysPortMax = pAC->GIni.GIMacsFound;
4597
4598 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
4599 PhysPortIndex ++) {
4600
4601 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4602
4603 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
4604 break;
4605 }
4606 }
4607 *pLen = sizeof(char);
4608 break;
4609
4610 case OID_SKGE_RLMT_PORT_PREFERRED:
4611 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
4612 *pLen = sizeof(char);
4613 break;
4614
4615 case OID_SKGE_RLMT_CHANGE_CTS:
4616 Val64 = pAC->Pnmi.RlmtChangeCts;
4617 SK_PNMI_STORE_U64(pBuf, Val64);
4618 *pLen = sizeof(SK_U64);
4619 break;
4620
4621 case OID_SKGE_RLMT_CHANGE_TIME:
4622 Val64 = pAC->Pnmi.RlmtChangeTime;
4623 SK_PNMI_STORE_U64(pBuf, Val64);
4624 *pLen = sizeof(SK_U64);
4625 break;
4626
4627 case OID_SKGE_RLMT_CHANGE_ESTIM:
4628 Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
4629 SK_PNMI_STORE_U64(pBuf, Val64);
4630 *pLen = sizeof(SK_U64);
4631 break;
4632
4633 case OID_SKGE_RLMT_CHANGE_THRES:
4634 Val64 = pAC->Pnmi.RlmtChangeThreshold;
4635 SK_PNMI_STORE_U64(pBuf, Val64);
4636 *pLen = sizeof(SK_U64);
4637 break;
4638
4639 default:
4640 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
4641 ("Rlmt: Unknown OID should be handled before"));
4642
4643 pAC->Pnmi.RlmtUpdatedFlag --;
4644 *pLen = 0;
4645 return (SK_PNMI_ERR_GENERAL);
4646 }
4647
4648 pAC->Pnmi.RlmtUpdatedFlag --;
4649 }
4650 else {
4651 /* Perform a preset or set */
4652 switch (Id) {
4653
4654 case OID_SKGE_RLMT_MODE:
4655 /* Check if the buffer length is plausible */
4656 if (*pLen < sizeof(char)) {
4657
4658 *pLen = sizeof(char);
4659 return (SK_PNMI_ERR_TOO_SHORT);
4660 }
4661 /* Check if the value range is correct */
4662 if (*pLen != sizeof(char) ||
4663 (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
4664 *(SK_U8 *)pBuf > 15) {
4665
4666 *pLen = 0;
4667 return (SK_PNMI_ERR_BAD_VALUE);
4668 }
4669 /* The preset ends here */
4670 if (Action == SK_PNMI_PRESET) {
4671
4672 *pLen = 0;
4673 return (SK_PNMI_ERR_OK);
4674 }
4675 /* Send an event to RLMT to change the mode */
4676 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
4677 EventParam.Para32[0] |= (SK_U32)(*pBuf);
4678 EventParam.Para32[1] = 0;
4679 if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
4680 EventParam) > 0) {
4681
4682 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
4683 SK_PNMI_ERR037MSG);
4684
4685 *pLen = 0;
4686 return (SK_PNMI_ERR_GENERAL);
4687 }
4688 break;
4689
4690 case OID_SKGE_RLMT_PORT_PREFERRED:
4691 /* Check if the buffer length is plausible */
4692 if (*pLen < sizeof(char)) {
4693
4694 *pLen = sizeof(char);
4695 return (SK_PNMI_ERR_TOO_SHORT);
4696 }
4697 /* Check if the value range is correct */
4698 if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
4699 (SK_U8)pAC->GIni.GIMacsFound) {
4700
4701 *pLen = 0;
4702 return (SK_PNMI_ERR_BAD_VALUE);
4703 }
4704 /* The preset ends here */
4705 if (Action == SK_PNMI_PRESET) {
4706
4707 *pLen = 0;
4708 return (SK_PNMI_ERR_OK);
4709 }
4710
4711 /*
4712 * Send an event to RLMT change the preferred port.
4713 * A param of -1 means automatic mode. RLMT will
4714 * make the decision which is the preferred port.
4715 */
4716 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
4717 EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
4718 EventParam.Para32[1] = NetIndex;
4719 if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
4720 EventParam) > 0) {
4721
4722 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
4723 SK_PNMI_ERR038MSG);
4724
4725 *pLen = 0;
4726 return (SK_PNMI_ERR_GENERAL);
4727 }
4728 break;
4729
4730 case OID_SKGE_RLMT_CHANGE_THRES:
4731 /* Check if the buffer length is plausible */
4732 if (*pLen < sizeof(SK_U64)) {
4733
4734 *pLen = sizeof(SK_U64);
4735 return (SK_PNMI_ERR_TOO_SHORT);
4736 }
4737 /*
4738 * There are not many restrictions to the
4739 * value range.
4740 */
4741 if (*pLen != sizeof(SK_U64)) {
4742
4743 *pLen = 0;
4744 return (SK_PNMI_ERR_BAD_VALUE);
4745 }
4746 /* A preset ends here */
4747 if (Action == SK_PNMI_PRESET) {
4748
4749 *pLen = 0;
4750 return (SK_PNMI_ERR_OK);
4751 }
4752 /*
4753 * Store the new threshold, which will be taken
4754 * on the next timer event.
4755 */
4756 SK_PNMI_READ_U64(pBuf, Val64);
4757 pAC->Pnmi.RlmtChangeThreshold = Val64;
4758 break;
4759
4760 default:
4761 /* The other OIDs are not be able for set */
4762 *pLen = 0;
4763 return (SK_PNMI_ERR_READ_ONLY);
4764 }
4765 }
4766
4767 return (SK_PNMI_ERR_OK);
4768 }
4769
4770 /*****************************************************************************
4771 *
4772 * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
4773 *
4774 * Description:
4775 * Performs get requests on multiple instance variables.
4776 *
4777 * Returns:
4778 * SK_PNMI_ERR_OK The request was successfully performed.
4779 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4780 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4781 * the correct data (e.g. a 32bit value is
4782 * needed, but a 16 bit value was passed).
4783 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4784 * exist (e.g. port instance 3 on a two port
4785 * adapter.
4786 */
RlmtStat(SK_AC * pAC,SK_IOC IoC,int Action,SK_U32 Id,char * pBuf,unsigned int * pLen,SK_U32 Instance,unsigned int TableIndex,SK_U32 NetIndex)4787 PNMI_STATIC int RlmtStat(
4788 SK_AC *pAC, /* Pointer to adapter context */
4789 SK_IOC IoC, /* IO context handle */
4790 int Action, /* GET/PRESET/SET action */
4791 SK_U32 Id, /* Object ID that is to be processed */
4792 char *pBuf, /* Buffer used for the management data transfer */
4793 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4794 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4795 unsigned int TableIndex, /* Index to the Id table */
4796 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
4797 {
4798 unsigned int PhysPortMax;
4799 unsigned int PhysPortIndex;
4800 unsigned int Limit;
4801 unsigned int Offset;
4802 int Ret;
4803 SK_U32 Val32;
4804 SK_U64 Val64;
4805
4806 /*
4807 * Calculate the port indexes from the instance.
4808 */
4809 PhysPortMax = pAC->GIni.GIMacsFound;
4810
4811 if ((Instance != (SK_U32)(-1))) {
4812 /* Check instance range */
4813 if ((Instance < 1) || (Instance > PhysPortMax)) {
4814
4815 *pLen = 0;
4816 return (SK_PNMI_ERR_UNKNOWN_INST);
4817 }
4818
4819 /* Single net mode */
4820 PhysPortIndex = Instance - 1;
4821
4822 /* Dual net mode */
4823 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4824 PhysPortIndex = NetIndex;
4825 }
4826
4827 /* Both net modes */
4828 Limit = PhysPortIndex + 1;
4829 }
4830 else {
4831 /* Single net mode */
4832 PhysPortIndex = 0;
4833 Limit = PhysPortMax;
4834
4835 /* Dual net mode */
4836 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4837 PhysPortIndex = NetIndex;
4838 Limit = PhysPortIndex + 1;
4839 }
4840 }
4841
4842 /*
4843 * Currently only get requests are allowed.
4844 */
4845 if (Action != SK_PNMI_GET) {
4846
4847 *pLen = 0;
4848 return (SK_PNMI_ERR_READ_ONLY);
4849 }
4850
4851 /*
4852 * Check if the buffer length is large enough.
4853 */
4854 switch (Id) {
4855
4856 case OID_SKGE_RLMT_PORT_INDEX:
4857 case OID_SKGE_RLMT_STATUS:
4858 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
4859
4860 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
4861 return (SK_PNMI_ERR_TOO_SHORT);
4862 }
4863 break;
4864
4865 case OID_SKGE_RLMT_TX_HELLO_CTS:
4866 case OID_SKGE_RLMT_RX_HELLO_CTS:
4867 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
4868 case OID_SKGE_RLMT_RX_SP_CTS:
4869 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
4870
4871 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
4872 return (SK_PNMI_ERR_TOO_SHORT);
4873 }
4874 break;
4875
4876 default:
4877 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
4878 SK_PNMI_ERR039MSG);
4879
4880 *pLen = 0;
4881 return (SK_PNMI_ERR_GENERAL);
4882
4883 }
4884
4885 /*
4886 * Update statistic and increment semaphores to indicate that
4887 * an update was already done.
4888 */
4889 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4890
4891 *pLen = 0;
4892 return (Ret);
4893 }
4894 pAC->Pnmi.RlmtUpdatedFlag ++;
4895
4896 /*
4897 * Get value
4898 */
4899 Offset = 0;
4900 for (; PhysPortIndex < Limit; PhysPortIndex ++) {
4901
4902 switch (Id) {
4903
4904 case OID_SKGE_RLMT_PORT_INDEX:
4905 Val32 = PhysPortIndex;
4906 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4907 Offset += sizeof(SK_U32);
4908 break;
4909
4910 case OID_SKGE_RLMT_STATUS:
4911 if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
4912 SK_RLMT_PS_INIT ||
4913 pAC->Rlmt.Port[PhysPortIndex].PortState ==
4914 SK_RLMT_PS_DOWN) {
4915
4916 Val32 = SK_PNMI_RLMT_STATUS_ERROR;
4917 }
4918 else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4919
4920 Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
4921 }
4922 else {
4923 Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
4924 }
4925 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4926 Offset += sizeof(SK_U32);
4927 break;
4928
4929 case OID_SKGE_RLMT_TX_HELLO_CTS:
4930 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
4931 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4932 Offset += sizeof(SK_U64);
4933 break;
4934
4935 case OID_SKGE_RLMT_RX_HELLO_CTS:
4936 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
4937 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4938 Offset += sizeof(SK_U64);
4939 break;
4940
4941 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
4942 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
4943 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4944 Offset += sizeof(SK_U64);
4945 break;
4946
4947 case OID_SKGE_RLMT_RX_SP_CTS:
4948 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
4949 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4950 Offset += sizeof(SK_U64);
4951 break;
4952
4953 default:
4954 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
4955 ("RlmtStat: Unknown OID should be errored before"));
4956
4957 pAC->Pnmi.RlmtUpdatedFlag --;
4958 *pLen = 0;
4959 return (SK_PNMI_ERR_GENERAL);
4960 }
4961 }
4962 *pLen = Offset;
4963
4964 pAC->Pnmi.RlmtUpdatedFlag --;
4965
4966 return (SK_PNMI_ERR_OK);
4967 }
4968
4969 /*****************************************************************************
4970 *
4971 * MacPrivateConf - OID handler function of OIDs concerning the configuration
4972 *
4973 * Description:
4974 * Get/Presets/Sets the OIDs concerning the configuration.
4975 *
4976 * Returns:
4977 * SK_PNMI_ERR_OK The request was successfully performed.
4978 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4979 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4980 * the correct data (e.g. a 32bit value is
4981 * needed, but a 16 bit value was passed).
4982 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
4983 * value range.
4984 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
4985 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4986 * exist (e.g. port instance 3 on a two port
4987 * adapter.
4988 */
MacPrivateConf(SK_AC * pAC,SK_IOC IoC,int Action,SK_U32 Id,char * pBuf,unsigned int * pLen,SK_U32 Instance,unsigned int TableIndex,SK_U32 NetIndex)4989 PNMI_STATIC int MacPrivateConf(
4990 SK_AC *pAC, /* Pointer to adapter context */
4991 SK_IOC IoC, /* IO context handle */
4992 int Action, /* GET/PRESET/SET action */
4993 SK_U32 Id, /* Object ID that is to be processed */
4994 char *pBuf, /* Buffer used for the management data transfer */
4995 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4996 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4997 unsigned int TableIndex, /* Index to the Id table */
4998 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
4999 {
5000 unsigned int PhysPortMax;
5001 unsigned int PhysPortIndex;
5002 unsigned int LogPortMax;
5003 unsigned int LogPortIndex;
5004 unsigned int Limit;
5005 unsigned int Offset;
5006 char Val8;
5007 char *pBufPtr;
5008 int Ret;
5009 SK_EVPARA EventParam;
5010 SK_U32 Val32;
5011
5012 /*
5013 * Calculate instance if wished. MAC index 0 is the virtual MAC.
5014 */
5015 PhysPortMax = pAC->GIni.GIMacsFound;
5016 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
5017
5018 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
5019 LogPortMax--;
5020 }
5021
5022 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
5023 /* Check instance range */
5024 if ((Instance < 1) || (Instance > LogPortMax)) {
5025
5026 *pLen = 0;
5027 return (SK_PNMI_ERR_UNKNOWN_INST);
5028 }
5029 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
5030 Limit = LogPortIndex + 1;
5031 }
5032
5033 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
5034
5035 LogPortIndex = 0;
5036 Limit = LogPortMax;
5037 }
5038
5039 /*
5040 * Perform action
5041 */
5042 if (Action == SK_PNMI_GET) {
5043
5044 /* Check length */
5045 switch (Id) {
5046
5047 case OID_SKGE_PMD:
5048 case OID_SKGE_CONNECTOR:
5049 case OID_SKGE_LINK_CAP:
5050 case OID_SKGE_LINK_MODE:
5051 case OID_SKGE_LINK_MODE_STATUS:
5052 case OID_SKGE_LINK_STATUS:
5053 case OID_SKGE_FLOWCTRL_CAP:
5054 case OID_SKGE_FLOWCTRL_MODE:
5055 case OID_SKGE_FLOWCTRL_STATUS:
5056 case OID_SKGE_PHY_OPERATION_CAP:
5057 case OID_SKGE_PHY_OPERATION_MODE:
5058 case OID_SKGE_PHY_OPERATION_STATUS:
5059 case OID_SKGE_SPEED_CAP:
5060 case OID_SKGE_SPEED_MODE:
5061 case OID_SKGE_SPEED_STATUS:
5062 #ifdef SK_PHY_LP_MODE
5063 case OID_SKGE_PHY_LP_MODE:
5064 #endif
5065 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
5066
5067 *pLen = (Limit - LogPortIndex) * sizeof(SK_U8);
5068 return (SK_PNMI_ERR_TOO_SHORT);
5069 }
5070 break;
5071
5072 case OID_SKGE_MTU:
5073 case OID_SKGE_PHY_TYPE:
5074 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) {
5075
5076 *pLen = (Limit - LogPortIndex) * sizeof(SK_U32);
5077 return (SK_PNMI_ERR_TOO_SHORT);
5078 }
5079 break;
5080
5081 default:
5082 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
5083 SK_PNMI_ERR041MSG);
5084 *pLen = 0;
5085 return (SK_PNMI_ERR_GENERAL);
5086 }
5087
5088 /*
5089 * Update statistic and increment semaphore to indicate
5090 * that an update was already done.
5091 */
5092 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
5093
5094 *pLen = 0;
5095 return (Ret);
5096 }
5097 pAC->Pnmi.SirqUpdatedFlag ++;
5098
5099 /*
5100 * Get value
5101 */
5102 Offset = 0;
5103 for (; LogPortIndex < Limit; LogPortIndex ++) {
5104
5105 pBufPtr = pBuf + Offset;
5106
5107 switch (Id) {
5108
5109 case OID_SKGE_PMD:
5110 *pBufPtr = pAC->Pnmi.PMD;
5111 Offset += sizeof(char);
5112 break;
5113
5114 case OID_SKGE_CONNECTOR:
5115 *pBufPtr = pAC->Pnmi.Connector;
5116 Offset += sizeof(char);
5117 break;
5118
5119 case OID_SKGE_PHY_TYPE:
5120 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5121 if (LogPortIndex == 0) {
5122 continue;
5123 }
5124 else {
5125 /* Get value for physical ports */
5126 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5127 pAC, LogPortIndex);
5128 Val32 = pAC->GIni.GP[PhysPortIndex].PhyType;
5129 SK_PNMI_STORE_U32(pBufPtr, Val32);
5130 }
5131 }
5132 else { /* DualNetMode */
5133
5134 Val32 = pAC->GIni.GP[NetIndex].PhyType;
5135 SK_PNMI_STORE_U32(pBufPtr, Val32);
5136 }
5137 Offset += sizeof(SK_U32);
5138 break;
5139
5140 #ifdef SK_PHY_LP_MODE
5141 case OID_SKGE_PHY_LP_MODE:
5142 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5143 if (LogPortIndex == 0) {
5144 continue;
5145 }
5146 else {
5147 /* Get value for physical ports */
5148 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
5149 Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
5150 *pBufPtr = Val8;
5151 }
5152 }
5153 else { /* DualNetMode */
5154
5155 Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
5156 *pBufPtr = Val8;
5157 }
5158 Offset += sizeof(SK_U8);
5159 break;
5160 #endif
5161
5162 case OID_SKGE_LINK_CAP:
5163 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5164 if (LogPortIndex == 0) {
5165 /* Get value for virtual port */
5166 VirtualConf(pAC, IoC, Id, pBufPtr);
5167 }
5168 else {
5169 /* Get value for physical ports */
5170 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5171 pAC, LogPortIndex);
5172
5173 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkCap;
5174 }
5175 }
5176 else { /* DualNetMode */
5177
5178 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap;
5179 }
5180 Offset += sizeof(char);
5181 break;
5182
5183 case OID_SKGE_LINK_MODE:
5184 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5185 if (LogPortIndex == 0) {
5186 /* Get value for virtual port */
5187 VirtualConf(pAC, IoC, Id, pBufPtr);
5188 }
5189 else {
5190 /* Get value for physical ports */
5191 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5192 pAC, LogPortIndex);
5193
5194 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
5195 }
5196 }
5197 else { /* DualNetMode */
5198
5199 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf;
5200 }
5201 Offset += sizeof(char);
5202 break;
5203
5204 case OID_SKGE_LINK_MODE_STATUS:
5205 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5206 if (LogPortIndex == 0) {
5207 /* Get value for virtual port */
5208 VirtualConf(pAC, IoC, Id, pBufPtr);
5209 }
5210 else {
5211 /* Get value for physical port */
5212 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5213 pAC, LogPortIndex);
5214
5215 *pBufPtr =
5216 CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
5217 }
5218 }
5219 else { /* DualNetMode */
5220
5221 *pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex);
5222 }
5223 Offset += sizeof(char);
5224 break;
5225
5226 case OID_SKGE_LINK_STATUS:
5227 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5228 if (LogPortIndex == 0) {
5229 /* Get value for virtual port */
5230 VirtualConf(pAC, IoC, Id, pBufPtr);
5231 }
5232 else {
5233 /* Get value for physical ports */
5234 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5235 pAC, LogPortIndex);
5236
5237 *pBufPtr = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
5238 }
5239 }
5240 else { /* DualNetMode */
5241
5242 *pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex);
5243 }
5244 Offset += sizeof(char);
5245 break;
5246
5247 case OID_SKGE_FLOWCTRL_CAP:
5248 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5249 if (LogPortIndex == 0) {
5250 /* Get value for virtual port */
5251 VirtualConf(pAC, IoC, Id, pBufPtr);
5252 }
5253 else {
5254 /* Get value for physical ports */
5255 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5256 pAC, LogPortIndex);
5257
5258 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
5259 }
5260 }
5261 else { /* DualNetMode */
5262
5263 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
5264 }
5265 Offset += sizeof(char);
5266 break;
5267
5268 case OID_SKGE_FLOWCTRL_MODE:
5269 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5270 if (LogPortIndex == 0) {
5271 /* Get value for virtual port */
5272 VirtualConf(pAC, IoC, Id, pBufPtr);
5273 }
5274 else {
5275 /* Get value for physical port */
5276 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5277 pAC, LogPortIndex);
5278
5279 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
5280 }
5281 }
5282 else { /* DualNetMode */
5283
5284 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
5285 }
5286 Offset += sizeof(char);
5287 break;
5288
5289 case OID_SKGE_FLOWCTRL_STATUS:
5290 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5291 if (LogPortIndex == 0) {
5292 /* Get value for virtual port */
5293 VirtualConf(pAC, IoC, Id, pBufPtr);
5294 }
5295 else {
5296 /* Get value for physical port */
5297 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5298 pAC, LogPortIndex);
5299
5300 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
5301 }
5302 }
5303 else { /* DualNetMode */
5304
5305 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
5306 }
5307 Offset += sizeof(char);
5308 break;
5309
5310 case OID_SKGE_PHY_OPERATION_CAP:
5311 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5312 if (LogPortIndex == 0) {
5313 /* Get value for virtual port */
5314 VirtualConf(pAC, IoC, Id, pBufPtr);
5315 }
5316 else {
5317 /* Get value for physical ports */
5318 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5319 pAC, LogPortIndex);
5320
5321 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSCap;
5322 }
5323 }
5324 else { /* DualNetMode */
5325
5326 *pBufPtr = pAC->GIni.GP[NetIndex].PMSCap;
5327 }
5328 Offset += sizeof(char);
5329 break;
5330
5331 case OID_SKGE_PHY_OPERATION_MODE:
5332 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5333 if (LogPortIndex == 0) {
5334 /* Get value for virtual port */
5335 VirtualConf(pAC, IoC, Id, pBufPtr);
5336 }
5337 else {
5338 /* Get value for physical port */
5339 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5340 pAC, LogPortIndex);
5341
5342 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSMode;
5343 }
5344 }
5345 else { /* DualNetMode */
5346
5347 *pBufPtr = pAC->GIni.GP[NetIndex].PMSMode;
5348 }
5349 Offset += sizeof(char);
5350 break;
5351
5352 case OID_SKGE_PHY_OPERATION_STATUS:
5353 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5354 if (LogPortIndex == 0) {
5355 /* Get value for virtual port */
5356 VirtualConf(pAC, IoC, Id, pBufPtr);
5357 }
5358 else {
5359 /* Get value for physical port */
5360 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5361 pAC, LogPortIndex);
5362
5363 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSStatus;
5364 }
5365 }
5366 else {
5367
5368 *pBufPtr = pAC->GIni.GP[NetIndex].PMSStatus;
5369 }
5370 Offset += sizeof(char);
5371 break;
5372
5373 case OID_SKGE_SPEED_CAP:
5374 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5375 if (LogPortIndex == 0) {
5376 /* Get value for virtual port */
5377 VirtualConf(pAC, IoC, Id, pBufPtr);
5378 }
5379 else {
5380 /* Get value for physical ports */
5381 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5382 pAC, LogPortIndex);
5383
5384 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedCap;
5385 }
5386 }
5387 else { /* DualNetMode */
5388
5389 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
5390 }
5391 Offset += sizeof(char);
5392 break;
5393
5394 case OID_SKGE_SPEED_MODE:
5395 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5396 if (LogPortIndex == 0) {
5397 /* Get value for virtual port */
5398 VirtualConf(pAC, IoC, Id, pBufPtr);
5399 }
5400 else {
5401 /* Get value for physical port */
5402 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5403 pAC, LogPortIndex);
5404
5405 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
5406 }
5407 }
5408 else { /* DualNetMode */
5409
5410 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed;
5411 }
5412 Offset += sizeof(char);
5413 break;
5414
5415 case OID_SKGE_SPEED_STATUS:
5416 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5417 if (LogPortIndex == 0) {
5418 /* Get value for virtual port */
5419 VirtualConf(pAC, IoC, Id, pBufPtr);
5420 }
5421 else {
5422 /* Get value for physical port */
5423 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5424 pAC, LogPortIndex);
5425
5426 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
5427 }
5428 }
5429 else { /* DualNetMode */
5430
5431 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
5432 }
5433 Offset += sizeof(char);
5434 break;
5435
5436 case OID_SKGE_MTU:
5437 Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
5438 SK_PNMI_STORE_U32(pBufPtr, Val32);
5439 Offset += sizeof(SK_U32);
5440 break;
5441
5442 default:
5443 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5444 ("MacPrivateConf: Unknown OID should be handled before"));
5445
5446 pAC->Pnmi.SirqUpdatedFlag --;
5447 return (SK_PNMI_ERR_GENERAL);
5448 }
5449 }
5450 *pLen = Offset;
5451 pAC->Pnmi.SirqUpdatedFlag --;
5452
5453 return (SK_PNMI_ERR_OK);
5454 }
5455
5456 /*
5457 * From here SET or PRESET action. Check if the passed
5458 * buffer length is plausible.
5459 */
5460 switch (Id) {
5461
5462 case OID_SKGE_LINK_MODE:
5463 case OID_SKGE_FLOWCTRL_MODE:
5464 case OID_SKGE_PHY_OPERATION_MODE:
5465 case OID_SKGE_SPEED_MODE:
5466 if (*pLen < Limit - LogPortIndex) {
5467
5468 *pLen = Limit - LogPortIndex;
5469 return (SK_PNMI_ERR_TOO_SHORT);
5470 }
5471 if (*pLen != Limit - LogPortIndex) {
5472
5473 *pLen = 0;
5474 return (SK_PNMI_ERR_BAD_VALUE);
5475 }
5476 break;
5477
5478 #ifdef SK_PHY_LP_MODE
5479 case OID_SKGE_PHY_LP_MODE:
5480 if (*pLen < Limit - LogPortIndex) {
5481
5482 *pLen = Limit - LogPortIndex;
5483 return (SK_PNMI_ERR_TOO_SHORT);
5484 }
5485 break;
5486 #endif
5487
5488 case OID_SKGE_MTU:
5489 if (*pLen < sizeof(SK_U32)) {
5490
5491 *pLen = sizeof(SK_U32);
5492 return (SK_PNMI_ERR_TOO_SHORT);
5493 }
5494 if (*pLen != sizeof(SK_U32)) {
5495
5496 *pLen = 0;
5497 return (SK_PNMI_ERR_BAD_VALUE);
5498 }
5499 break;
5500
5501 default:
5502 *pLen = 0;
5503 return (SK_PNMI_ERR_READ_ONLY);
5504 }
5505
5506 /*
5507 * Perform preset or set
5508 */
5509 Offset = 0;
5510 for (; LogPortIndex < Limit; LogPortIndex ++) {
5511
5512 switch (Id) {
5513
5514 case OID_SKGE_LINK_MODE:
5515 /* Check the value range */
5516 Val8 = *(pBuf + Offset);
5517 if (Val8 == 0) {
5518
5519 Offset += sizeof(char);
5520 break;
5521 }
5522 if (Val8 < SK_LMODE_HALF ||
5523 (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
5524 (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
5525
5526 *pLen = 0;
5527 return (SK_PNMI_ERR_BAD_VALUE);
5528 }
5529
5530 /* The preset ends here */
5531 if (Action == SK_PNMI_PRESET) {
5532
5533 return (SK_PNMI_ERR_OK);
5534 }
5535
5536 if (LogPortIndex == 0) {
5537
5538 /*
5539 * The virtual port consists of all currently
5540 * active ports. Find them and send an event
5541 * with the new link mode to SIRQ.
5542 */
5543 for (PhysPortIndex = 0;
5544 PhysPortIndex < PhysPortMax;
5545 PhysPortIndex ++) {
5546
5547 if (!pAC->Pnmi.Port[PhysPortIndex].
5548 ActiveFlag) {
5549
5550 continue;
5551 }
5552
5553 EventParam.Para32[0] = PhysPortIndex;
5554 EventParam.Para32[1] = (SK_U32)Val8;
5555 if (SkGeSirqEvent(pAC, IoC,
5556 SK_HWEV_SET_LMODE,
5557 EventParam) > 0) {
5558
5559 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5560 SK_PNMI_ERR043,
5561 SK_PNMI_ERR043MSG);
5562
5563 *pLen = 0;
5564 return (SK_PNMI_ERR_GENERAL);
5565 }
5566 }
5567 }
5568 else {
5569 /*
5570 * Send an event with the new link mode to
5571 * the SIRQ module.
5572 */
5573 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5574 pAC, LogPortIndex);
5575 EventParam.Para32[1] = (SK_U32)Val8;
5576 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
5577 EventParam) > 0) {
5578
5579 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5580 SK_PNMI_ERR043,
5581 SK_PNMI_ERR043MSG);
5582
5583 *pLen = 0;
5584 return (SK_PNMI_ERR_GENERAL);
5585 }
5586 }
5587 Offset += sizeof(char);
5588 break;
5589
5590 case OID_SKGE_FLOWCTRL_MODE:
5591 /* Check the value range */
5592 Val8 = *(pBuf + Offset);
5593 if (Val8 == 0) {
5594
5595 Offset += sizeof(char);
5596 break;
5597 }
5598 if (Val8 < SK_FLOW_MODE_NONE ||
5599 (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
5600 (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
5601
5602 *pLen = 0;
5603 return (SK_PNMI_ERR_BAD_VALUE);
5604 }
5605
5606 /* The preset ends here */
5607 if (Action == SK_PNMI_PRESET) {
5608
5609 return (SK_PNMI_ERR_OK);
5610 }
5611
5612 if (LogPortIndex == 0) {
5613
5614 /*
5615 * The virtual port consists of all currently
5616 * active ports. Find them and send an event
5617 * with the new flow control mode to SIRQ.
5618 */
5619 for (PhysPortIndex = 0;
5620 PhysPortIndex < PhysPortMax;
5621 PhysPortIndex ++) {
5622
5623 if (!pAC->Pnmi.Port[PhysPortIndex].
5624 ActiveFlag) {
5625
5626 continue;
5627 }
5628
5629 EventParam.Para32[0] = PhysPortIndex;
5630 EventParam.Para32[1] = (SK_U32)Val8;
5631 if (SkGeSirqEvent(pAC, IoC,
5632 SK_HWEV_SET_FLOWMODE,
5633 EventParam) > 0) {
5634
5635 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5636 SK_PNMI_ERR044,
5637 SK_PNMI_ERR044MSG);
5638
5639 *pLen = 0;
5640 return (SK_PNMI_ERR_GENERAL);
5641 }
5642 }
5643 }
5644 else {
5645 /*
5646 * Send an event with the new flow control
5647 * mode to the SIRQ module.
5648 */
5649 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5650 pAC, LogPortIndex);
5651 EventParam.Para32[1] = (SK_U32)Val8;
5652 if (SkGeSirqEvent(pAC, IoC,
5653 SK_HWEV_SET_FLOWMODE, EventParam)
5654 > 0) {
5655
5656 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5657 SK_PNMI_ERR044,
5658 SK_PNMI_ERR044MSG);
5659
5660 *pLen = 0;
5661 return (SK_PNMI_ERR_GENERAL);
5662 }
5663 }
5664 Offset += sizeof(char);
5665 break;
5666
5667 case OID_SKGE_PHY_OPERATION_MODE :
5668 /* Check the value range */
5669 Val8 = *(pBuf + Offset);
5670 if (Val8 == 0) {
5671 /* mode of this port remains unchanged */
5672 Offset += sizeof(char);
5673 break;
5674 }
5675 if (Val8 < SK_MS_MODE_AUTO ||
5676 (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
5677 (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
5678
5679 *pLen = 0;
5680 return (SK_PNMI_ERR_BAD_VALUE);
5681 }
5682
5683 /* The preset ends here */
5684 if (Action == SK_PNMI_PRESET) {
5685
5686 return (SK_PNMI_ERR_OK);
5687 }
5688
5689 if (LogPortIndex == 0) {
5690
5691 /*
5692 * The virtual port consists of all currently
5693 * active ports. Find them and send an event
5694 * with new master/slave (role) mode to SIRQ.
5695 */
5696 for (PhysPortIndex = 0;
5697 PhysPortIndex < PhysPortMax;
5698 PhysPortIndex ++) {
5699
5700 if (!pAC->Pnmi.Port[PhysPortIndex].
5701 ActiveFlag) {
5702
5703 continue;
5704 }
5705
5706 EventParam.Para32[0] = PhysPortIndex;
5707 EventParam.Para32[1] = (SK_U32)Val8;
5708 if (SkGeSirqEvent(pAC, IoC,
5709 SK_HWEV_SET_ROLE,
5710 EventParam) > 0) {
5711
5712 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5713 SK_PNMI_ERR042,
5714 SK_PNMI_ERR042MSG);
5715
5716 *pLen = 0;
5717 return (SK_PNMI_ERR_GENERAL);
5718 }
5719 }
5720 }
5721 else {
5722 /*
5723 * Send an event with the new master/slave
5724 * (role) mode to the SIRQ module.
5725 */
5726 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5727 pAC, LogPortIndex);
5728 EventParam.Para32[1] = (SK_U32)Val8;
5729 if (SkGeSirqEvent(pAC, IoC,
5730 SK_HWEV_SET_ROLE, EventParam) > 0) {
5731
5732 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5733 SK_PNMI_ERR042,
5734 SK_PNMI_ERR042MSG);
5735
5736 *pLen = 0;
5737 return (SK_PNMI_ERR_GENERAL);
5738 }
5739 }
5740
5741 Offset += sizeof(char);
5742 break;
5743
5744 case OID_SKGE_SPEED_MODE:
5745 /* Check the value range */
5746 Val8 = *(pBuf + Offset);
5747 if (Val8 == 0) {
5748
5749 Offset += sizeof(char);
5750 break;
5751 }
5752 if (Val8 < (SK_LSPEED_AUTO) ||
5753 (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) ||
5754 (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) {
5755
5756 *pLen = 0;
5757 return (SK_PNMI_ERR_BAD_VALUE);
5758 }
5759
5760 /* The preset ends here */
5761 if (Action == SK_PNMI_PRESET) {
5762
5763 return (SK_PNMI_ERR_OK);
5764 }
5765
5766 if (LogPortIndex == 0) {
5767
5768 /*
5769 * The virtual port consists of all currently
5770 * active ports. Find them and send an event
5771 * with the new flow control mode to SIRQ.
5772 */
5773 for (PhysPortIndex = 0;
5774 PhysPortIndex < PhysPortMax;
5775 PhysPortIndex ++) {
5776
5777 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
5778
5779 continue;
5780 }
5781
5782 EventParam.Para32[0] = PhysPortIndex;
5783 EventParam.Para32[1] = (SK_U32)Val8;
5784 if (SkGeSirqEvent(pAC, IoC,
5785 SK_HWEV_SET_SPEED,
5786 EventParam) > 0) {
5787
5788 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5789 SK_PNMI_ERR045,
5790 SK_PNMI_ERR045MSG);
5791
5792 *pLen = 0;
5793 return (SK_PNMI_ERR_GENERAL);
5794 }
5795 }
5796 }
5797 else {
5798 /*
5799 * Send an event with the new flow control
5800 * mode to the SIRQ module.
5801 */
5802 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5803 pAC, LogPortIndex);
5804 EventParam.Para32[1] = (SK_U32)Val8;
5805 if (SkGeSirqEvent(pAC, IoC,
5806 SK_HWEV_SET_SPEED,
5807 EventParam) > 0) {
5808
5809 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5810 SK_PNMI_ERR045,
5811 SK_PNMI_ERR045MSG);
5812
5813 *pLen = 0;
5814 return (SK_PNMI_ERR_GENERAL);
5815 }
5816 }
5817 Offset += sizeof(char);
5818 break;
5819
5820 case OID_SKGE_MTU :
5821 /* Check the value range */
5822 Val32 = *(SK_U32*)(pBuf + Offset);
5823 if (Val32 == 0) {
5824 /* mtu of this port remains unchanged */
5825 Offset += sizeof(SK_U32);
5826 break;
5827 }
5828 if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
5829 *pLen = 0;
5830 return (SK_PNMI_ERR_BAD_VALUE);
5831 }
5832
5833 /* The preset ends here */
5834 if (Action == SK_PNMI_PRESET) {
5835 return (SK_PNMI_ERR_OK);
5836 }
5837
5838 if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
5839 return (SK_PNMI_ERR_GENERAL);
5840 }
5841
5842 Offset += sizeof(SK_U32);
5843 break;
5844
5845 #ifdef SK_PHY_LP_MODE
5846 case OID_SKGE_PHY_LP_MODE:
5847 /* The preset ends here */
5848 if (Action == SK_PNMI_PRESET) {
5849
5850 return (SK_PNMI_ERR_OK);
5851 }
5852
5853 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5854 if (LogPortIndex == 0) {
5855 Offset = 0;
5856 continue;
5857 }
5858 else {
5859 /* Set value for physical ports */
5860 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
5861
5862 switch (*(pBuf + Offset)) {
5863 case 0:
5864 /* If LowPowerMode is active, we can leave it. */
5865 if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
5866
5867 Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex);
5868
5869 if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) {
5870
5871 SkDrvInitAdapter(pAC);
5872 }
5873 break;
5874 }
5875 else {
5876 *pLen = 0;
5877 return (SK_PNMI_ERR_GENERAL);
5878 }
5879 case 1:
5880 case 2:
5881 case 3:
5882 case 4:
5883 /* If no LowPowerMode is active, we can enter it. */
5884 if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
5885
5886 if ((*(pBuf + Offset)) < 3) {
5887
5888 SkDrvDeInitAdapter(pAC);
5889 }
5890
5891 Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf);
5892 break;
5893 }
5894 else {
5895 *pLen = 0;
5896 return (SK_PNMI_ERR_GENERAL);
5897 }
5898 default:
5899 *pLen = 0;
5900 return (SK_PNMI_ERR_BAD_VALUE);
5901 }
5902 }
5903 }
5904 else { /* DualNetMode */
5905
5906 switch (*(pBuf + Offset)) {
5907 case 0:
5908 /* If we are in a LowPowerMode, we can leave it. */
5909 if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
5910
5911 Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex);
5912
5913 if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) {
5914
5915 SkDrvInitAdapter(pAC);
5916 }
5917 break;
5918 }
5919 else {
5920 *pLen = 0;
5921 return (SK_PNMI_ERR_GENERAL);
5922 }
5923
5924 case 1:
5925 case 2:
5926 case 3:
5927 case 4:
5928 /* If we are not already in LowPowerMode, we can enter it. */
5929 if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
5930
5931 if ((*(pBuf + Offset)) < 3) {
5932
5933 SkDrvDeInitAdapter(pAC);
5934 }
5935 else {
5936
5937 Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf);
5938 }
5939 break;
5940 }
5941 else {
5942 *pLen = 0;
5943 return (SK_PNMI_ERR_GENERAL);
5944 }
5945
5946 default:
5947 *pLen = 0;
5948 return (SK_PNMI_ERR_BAD_VALUE);
5949 }
5950 }
5951 Offset += sizeof(SK_U8);
5952 break;
5953 #endif
5954
5955 default:
5956 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5957 ("MacPrivateConf: Unknown OID should be handled before set"));
5958
5959 *pLen = 0;
5960 return (SK_PNMI_ERR_GENERAL);
5961 }
5962 }
5963
5964 return (SK_PNMI_ERR_OK);
5965 }
5966
5967 /*****************************************************************************
5968 *
5969 * Monitor - OID handler function for RLMT_MONITOR_XXX
5970 *
5971 * Description:
5972 * Because RLMT currently does not support the monitoring of
5973 * remote adapter cards, we return always an empty table.
5974 *
5975 * Returns:
5976 * SK_PNMI_ERR_OK The request was successfully performed.
5977 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
5978 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
5979 * the correct data (e.g. a 32bit value is
5980 * needed, but a 16 bit value was passed).
5981 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
5982 * value range.
5983 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
5984 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
5985 * exist (e.g. port instance 3 on a two port
5986 * adapter.
5987 */
Monitor(SK_AC * pAC,SK_IOC IoC,int Action,SK_U32 Id,char * pBuf,unsigned int * pLen,SK_U32 Instance,unsigned int TableIndex,SK_U32 NetIndex)5988 PNMI_STATIC int Monitor(
5989 SK_AC *pAC, /* Pointer to adapter context */
5990 SK_IOC IoC, /* IO context handle */
5991 int Action, /* GET/PRESET/SET action */
5992 SK_U32 Id, /* Object ID that is to be processed */
5993 char *pBuf, /* Buffer used for the management data transfer */
5994 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
5995 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5996 unsigned int TableIndex, /* Index to the Id table */
5997 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
5998 {
5999 unsigned int Index;
6000 unsigned int Limit;
6001 unsigned int Offset;
6002 unsigned int Entries;
6003
6004
6005 /*
6006 * Calculate instance if wished.
6007 */
6008 /* XXX Not yet implemented. Return always an empty table. */
6009 Entries = 0;
6010
6011 if ((Instance != (SK_U32)(-1))) {
6012
6013 if ((Instance < 1) || (Instance > Entries)) {
6014
6015 *pLen = 0;
6016 return (SK_PNMI_ERR_UNKNOWN_INST);
6017 }
6018
6019 Index = (unsigned int)Instance - 1;
6020 Limit = (unsigned int)Instance;
6021 }
6022 else {
6023 Index = 0;
6024 Limit = Entries;
6025 }
6026
6027 /*
6028 * Get/Set value
6029 */
6030 if (Action == SK_PNMI_GET) {
6031
6032 for (Offset=0; Index < Limit; Index ++) {
6033
6034 switch (Id) {
6035
6036 case OID_SKGE_RLMT_MONITOR_INDEX:
6037 case OID_SKGE_RLMT_MONITOR_ADDR:
6038 case OID_SKGE_RLMT_MONITOR_ERRS:
6039 case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
6040 case OID_SKGE_RLMT_MONITOR_ADMIN:
6041 break;
6042
6043 default:
6044 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
6045 SK_PNMI_ERR046MSG);
6046
6047 *pLen = 0;
6048 return (SK_PNMI_ERR_GENERAL);
6049 }
6050 }
6051 *pLen = Offset;
6052 }
6053 else {
6054 /* Only MONITOR_ADMIN can be set */
6055 if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
6056
6057 *pLen = 0;
6058 return (SK_PNMI_ERR_READ_ONLY);
6059 }
6060
6061 /* Check if the length is plausible */
6062 if (*pLen < (Limit - Index)) {
6063
6064 return (SK_PNMI_ERR_TOO_SHORT);
6065 }
6066 /* Okay, we have a wide value range */
6067 if (*pLen != (Limit - Index)) {
6068
6069 *pLen = 0;
6070 return (SK_PNMI_ERR_BAD_VALUE);
6071 }
6072 /*
6073 for (Offset=0; Index < Limit; Index ++) {
6074 }
6075 */
6076 /*
6077 * XXX Not yet implemented. Return always BAD_VALUE, because the table
6078 * is empty.
6079 */
6080 *pLen = 0;
6081 return (SK_PNMI_ERR_BAD_VALUE);
6082 }
6083
6084 return (SK_PNMI_ERR_OK);
6085 }
6086
6087 /*****************************************************************************
6088 *
6089 * VirtualConf - Calculates the values of configuration OIDs for virtual port
6090 *
6091 * Description:
6092 * We handle here the get of the configuration group OIDs, which are
6093 * a little bit complicated. The virtual port consists of all currently
6094 * active physical ports. If multiple ports are active and configured
6095 * differently we get in some trouble to return a single value. So we
6096 * get the value of the first active port and compare it with that of
6097 * the other active ports. If they are not the same, we return a value
6098 * that indicates that the state is indeterminated.
6099 *
6100 * Returns:
6101 * Nothing
6102 */
VirtualConf(SK_AC * pAC,SK_IOC IoC,SK_U32 Id,char * pBuf)6103 PNMI_STATIC void VirtualConf(
6104 SK_AC *pAC, /* Pointer to adapter context */
6105 SK_IOC IoC, /* IO context handle */
6106 SK_U32 Id, /* Object ID that is to be processed */
6107 char *pBuf) /* Buffer used for the management data transfer */
6108 {
6109 unsigned int PhysPortMax;
6110 unsigned int PhysPortIndex;
6111 SK_U8 Val8;
6112 SK_U32 Val32;
6113 SK_BOOL PortActiveFlag;
6114 SK_GEPORT *pPrt;
6115
6116 *pBuf = 0;
6117 PortActiveFlag = SK_FALSE;
6118 PhysPortMax = pAC->GIni.GIMacsFound;
6119
6120 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
6121 PhysPortIndex ++) {
6122
6123 pPrt = &pAC->GIni.GP[PhysPortIndex];
6124
6125 /* Check if the physical port is active */
6126 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6127
6128 continue;
6129 }
6130
6131 PortActiveFlag = SK_TRUE;
6132
6133 switch (Id) {
6134
6135 case OID_SKGE_PHY_TYPE:
6136 /* Check if it is the first active port */
6137 if (*pBuf == 0) {
6138 Val32 = pPrt->PhyType;
6139 SK_PNMI_STORE_U32(pBuf, Val32);
6140 continue;
6141 }
6142
6143 case OID_SKGE_LINK_CAP:
6144
6145 /*
6146 * Different capabilities should not happen, but
6147 * in the case of the cases OR them all together.
6148 * From a curious point of view the virtual port
6149 * is capable of all found capabilities.
6150 */
6151 *pBuf |= pPrt->PLinkCap;
6152 break;
6153
6154 case OID_SKGE_LINK_MODE:
6155 /* Check if it is the first active port */
6156 if (*pBuf == 0) {
6157
6158 *pBuf = pPrt->PLinkModeConf;
6159 continue;
6160 }
6161
6162 /*
6163 * If we find an active port with a different link
6164 * mode than the first one we return a value that
6165 * indicates that the link mode is indeterminated.
6166 */
6167 if (*pBuf != pPrt->PLinkModeConf) {
6168
6169 *pBuf = SK_LMODE_INDETERMINATED;
6170 }
6171 break;
6172
6173 case OID_SKGE_LINK_MODE_STATUS:
6174 /* Get the link mode of the physical port */
6175 Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
6176
6177 /* Check if it is the first active port */
6178 if (*pBuf == 0) {
6179
6180 *pBuf = Val8;
6181 continue;
6182 }
6183
6184 /*
6185 * If we find an active port with a different link
6186 * mode status than the first one we return a value
6187 * that indicates that the link mode status is
6188 * indeterminated.
6189 */
6190 if (*pBuf != Val8) {
6191
6192 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6193 }
6194 break;
6195
6196 case OID_SKGE_LINK_STATUS:
6197 /* Get the link status of the physical port */
6198 Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
6199
6200 /* Check if it is the first active port */
6201 if (*pBuf == 0) {
6202
6203 *pBuf = Val8;
6204 continue;
6205 }
6206
6207 /*
6208 * If we find an active port with a different link
6209 * status than the first one, we return a value
6210 * that indicates that the link status is
6211 * indeterminated.
6212 */
6213 if (*pBuf != Val8) {
6214
6215 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6216 }
6217 break;
6218
6219 case OID_SKGE_FLOWCTRL_CAP:
6220 /* Check if it is the first active port */
6221 if (*pBuf == 0) {
6222
6223 *pBuf = pPrt->PFlowCtrlCap;
6224 continue;
6225 }
6226
6227 /*
6228 * From a curious point of view the virtual port
6229 * is capable of all found capabilities.
6230 */
6231 *pBuf |= pPrt->PFlowCtrlCap;
6232 break;
6233
6234 case OID_SKGE_FLOWCTRL_MODE:
6235 /* Check if it is the first active port */
6236 if (*pBuf == 0) {
6237
6238 *pBuf = pPrt->PFlowCtrlMode;
6239 continue;
6240 }
6241
6242 /*
6243 * If we find an active port with a different flow
6244 * control mode than the first one, we return a value
6245 * that indicates that the mode is indeterminated.
6246 */
6247 if (*pBuf != pPrt->PFlowCtrlMode) {
6248
6249 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6250 }
6251 break;
6252
6253 case OID_SKGE_FLOWCTRL_STATUS:
6254 /* Check if it is the first active port */
6255 if (*pBuf == 0) {
6256
6257 *pBuf = pPrt->PFlowCtrlStatus;
6258 continue;
6259 }
6260
6261 /*
6262 * If we find an active port with a different flow
6263 * control status than the first one, we return a
6264 * value that indicates that the status is
6265 * indeterminated.
6266 */
6267 if (*pBuf != pPrt->PFlowCtrlStatus) {
6268
6269 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6270 }
6271 break;
6272
6273 case OID_SKGE_PHY_OPERATION_CAP:
6274 /* Check if it is the first active port */
6275 if (*pBuf == 0) {
6276
6277 *pBuf = pPrt->PMSCap;
6278 continue;
6279 }
6280
6281 /*
6282 * From a curious point of view the virtual port
6283 * is capable of all found capabilities.
6284 */
6285 *pBuf |= pPrt->PMSCap;
6286 break;
6287
6288 case OID_SKGE_PHY_OPERATION_MODE:
6289 /* Check if it is the first active port */
6290 if (*pBuf == 0) {
6291
6292 *pBuf = pPrt->PMSMode;
6293 continue;
6294 }
6295
6296 /*
6297 * If we find an active port with a different master/
6298 * slave mode than the first one, we return a value
6299 * that indicates that the mode is indeterminated.
6300 */
6301 if (*pBuf != pPrt->PMSMode) {
6302
6303 *pBuf = SK_MS_MODE_INDETERMINATED;
6304 }
6305 break;
6306
6307 case OID_SKGE_PHY_OPERATION_STATUS:
6308 /* Check if it is the first active port */
6309 if (*pBuf == 0) {
6310
6311 *pBuf = pPrt->PMSStatus;
6312 continue;
6313 }
6314
6315 /*
6316 * If we find an active port with a different master/
6317 * slave status than the first one, we return a
6318 * value that indicates that the status is
6319 * indeterminated.
6320 */
6321 if (*pBuf != pPrt->PMSStatus) {
6322
6323 *pBuf = SK_MS_STAT_INDETERMINATED;
6324 }
6325 break;
6326
6327 case OID_SKGE_SPEED_MODE:
6328 /* Check if it is the first active port */
6329 if (*pBuf == 0) {
6330
6331 *pBuf = pPrt->PLinkSpeed;
6332 continue;
6333 }
6334
6335 /*
6336 * If we find an active port with a different flow
6337 * control mode than the first one, we return a value
6338 * that indicates that the mode is indeterminated.
6339 */
6340 if (*pBuf != pPrt->PLinkSpeed) {
6341
6342 *pBuf = SK_LSPEED_INDETERMINATED;
6343 }
6344 break;
6345
6346 case OID_SKGE_SPEED_STATUS:
6347 /* Check if it is the first active port */
6348 if (*pBuf == 0) {
6349
6350 *pBuf = pPrt->PLinkSpeedUsed;
6351 continue;
6352 }
6353
6354 /*
6355 * If we find an active port with a different flow
6356 * control status than the first one, we return a
6357 * value that indicates that the status is
6358 * indeterminated.
6359 */
6360 if (*pBuf != pPrt->PLinkSpeedUsed) {
6361
6362 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6363 }
6364 break;
6365 }
6366 }
6367
6368 /*
6369 * If no port is active return an indeterminated answer
6370 */
6371 if (!PortActiveFlag) {
6372
6373 switch (Id) {
6374
6375 case OID_SKGE_LINK_CAP:
6376 *pBuf = SK_LMODE_CAP_INDETERMINATED;
6377 break;
6378
6379 case OID_SKGE_LINK_MODE:
6380 *pBuf = SK_LMODE_INDETERMINATED;
6381 break;
6382
6383 case OID_SKGE_LINK_MODE_STATUS:
6384 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6385 break;
6386
6387 case OID_SKGE_LINK_STATUS:
6388 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6389 break;
6390
6391 case OID_SKGE_FLOWCTRL_CAP:
6392 case OID_SKGE_FLOWCTRL_MODE:
6393 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6394 break;
6395
6396 case OID_SKGE_FLOWCTRL_STATUS:
6397 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6398 break;
6399
6400 case OID_SKGE_PHY_OPERATION_CAP:
6401 *pBuf = SK_MS_CAP_INDETERMINATED;
6402 break;
6403
6404 case OID_SKGE_PHY_OPERATION_MODE:
6405 *pBuf = SK_MS_MODE_INDETERMINATED;
6406 break;
6407
6408 case OID_SKGE_PHY_OPERATION_STATUS:
6409 *pBuf = SK_MS_STAT_INDETERMINATED;
6410 break;
6411 case OID_SKGE_SPEED_CAP:
6412 *pBuf = SK_LSPEED_CAP_INDETERMINATED;
6413 break;
6414
6415 case OID_SKGE_SPEED_MODE:
6416 *pBuf = SK_LSPEED_INDETERMINATED;
6417 break;
6418
6419 case OID_SKGE_SPEED_STATUS:
6420 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6421 break;
6422 }
6423 }
6424 }
6425
6426 /*****************************************************************************
6427 *
6428 * CalculateLinkStatus - Determins the link status of a physical port
6429 *
6430 * Description:
6431 * Determins the link status the following way:
6432 * LSTAT_PHY_DOWN: Link is down
6433 * LSTAT_AUTONEG: Auto-negotiation failed
6434 * LSTAT_LOG_DOWN: Link is up but RLMT did not yet put the port
6435 * logically up.
6436 * LSTAT_LOG_UP: RLMT marked the port as up
6437 *
6438 * Returns:
6439 * Link status of physical port
6440 */
CalculateLinkStatus(SK_AC * pAC,SK_IOC IoC,unsigned int PhysPortIndex)6441 PNMI_STATIC SK_U8 CalculateLinkStatus(
6442 SK_AC *pAC, /* Pointer to adapter context */
6443 SK_IOC IoC, /* IO context handle */
6444 unsigned int PhysPortIndex) /* Physical port index */
6445 {
6446 SK_U8 Result;
6447
6448 if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
6449
6450 Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
6451 }
6452 else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
6453
6454 Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
6455 }
6456 else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
6457
6458 Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
6459 }
6460 else {
6461 Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
6462 }
6463
6464 return (Result);
6465 }
6466
6467 /*****************************************************************************
6468 *
6469 * CalculateLinkModeStatus - Determins the link mode status of a phys. port
6470 *
6471 * Description:
6472 * The COMMON module only tells us if the mode is half or full duplex.
6473 * But in the decade of auto sensing it is usefull for the user to
6474 * know if the mode was negotiated or forced. Therefore we have a
6475 * look to the mode, which was last used by the negotiation process.
6476 *
6477 * Returns:
6478 * The link mode status
6479 */
CalculateLinkModeStatus(SK_AC * pAC,SK_IOC IoC,unsigned int PhysPortIndex)6480 PNMI_STATIC SK_U8 CalculateLinkModeStatus(
6481 SK_AC *pAC, /* Pointer to adapter context */
6482 SK_IOC IoC, /* IO context handle */
6483 unsigned int PhysPortIndex) /* Physical port index */
6484 {
6485 SK_U8 Result;
6486
6487 /* Get the current mode, which can be full or half duplex */
6488 Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
6489
6490 /* Check if no valid mode could be found (link is down) */
6491 if (Result < SK_LMODE_STAT_HALF) {
6492
6493 Result = SK_LMODE_STAT_UNKNOWN;
6494 }
6495 else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
6496
6497 /*
6498 * Auto-negotiation was used to bring up the link. Change
6499 * the already found duplex status that it indicates
6500 * auto-negotiation was involved.
6501 */
6502 if (Result == SK_LMODE_STAT_HALF) {
6503
6504 Result = SK_LMODE_STAT_AUTOHALF;
6505 }
6506 else if (Result == SK_LMODE_STAT_FULL) {
6507
6508 Result = SK_LMODE_STAT_AUTOFULL;
6509 }
6510 }
6511
6512 return (Result);
6513 }
6514
6515 /*****************************************************************************
6516 *
6517 * GetVpdKeyArr - Obtain an array of VPD keys
6518 *
6519 * Description:
6520 * Read the VPD keys and build an array of VPD keys, which are
6521 * easy to access.
6522 *
6523 * Returns:
6524 * SK_PNMI_ERR_OK Task successfully performed.
6525 * SK_PNMI_ERR_GENERAL Something went wrong.
6526 */
GetVpdKeyArr(SK_AC * pAC,SK_IOC IoC,char * pKeyArr,unsigned int KeyArrLen,unsigned int * pKeyNo)6527 PNMI_STATIC int GetVpdKeyArr(
6528 SK_AC *pAC, /* Pointer to adapter context */
6529 SK_IOC IoC, /* IO context handle */
6530 char *pKeyArr, /* Ptr KeyArray */
6531 unsigned int KeyArrLen, /* Length of array in bytes */
6532 unsigned int *pKeyNo) /* Number of keys */
6533 {
6534 unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE;
6535 char BufKeys[SK_PNMI_VPD_BUFSIZE];
6536 unsigned int StartOffset;
6537 unsigned int Offset;
6538 int Index;
6539 int Ret;
6540
6541
6542 SK_MEMSET(pKeyArr, 0, KeyArrLen);
6543
6544 /*
6545 * Get VPD key list
6546 */
6547 Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
6548 (int *)pKeyNo);
6549 if (Ret > 0) {
6550
6551 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
6552 SK_PNMI_ERR014MSG);
6553
6554 return (SK_PNMI_ERR_GENERAL);
6555 }
6556 /* If no keys are available return now */
6557 if (*pKeyNo == 0 || BufKeysLen == 0) {
6558
6559 return (SK_PNMI_ERR_OK);
6560 }
6561 /*
6562 * If the key list is too long for us trunc it and give a
6563 * errorlog notification. This case should not happen because
6564 * the maximum number of keys is limited due to RAM limitations
6565 */
6566 if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
6567
6568 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
6569 SK_PNMI_ERR015MSG);
6570
6571 *pKeyNo = SK_PNMI_VPD_ENTRIES;
6572 }
6573
6574 /*
6575 * Now build an array of fixed string length size and copy
6576 * the keys together.
6577 */
6578 for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
6579 Offset ++) {
6580
6581 if (BufKeys[Offset] != 0) {
6582
6583 continue;
6584 }
6585
6586 if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
6587
6588 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
6589 SK_PNMI_ERR016MSG);
6590 return (SK_PNMI_ERR_GENERAL);
6591 }
6592
6593 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6594 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6595
6596 Index ++;
6597 StartOffset = Offset + 1;
6598 }
6599
6600 /* Last key not zero terminated? Get it anyway */
6601 if (StartOffset < Offset) {
6602
6603 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6604 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6605 }
6606
6607 return (SK_PNMI_ERR_OK);
6608 }
6609
6610 /*****************************************************************************
6611 *
6612 * SirqUpdate - Let the SIRQ update its internal values
6613 *
6614 * Description:
6615 * Just to be sure that the SIRQ module holds its internal data
6616 * structures up to date, we send an update event before we make
6617 * any access.
6618 *
6619 * Returns:
6620 * SK_PNMI_ERR_OK Task successfully performed.
6621 * SK_PNMI_ERR_GENERAL Something went wrong.
6622 */
SirqUpdate(SK_AC * pAC,SK_IOC IoC)6623 PNMI_STATIC int SirqUpdate(
6624 SK_AC *pAC, /* Pointer to adapter context */
6625 SK_IOC IoC) /* IO context handle */
6626 {
6627 SK_EVPARA EventParam;
6628
6629
6630 /* Was the module already updated during the current PNMI call? */
6631 if (pAC->Pnmi.SirqUpdatedFlag > 0) {
6632
6633 return (SK_PNMI_ERR_OK);
6634 }
6635
6636 /* Send an synchronuous update event to the module */
6637 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6638 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
6639
6640 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
6641 SK_PNMI_ERR047MSG);
6642
6643 return (SK_PNMI_ERR_GENERAL);
6644 }
6645
6646 return (SK_PNMI_ERR_OK);
6647 }
6648
6649 /*****************************************************************************
6650 *
6651 * RlmtUpdate - Let the RLMT update its internal values
6652 *
6653 * Description:
6654 * Just to be sure that the RLMT module holds its internal data
6655 * structures up to date, we send an update event before we make
6656 * any access.
6657 *
6658 * Returns:
6659 * SK_PNMI_ERR_OK Task successfully performed.
6660 * SK_PNMI_ERR_GENERAL Something went wrong.
6661 */
RlmtUpdate(SK_AC * pAC,SK_IOC IoC,SK_U32 NetIndex)6662 PNMI_STATIC int RlmtUpdate(
6663 SK_AC *pAC, /* Pointer to adapter context */
6664 SK_IOC IoC, /* IO context handle */
6665 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6666 {
6667 SK_EVPARA EventParam;
6668
6669
6670 /* Was the module already updated during the current PNMI call? */
6671 if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
6672
6673 return (SK_PNMI_ERR_OK);
6674 }
6675
6676 /* Send an synchronuous update event to the module */
6677 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6678 EventParam.Para32[0] = NetIndex;
6679 EventParam.Para32[1] = (SK_U32)-1;
6680 if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
6681
6682 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
6683 SK_PNMI_ERR048MSG);
6684
6685 return (SK_PNMI_ERR_GENERAL);
6686 }
6687
6688 return (SK_PNMI_ERR_OK);
6689 }
6690
6691 /*****************************************************************************
6692 *
6693 * MacUpdate - Force the XMAC to output the current statistic
6694 *
6695 * Description:
6696 * The XMAC holds its statistic internally. To obtain the current
6697 * values we must send a command so that the statistic data will
6698 * be written to a predefined memory area on the adapter.
6699 *
6700 * Returns:
6701 * SK_PNMI_ERR_OK Task successfully performed.
6702 * SK_PNMI_ERR_GENERAL Something went wrong.
6703 */
MacUpdate(SK_AC * pAC,SK_IOC IoC,unsigned int FirstMac,unsigned int LastMac)6704 PNMI_STATIC int MacUpdate(
6705 SK_AC *pAC, /* Pointer to adapter context */
6706 SK_IOC IoC, /* IO context handle */
6707 unsigned int FirstMac, /* Index of the first Mac to be updated */
6708 unsigned int LastMac) /* Index of the last Mac to be updated */
6709 {
6710 unsigned int MacIndex;
6711
6712 /*
6713 * Were the statistics already updated during the
6714 * current PNMI call?
6715 */
6716 if (pAC->Pnmi.MacUpdatedFlag > 0) {
6717
6718 return (SK_PNMI_ERR_OK);
6719 }
6720
6721 /* Send an update command to all MACs specified */
6722 for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
6723
6724 /*
6725 * 2002-09-13 pweber: Freeze the current SW counters.
6726 * (That should be done as close as
6727 * possible to the update of the
6728 * HW counters)
6729 */
6730 if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
6731 pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
6732 }
6733
6734 /* 2002-09-13 pweber: Update the HW counter */
6735 if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
6736
6737 return (SK_PNMI_ERR_GENERAL);
6738 }
6739 }
6740
6741 return (SK_PNMI_ERR_OK);
6742 }
6743
6744 /*****************************************************************************
6745 *
6746 * GetStatVal - Retrieve an XMAC statistic counter
6747 *
6748 * Description:
6749 * Retrieves the statistic counter of a virtual or physical port. The
6750 * virtual port is identified by the index 0. It consists of all
6751 * currently active ports. To obtain the counter value for this port
6752 * we must add the statistic counter of all active ports. To grant
6753 * continuous counter values for the virtual port even when port
6754 * switches occur we must additionally add a delta value, which was
6755 * calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
6756 *
6757 * Returns:
6758 * Requested statistic value
6759 */
GetStatVal(SK_AC * pAC,SK_IOC IoC,unsigned int LogPortIndex,unsigned int StatIndex,SK_U32 NetIndex)6760 PNMI_STATIC SK_U64 GetStatVal(
6761 SK_AC *pAC, /* Pointer to adapter context */
6762 SK_IOC IoC, /* IO context handle */
6763 unsigned int LogPortIndex, /* Index of the logical Port to be processed */
6764 unsigned int StatIndex, /* Index to statistic value */
6765 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6766 {
6767 unsigned int PhysPortIndex;
6768 unsigned int PhysPortMax;
6769 SK_U64 Val = 0;
6770
6771
6772 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
6773
6774 PhysPortIndex = NetIndex;
6775
6776 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6777 }
6778 else { /* Single Net mode */
6779
6780 if (LogPortIndex == 0) {
6781
6782 PhysPortMax = pAC->GIni.GIMacsFound;
6783
6784 /* Add counter of all active ports */
6785 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
6786 PhysPortIndex ++) {
6787
6788 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6789
6790 Val += GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6791 }
6792 }
6793
6794 /* Correct value because of port switches */
6795 Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
6796 }
6797 else {
6798 /* Get counter value of physical port */
6799 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
6800
6801 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6802 }
6803 }
6804 return (Val);
6805 }
6806
6807 /*****************************************************************************
6808 *
6809 * GetPhysStatVal - Get counter value for physical port
6810 *
6811 * Description:
6812 * Builds a 64bit counter value. Except for the octet counters
6813 * the lower 32bit are counted in hardware and the upper 32bit
6814 * in software by monitoring counter overflow interrupts in the
6815 * event handler. To grant continous counter values during XMAC
6816 * resets (caused by a workaround) we must add a delta value.
6817 * The delta was calculated in the event handler when a
6818 * SK_PNMI_EVT_XMAC_RESET was received.
6819 *
6820 * Returns:
6821 * Counter value
6822 */
GetPhysStatVal(SK_AC * pAC,SK_IOC IoC,unsigned int PhysPortIndex,unsigned int StatIndex)6823 PNMI_STATIC SK_U64 GetPhysStatVal(
6824 SK_AC *pAC, /* Pointer to adapter context */
6825 SK_IOC IoC, /* IO context handle */
6826 unsigned int PhysPortIndex, /* Index of the logical Port to be processed */
6827 unsigned int StatIndex) /* Index to statistic value */
6828 {
6829 SK_U64 Val = 0;
6830 SK_U32 LowVal = 0;
6831 SK_U32 HighVal = 0;
6832 SK_U16 Word;
6833 int MacType;
6834 unsigned int HelpIndex;
6835 SK_GEPORT *pPrt;
6836
6837 SK_PNMI_PORT *pPnmiPrt;
6838 SK_GEMACFUNC *pFnMac;
6839
6840 pPrt = &pAC->GIni.GP[PhysPortIndex];
6841
6842 MacType = pAC->GIni.GIMacType;
6843
6844 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
6845 if (MacType == SK_MAC_XMAC) {
6846 pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
6847 }
6848 else {
6849 pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex];
6850 }
6851
6852 pFnMac = &pAC->GIni.GIFunc;
6853
6854 switch (StatIndex) {
6855 case SK_PNMI_HTX:
6856 if (MacType == SK_MAC_GMAC) {
6857 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6858 StatAddr[SK_PNMI_HTX_BROADCAST][MacType].Reg,
6859 &LowVal);
6860 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6861 StatAddr[SK_PNMI_HTX_MULTICAST][MacType].Reg,
6862 &HighVal);
6863 LowVal += HighVal;
6864 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6865 StatAddr[SK_PNMI_HTX_UNICAST][MacType].Reg,
6866 &HighVal);
6867 LowVal += HighVal;
6868 }
6869 else {
6870 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6871 StatAddr[StatIndex][MacType].Reg,
6872 &LowVal);
6873 }
6874 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6875 break;
6876
6877 case SK_PNMI_HRX:
6878 if (MacType == SK_MAC_GMAC) {
6879 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6880 StatAddr[SK_PNMI_HRX_BROADCAST][MacType].Reg,
6881 &LowVal);
6882 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6883 StatAddr[SK_PNMI_HRX_MULTICAST][MacType].Reg,
6884 &HighVal);
6885 LowVal += HighVal;
6886 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6887 StatAddr[SK_PNMI_HRX_UNICAST][MacType].Reg,
6888 &HighVal);
6889 LowVal += HighVal;
6890 }
6891 else {
6892 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6893 StatAddr[StatIndex][MacType].Reg,
6894 &LowVal);
6895 }
6896 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6897 break;
6898
6899 case SK_PNMI_HTX_OCTET:
6900 case SK_PNMI_HRX_OCTET:
6901 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6902 StatAddr[StatIndex][MacType].Reg,
6903 &HighVal);
6904 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6905 StatAddr[StatIndex + 1][MacType].Reg,
6906 &LowVal);
6907 break;
6908
6909 case SK_PNMI_HTX_BURST:
6910 case SK_PNMI_HTX_EXCESS_DEF:
6911 case SK_PNMI_HTX_CARRIER:
6912 /* Not supported by GMAC */
6913 if (MacType == SK_MAC_GMAC) {
6914 return (Val);
6915 }
6916
6917 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6918 StatAddr[StatIndex][MacType].Reg,
6919 &LowVal);
6920 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6921 break;
6922
6923 case SK_PNMI_HTX_MACC:
6924 /* GMAC only supports PAUSE MAC control frames */
6925 if (MacType == SK_MAC_GMAC) {
6926 HelpIndex = SK_PNMI_HTX_PMACC;
6927 }
6928 else {
6929 HelpIndex = StatIndex;
6930 }
6931
6932 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6933 StatAddr[HelpIndex][MacType].Reg,
6934 &LowVal);
6935
6936 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6937 break;
6938
6939 case SK_PNMI_HTX_COL:
6940 case SK_PNMI_HRX_UNDERSIZE:
6941 /* Not supported by XMAC */
6942 if (MacType == SK_MAC_XMAC) {
6943 return (Val);
6944 }
6945
6946 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6947 StatAddr[StatIndex][MacType].Reg,
6948 &LowVal);
6949 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6950 break;
6951
6952 case SK_PNMI_HTX_DEFFERAL:
6953 /* Not supported by GMAC */
6954 if (MacType == SK_MAC_GMAC) {
6955 return (Val);
6956 }
6957
6958 /*
6959 * XMAC counts frames with deferred transmission
6960 * even in full-duplex mode.
6961 *
6962 * In full-duplex mode the counter remains constant!
6963 */
6964 if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) ||
6965 (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL)) {
6966
6967 LowVal = 0;
6968 HighVal = 0;
6969 }
6970 else {
6971 /* Otherwise get contents of hardware register */
6972 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6973 StatAddr[StatIndex][MacType].Reg,
6974 &LowVal);
6975 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6976 }
6977 break;
6978
6979 case SK_PNMI_HRX_BADOCTET:
6980 /* Not supported by XMAC */
6981 if (MacType == SK_MAC_XMAC) {
6982 return (Val);
6983 }
6984
6985 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6986 StatAddr[StatIndex][MacType].Reg,
6987 &HighVal);
6988 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6989 StatAddr[StatIndex + 1][MacType].Reg,
6990 &LowVal);
6991 break;
6992
6993 case SK_PNMI_HTX_OCTETLOW:
6994 case SK_PNMI_HRX_OCTETLOW:
6995 case SK_PNMI_HRX_BADOCTETLOW:
6996 return (Val);
6997
6998 case SK_PNMI_HRX_LONGFRAMES:
6999 /* For XMAC the SW counter is managed by PNMI */
7000 if (MacType == SK_MAC_XMAC) {
7001 return (pPnmiPrt->StatRxLongFrameCts);
7002 }
7003
7004 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7005 StatAddr[StatIndex][MacType].Reg,
7006 &LowVal);
7007 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7008 break;
7009
7010 case SK_PNMI_HRX_TOO_LONG:
7011 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7012 StatAddr[StatIndex][MacType].Reg,
7013 &LowVal);
7014 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7015
7016 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7017
7018 if (MacType == SK_MAC_GMAC) {
7019 /* For GMAC the SW counter is additionally managed by PNMI */
7020 Val += pPnmiPrt->StatRxFrameTooLongCts;
7021 }
7022 else {
7023 /*
7024 * Frames longer than IEEE 802.3 frame max size are counted
7025 * by XMAC in frame_too_long counter even reception of long
7026 * frames was enabled and the frame was correct.
7027 * So correct the value by subtracting RxLongFrame counter.
7028 */
7029 Val -= pPnmiPrt->StatRxLongFrameCts;
7030 }
7031
7032 LowVal = (SK_U32)Val;
7033 HighVal = (SK_U32)(Val >> 32);
7034 break;
7035
7036 case SK_PNMI_HRX_SHORTS:
7037 /* Not supported by GMAC */
7038 if (MacType == SK_MAC_GMAC) {
7039 /* GM_RXE_FRAG?? */
7040 return (Val);
7041 }
7042
7043 /*
7044 * XMAC counts short frame errors even if link down (#10620)
7045 *
7046 * If link-down the counter remains constant
7047 */
7048 if (pPrt->PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
7049
7050 /* Otherwise get incremental difference */
7051 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7052 StatAddr[StatIndex][MacType].Reg,
7053 &LowVal);
7054 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7055
7056 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7057 Val -= pPnmiPrt->RxShortZeroMark;
7058
7059 LowVal = (SK_U32)Val;
7060 HighVal = (SK_U32)(Val >> 32);
7061 }
7062 break;
7063
7064 case SK_PNMI_HRX_MACC:
7065 case SK_PNMI_HRX_MACC_UNKWN:
7066 case SK_PNMI_HRX_BURST:
7067 case SK_PNMI_HRX_MISSED:
7068 case SK_PNMI_HRX_FRAMING:
7069 case SK_PNMI_HRX_CARRIER:
7070 case SK_PNMI_HRX_IRLENGTH:
7071 case SK_PNMI_HRX_SYMBOL:
7072 case SK_PNMI_HRX_CEXT:
7073 /* Not supported by GMAC */
7074 if (MacType == SK_MAC_GMAC) {
7075 return (Val);
7076 }
7077
7078 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7079 StatAddr[StatIndex][MacType].Reg,
7080 &LowVal);
7081 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7082 break;
7083
7084 case SK_PNMI_HRX_PMACC_ERR:
7085 /* For GMAC the SW counter is managed by PNMI */
7086 if (MacType == SK_MAC_GMAC) {
7087 return (pPnmiPrt->StatRxPMaccErr);
7088 }
7089
7090 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7091 StatAddr[StatIndex][MacType].Reg,
7092 &LowVal);
7093 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7094 break;
7095
7096 /* SW counter managed by PNMI */
7097 case SK_PNMI_HTX_SYNC:
7098 LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
7099 HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
7100 break;
7101
7102 /* SW counter managed by PNMI */
7103 case SK_PNMI_HTX_SYNC_OCTET:
7104 LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
7105 HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
7106 break;
7107
7108 case SK_PNMI_HRX_FCS:
7109 /*
7110 * Broadcom filters FCS errors and counts it in
7111 * Receive Error Counter register
7112 */
7113 if (pPrt->PhyType == SK_PHY_BCOM) {
7114 /* do not read while not initialized (PHY_READ hangs!)*/
7115 if (pPrt->PState != SK_PRT_RESET) {
7116 SkXmPhyRead(pAC, IoC, PhysPortIndex, PHY_BCOM_RE_CTR, &Word);
7117
7118 LowVal = Word;
7119 }
7120 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7121 }
7122 else {
7123 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7124 StatAddr[StatIndex][MacType].Reg,
7125 &LowVal);
7126 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7127 }
7128 break;
7129
7130 default:
7131 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7132 StatAddr[StatIndex][MacType].Reg,
7133 &LowVal);
7134 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7135 break;
7136 }
7137
7138 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7139
7140 /* Correct value because of possible XMAC reset. XMAC Errata #2 */
7141 Val += pPnmiPrt->CounterOffset[StatIndex];
7142
7143 return (Val);
7144 }
7145
7146 /*****************************************************************************
7147 *
7148 * ResetCounter - Set all counters and timestamps to zero
7149 *
7150 * Description:
7151 * Notifies other common modules which store statistic data to
7152 * reset their counters and finally reset our own counters.
7153 *
7154 * Returns:
7155 * Nothing
7156 */
ResetCounter(SK_AC * pAC,SK_IOC IoC,SK_U32 NetIndex)7157 PNMI_STATIC void ResetCounter(
7158 SK_AC *pAC, /* Pointer to adapter context */
7159 SK_IOC IoC, /* IO context handle */
7160 SK_U32 NetIndex)
7161 {
7162 unsigned int PhysPortIndex;
7163 SK_EVPARA EventParam;
7164
7165
7166 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
7167
7168 /* Notify sensor module */
7169 SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
7170
7171 /* Notify RLMT module */
7172 EventParam.Para32[0] = NetIndex;
7173 EventParam.Para32[1] = (SK_U32)-1;
7174 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
7175 EventParam.Para32[1] = 0;
7176
7177 /* Notify SIRQ module */
7178 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
7179
7180 /* Notify CSUM module */
7181 #ifdef SK_USE_CSUM
7182 EventParam.Para32[0] = NetIndex;
7183 EventParam.Para32[1] = (SK_U32)-1;
7184 SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
7185 EventParam);
7186 #endif /* SK_USE_CSUM */
7187
7188 /* Clear XMAC statistic */
7189 for (PhysPortIndex = 0; PhysPortIndex <
7190 (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
7191
7192 (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex);
7193
7194 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
7195 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
7196 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7197 CounterOffset, 0, sizeof(pAC->Pnmi.Port[
7198 PhysPortIndex].CounterOffset));
7199 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
7200 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
7201 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7202 StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
7203 PhysPortIndex].StatSyncOctetsCts));
7204 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7205 StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
7206 PhysPortIndex].StatRxLongFrameCts));
7207 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7208 StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[
7209 PhysPortIndex].StatRxFrameTooLongCts));
7210 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7211 StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[
7212 PhysPortIndex].StatRxPMaccErr));
7213 }
7214
7215 /*
7216 * Clear local statistics
7217 */
7218 SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
7219 sizeof(pAC->Pnmi.VirtualCounterOffset));
7220 pAC->Pnmi.RlmtChangeCts = 0;
7221 pAC->Pnmi.RlmtChangeTime = 0;
7222 SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
7223 sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
7224 pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
7225 pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
7226 pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
7227 pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
7228 pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
7229 pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
7230 pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
7231 pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
7232 pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
7233 pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
7234 pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
7235 pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
7236 }
7237
7238 /*****************************************************************************
7239 *
7240 * GetTrapEntry - Get an entry in the trap buffer
7241 *
7242 * Description:
7243 * The trap buffer stores various events. A user application somehow
7244 * gets notified that an event occured and retrieves the trap buffer
7245 * contens (or simply polls the buffer). The buffer is organized as
7246 * a ring which stores the newest traps at the beginning. The oldest
7247 * traps are overwritten by the newest ones. Each trap entry has a
7248 * unique number, so that applications may detect new trap entries.
7249 *
7250 * Returns:
7251 * A pointer to the trap entry
7252 */
GetTrapEntry(SK_AC * pAC,SK_U32 TrapId,unsigned int Size)7253 PNMI_STATIC char* GetTrapEntry(
7254 SK_AC *pAC, /* Pointer to adapter context */
7255 SK_U32 TrapId, /* SNMP ID of the trap */
7256 unsigned int Size) /* Space needed for trap entry */
7257 {
7258 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7259 unsigned int BufFree = pAC->Pnmi.TrapBufFree;
7260 unsigned int Beg = pAC->Pnmi.TrapQueueBeg;
7261 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7262 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7263 int Wrap;
7264 unsigned int NeededSpace;
7265 unsigned int EntrySize;
7266 SK_U32 Val32;
7267 SK_U64 Val64;
7268
7269
7270 /* Last byte of entry will get a copy of the entry length */
7271 Size ++;
7272
7273 /*
7274 * Calculate needed buffer space */
7275 if (Beg >= Size) {
7276
7277 NeededSpace = Size;
7278 Wrap = SK_FALSE;
7279 }
7280 else {
7281 NeededSpace = Beg + Size;
7282 Wrap = SK_TRUE;
7283 }
7284
7285 /*
7286 * Check if enough buffer space is provided. Otherwise
7287 * free some entries. Leave one byte space between begin
7288 * and end of buffer to make it possible to detect whether
7289 * the buffer is full or empty
7290 */
7291 while (BufFree < NeededSpace + 1) {
7292
7293 if (End == 0) {
7294
7295 End = SK_PNMI_TRAP_QUEUE_LEN;
7296 }
7297
7298 EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
7299 BufFree += EntrySize;
7300 End -= EntrySize;
7301 #ifdef DEBUG
7302 SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
7303 #endif /* DEBUG */
7304 if (End == BufPad) {
7305 #ifdef DEBUG
7306 SK_MEMSET(pBuf, (char)(-1), End);
7307 #endif /* DEBUG */
7308 BufFree += End;
7309 End = 0;
7310 BufPad = 0;
7311 }
7312 }
7313
7314 /*
7315 * Insert new entry as first entry. Newest entries are
7316 * stored at the beginning of the queue.
7317 */
7318 if (Wrap) {
7319
7320 BufPad = Beg;
7321 Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
7322 }
7323 else {
7324 Beg = Beg - Size;
7325 }
7326 BufFree -= NeededSpace;
7327
7328 /* Save the current offsets */
7329 pAC->Pnmi.TrapQueueBeg = Beg;
7330 pAC->Pnmi.TrapQueueEnd = End;
7331 pAC->Pnmi.TrapBufPad = BufPad;
7332 pAC->Pnmi.TrapBufFree = BufFree;
7333
7334 /* Initialize the trap entry */
7335 *(pBuf + Beg + Size - 1) = (char)Size;
7336 *(pBuf + Beg) = (char)Size;
7337 Val32 = (pAC->Pnmi.TrapUnique) ++;
7338 SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
7339 SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
7340 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
7341 SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
7342
7343 return (pBuf + Beg);
7344 }
7345
7346 /*****************************************************************************
7347 *
7348 * CopyTrapQueue - Copies the trap buffer for the TRAP OID
7349 *
7350 * Description:
7351 * On a query of the TRAP OID the trap buffer contents will be
7352 * copied continuously to the request buffer, which must be large
7353 * enough. No length check is performed.
7354 *
7355 * Returns:
7356 * Nothing
7357 */
CopyTrapQueue(SK_AC * pAC,char * pDstBuf)7358 PNMI_STATIC void CopyTrapQueue(
7359 SK_AC *pAC, /* Pointer to adapter context */
7360 char *pDstBuf) /* Buffer to which the queued traps will be copied */
7361 {
7362 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7363 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7364 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7365 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7366 unsigned int Len;
7367 unsigned int DstOff = 0;
7368
7369
7370 while (Trap != End) {
7371
7372 Len = (unsigned int)*(pBuf + Trap);
7373
7374 /*
7375 * Last byte containing a copy of the length will
7376 * not be copied.
7377 */
7378 *(pDstBuf + DstOff) = (char)(Len - 1);
7379 SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
7380 DstOff += Len - 1;
7381
7382 Trap += Len;
7383 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7384
7385 Trap = BufPad;
7386 }
7387 }
7388 }
7389
7390 /*****************************************************************************
7391 *
7392 * GetTrapQueueLen - Get the length of the trap buffer
7393 *
7394 * Description:
7395 * Evaluates the number of currently stored traps and the needed
7396 * buffer size to retrieve them.
7397 *
7398 * Returns:
7399 * Nothing
7400 */
GetTrapQueueLen(SK_AC * pAC,unsigned int * pLen,unsigned int * pEntries)7401 PNMI_STATIC void GetTrapQueueLen(
7402 SK_AC *pAC, /* Pointer to adapter context */
7403 unsigned int *pLen, /* Length in Bytes of all queued traps */
7404 unsigned int *pEntries) /* Returns number of trapes stored in queue */
7405 {
7406 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7407 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7408 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7409 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7410 unsigned int Len;
7411 unsigned int Entries = 0;
7412 unsigned int TotalLen = 0;
7413
7414
7415 while (Trap != End) {
7416
7417 Len = (unsigned int)*(pBuf + Trap);
7418 TotalLen += Len - 1;
7419 Entries ++;
7420
7421 Trap += Len;
7422 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7423
7424 Trap = BufPad;
7425 }
7426 }
7427
7428 *pEntries = Entries;
7429 *pLen = TotalLen;
7430 }
7431
7432 /*****************************************************************************
7433 *
7434 * QueueSimpleTrap - Store a simple trap to the trap buffer
7435 *
7436 * Description:
7437 * A simple trap is a trap with now additional data. It consists
7438 * simply of a trap code.
7439 *
7440 * Returns:
7441 * Nothing
7442 */
QueueSimpleTrap(SK_AC * pAC,SK_U32 TrapId)7443 PNMI_STATIC void QueueSimpleTrap(
7444 SK_AC *pAC, /* Pointer to adapter context */
7445 SK_U32 TrapId) /* Type of sensor trap */
7446 {
7447 GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
7448 }
7449
7450 /*****************************************************************************
7451 *
7452 * QueueSensorTrap - Stores a sensor trap in the trap buffer
7453 *
7454 * Description:
7455 * Gets an entry in the trap buffer and fills it with sensor related
7456 * data.
7457 *
7458 * Returns:
7459 * Nothing
7460 */
QueueSensorTrap(SK_AC * pAC,SK_U32 TrapId,unsigned int SensorIndex)7461 PNMI_STATIC void QueueSensorTrap(
7462 SK_AC *pAC, /* Pointer to adapter context */
7463 SK_U32 TrapId, /* Type of sensor trap */
7464 unsigned int SensorIndex) /* Index of sensor which caused the trap */
7465 {
7466 char *pBuf;
7467 unsigned int Offset;
7468 unsigned int DescrLen;
7469 SK_U32 Val32;
7470
7471
7472 /* Get trap buffer entry */
7473 DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
7474 pBuf = GetTrapEntry(pAC, TrapId,
7475 SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
7476 Offset = SK_PNMI_TRAP_SIMPLE_LEN;
7477
7478 /* Store additionally sensor trap related data */
7479 Val32 = OID_SKGE_SENSOR_INDEX;
7480 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7481 *(pBuf + Offset + 4) = 4;
7482 Val32 = (SK_U32)SensorIndex;
7483 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7484 Offset += 9;
7485
7486 Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
7487 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7488 *(pBuf + Offset + 4) = (char)DescrLen;
7489 SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
7490 DescrLen);
7491 Offset += DescrLen + 5;
7492
7493 Val32 = OID_SKGE_SENSOR_TYPE;
7494 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7495 *(pBuf + Offset + 4) = 1;
7496 *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
7497 Offset += 6;
7498
7499 Val32 = OID_SKGE_SENSOR_VALUE;
7500 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7501 *(pBuf + Offset + 4) = 4;
7502 Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
7503 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7504 }
7505
7506 /*****************************************************************************
7507 *
7508 * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
7509 *
7510 * Description:
7511 * Nothing further to explain.
7512 *
7513 * Returns:
7514 * Nothing
7515 */
QueueRlmtNewMacTrap(SK_AC * pAC,unsigned int ActiveMac)7516 PNMI_STATIC void QueueRlmtNewMacTrap(
7517 SK_AC *pAC, /* Pointer to adapter context */
7518 unsigned int ActiveMac) /* Index (0..n) of the currently active port */
7519 {
7520 char *pBuf;
7521 SK_U32 Val32;
7522
7523
7524 pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
7525 SK_PNMI_TRAP_RLMT_CHANGE_LEN);
7526
7527 Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
7528 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7529 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7530 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
7531 }
7532
7533 /*****************************************************************************
7534 *
7535 * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
7536 *
7537 * Description:
7538 * Nothing further to explain.
7539 *
7540 * Returns:
7541 * Nothing
7542 */
QueueRlmtPortTrap(SK_AC * pAC,SK_U32 TrapId,unsigned int PortIndex)7543 PNMI_STATIC void QueueRlmtPortTrap(
7544 SK_AC *pAC, /* Pointer to adapter context */
7545 SK_U32 TrapId, /* Type of RLMT port trap */
7546 unsigned int PortIndex) /* Index of the port, which changed its state */
7547 {
7548 char *pBuf;
7549 SK_U32 Val32;
7550
7551
7552 pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
7553
7554 Val32 = OID_SKGE_RLMT_PORT_INDEX;
7555 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7556 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7557 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
7558 }
7559
7560 /*****************************************************************************
7561 *
7562 * CopyMac - Copies a MAC address
7563 *
7564 * Description:
7565 * Nothing further to explain.
7566 *
7567 * Returns:
7568 * Nothing
7569 */
CopyMac(char * pDst,SK_MAC_ADDR * pMac)7570 PNMI_STATIC void CopyMac(
7571 char *pDst, /* Pointer to destination buffer */
7572 SK_MAC_ADDR *pMac) /* Pointer of Source */
7573 {
7574 int i;
7575
7576
7577 for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
7578
7579 *(pDst + i) = pMac->a[i];
7580 }
7581 }
7582
7583 #ifdef SK_POWER_MGMT
7584 /*****************************************************************************
7585 *
7586 * PowerManagement - OID handler function of PowerManagement OIDs
7587 *
7588 * Description:
7589 * The code is simple. No description necessary.
7590 *
7591 * Returns:
7592 * SK_PNMI_ERR_OK The request was successfully performed.
7593 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7594 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7595 * the correct data (e.g. a 32bit value is
7596 * needed, but a 16 bit value was passed).
7597 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7598 * exist (e.g. port instance 3 on a two port
7599 * adapter.
7600 */
7601
PowerManagement(SK_AC * pAC,SK_IOC IoC,int Action,SK_U32 Id,char * pBuf,unsigned int * pLen,SK_U32 Instance,unsigned int TableIndex,SK_U32 NetIndex)7602 PNMI_STATIC int PowerManagement(
7603 SK_AC *pAC, /* Pointer to adapter context */
7604 SK_IOC IoC, /* IO context handle */
7605 int Action, /* Get/PreSet/Set action */
7606 SK_U32 Id, /* Object ID that is to be processed */
7607 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
7608 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
7609 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7610 unsigned int TableIndex, /* Index to the Id table */
7611 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
7612 {
7613
7614 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7615
7616 /*
7617 * Check instance. We only handle single instance variables
7618 */
7619 if (Instance != (SK_U32)(-1) && Instance != 1) {
7620
7621 *pLen = 0;
7622 return (SK_PNMI_ERR_UNKNOWN_INST);
7623 }
7624
7625
7626 /* Check length */
7627 switch (Id) {
7628
7629 case OID_PNP_CAPABILITIES:
7630 if (*pLen < sizeof(SK_PNP_CAPABILITIES)) {
7631
7632 *pLen = sizeof(SK_PNP_CAPABILITIES);
7633 return (SK_PNMI_ERR_TOO_SHORT);
7634 }
7635 break;
7636
7637 case OID_PNP_SET_POWER:
7638 case OID_PNP_QUERY_POWER:
7639 if (*pLen < sizeof(SK_DEVICE_POWER_STATE))
7640 {
7641 *pLen = sizeof(SK_DEVICE_POWER_STATE);
7642 return (SK_PNMI_ERR_TOO_SHORT);
7643 }
7644 break;
7645
7646 case OID_PNP_ADD_WAKE_UP_PATTERN:
7647 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7648 if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) {
7649
7650 *pLen = sizeof(SK_PM_PACKET_PATTERN);
7651 return (SK_PNMI_ERR_TOO_SHORT);
7652 }
7653 break;
7654
7655 case OID_PNP_ENABLE_WAKE_UP:
7656 if (*pLen < sizeof(SK_U32)) {
7657
7658 *pLen = sizeof(SK_U32);
7659 return (SK_PNMI_ERR_TOO_SHORT);
7660 }
7661 break;
7662 }
7663
7664 /*
7665 * Perform action
7666 */
7667 if (Action == SK_PNMI_GET) {
7668
7669 /*
7670 * Get value
7671 */
7672 switch (Id) {
7673
7674 case OID_PNP_CAPABILITIES:
7675 RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen);
7676 break;
7677
7678 case OID_PNP_QUERY_POWER:
7679 /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
7680 the miniport to indicate whether it can transition its NIC
7681 to the low-power state.
7682 A miniport driver must always return NDIS_STATUS_SUCCESS
7683 to a query of OID_PNP_QUERY_POWER. */
7684 *pLen = sizeof(SK_DEVICE_POWER_STATE);;
7685 RetCode = SK_PNMI_ERR_OK;
7686 break;
7687
7688 /* NDIS handles these OIDs as write-only.
7689 * So in case of get action the buffer with written length = 0
7690 * is returned
7691 */
7692 case OID_PNP_SET_POWER:
7693 case OID_PNP_ADD_WAKE_UP_PATTERN:
7694 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7695 *pLen = 0;
7696 RetCode = SK_PNMI_ERR_NOT_SUPPORTED;
7697 break;
7698
7699 case OID_PNP_ENABLE_WAKE_UP:
7700 RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen);
7701 break;
7702
7703 default:
7704 RetCode = SK_PNMI_ERR_GENERAL;
7705 break;
7706 }
7707
7708 return (RetCode);
7709 }
7710
7711
7712 /*
7713 * Perform preset or set
7714 */
7715
7716 /* POWER module does not support PRESET action */
7717 if (Action == SK_PNMI_PRESET) {
7718 return (SK_PNMI_ERR_OK);
7719 }
7720
7721 switch (Id) {
7722 case OID_PNP_SET_POWER:
7723 RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen);
7724 break;
7725
7726 case OID_PNP_ADD_WAKE_UP_PATTERN:
7727 RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen);
7728 break;
7729
7730 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7731 RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen);
7732 break;
7733
7734 case OID_PNP_ENABLE_WAKE_UP:
7735 RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen);
7736 break;
7737
7738 default:
7739 RetCode = SK_PNMI_ERR_READ_ONLY;
7740 }
7741
7742 return (RetCode);
7743 }
7744 #endif /* SK_POWER_MGMT */
7745
7746 #ifdef SK_DIAG_SUPPORT
7747 /*****************************************************************************
7748 *
7749 * DiagActions - OID handler function of Diagnostic driver
7750 *
7751 * Description:
7752 * The code is simple. No description necessary.
7753 *
7754 * Returns:
7755 * SK_PNMI_ERR_OK The request was successfully performed.
7756 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7757 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7758 * the correct data (e.g. a 32bit value is
7759 * needed, but a 16 bit value was passed).
7760 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7761 * exist (e.g. port instance 3 on a two port
7762 * adapter.
7763 */
7764
DiagActions(SK_AC * pAC,SK_IOC IoC,int Action,SK_U32 Id,char * pBuf,unsigned int * pLen,SK_U32 Instance,unsigned int TableIndex,SK_U32 NetIndex)7765 PNMI_STATIC int DiagActions(
7766 SK_AC *pAC, /* Pointer to adapter context */
7767 SK_IOC IoC, /* IO context handle */
7768 int Action, /* GET/PRESET/SET action */
7769 SK_U32 Id, /* Object ID that is to be processed */
7770 char *pBuf, /* Buffer used for the management data transfer */
7771 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
7772 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7773 unsigned int TableIndex, /* Index to the Id table */
7774 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
7775 {
7776
7777 SK_U32 DiagStatus;
7778 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7779
7780 /*
7781 * Check instance. We only handle single instance variables.
7782 */
7783 if (Instance != (SK_U32)(-1) && Instance != 1) {
7784
7785 *pLen = 0;
7786 return (SK_PNMI_ERR_UNKNOWN_INST);
7787 }
7788
7789 /*
7790 * Check length.
7791 */
7792 switch (Id) {
7793
7794 case OID_SKGE_DIAG_MODE:
7795 if (*pLen < sizeof(SK_U32)) {
7796
7797 *pLen = sizeof(SK_U32);
7798 return (SK_PNMI_ERR_TOO_SHORT);
7799 }
7800 break;
7801
7802 default:
7803 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040, SK_PNMI_ERR040MSG);
7804 *pLen = 0;
7805 return (SK_PNMI_ERR_GENERAL);
7806 }
7807
7808 /* Perform action. */
7809
7810 /* GET value. */
7811 if (Action == SK_PNMI_GET) {
7812
7813 switch (Id) {
7814
7815 case OID_SKGE_DIAG_MODE:
7816 DiagStatus = pAC->Pnmi.DiagAttached;
7817 SK_PNMI_STORE_U32(pBuf, DiagStatus);
7818 *pLen = sizeof(SK_U32);
7819 RetCode = SK_PNMI_ERR_OK;
7820 break;
7821
7822 default:
7823 *pLen = 0;
7824 RetCode = SK_PNMI_ERR_GENERAL;
7825 break;
7826 }
7827 return (RetCode);
7828 }
7829
7830 /* From here SET or PRESET value. */
7831
7832 /* PRESET value is not supported. */
7833 if (Action == SK_PNMI_PRESET) {
7834 return (SK_PNMI_ERR_OK);
7835 }
7836
7837 /* SET value. */
7838 switch (Id) {
7839 case OID_SKGE_DIAG_MODE:
7840
7841 /* Handle the SET. */
7842 switch (*pBuf) {
7843
7844 /* Attach the DIAG to this adapter. */
7845 case SK_DIAG_ATTACHED:
7846 /* Check if we come from running */
7847 if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
7848
7849 RetCode = SkDrvLeaveDiagMode(pAC);
7850
7851 }
7852 else if (pAC->Pnmi.DiagAttached == SK_DIAG_IDLE) {
7853
7854 RetCode = SK_PNMI_ERR_OK;
7855 }
7856
7857 else {
7858
7859 RetCode = SK_PNMI_ERR_GENERAL;
7860
7861 }
7862
7863 if (RetCode == SK_PNMI_ERR_OK) {
7864
7865 pAC->Pnmi.DiagAttached = SK_DIAG_ATTACHED;
7866 }
7867 break;
7868
7869 /* Enter the DIAG mode in the driver. */
7870 case SK_DIAG_RUNNING:
7871 RetCode = SK_PNMI_ERR_OK;
7872
7873 /*
7874 * If DiagAttached is set, we can tell the driver
7875 * to enter the DIAG mode.
7876 */
7877 if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
7878 /* If DiagMode is not active, we can enter it. */
7879 if (!pAC->DiagModeActive) {
7880
7881 RetCode = SkDrvEnterDiagMode(pAC);
7882 }
7883 else {
7884
7885 RetCode = SK_PNMI_ERR_GENERAL;
7886 }
7887 }
7888 else {
7889
7890 RetCode = SK_PNMI_ERR_GENERAL;
7891 }
7892
7893 if (RetCode == SK_PNMI_ERR_OK) {
7894
7895 pAC->Pnmi.DiagAttached = SK_DIAG_RUNNING;
7896 }
7897 break;
7898
7899 case SK_DIAG_IDLE:
7900 /* Check if we come from running */
7901 if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
7902
7903 RetCode = SkDrvLeaveDiagMode(pAC);
7904
7905 }
7906 else if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
7907
7908 RetCode = SK_PNMI_ERR_OK;
7909 }
7910
7911 else {
7912
7913 RetCode = SK_PNMI_ERR_GENERAL;
7914
7915 }
7916
7917 if (RetCode == SK_PNMI_ERR_OK) {
7918
7919 pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
7920 }
7921 break;
7922
7923 default:
7924 RetCode = SK_PNMI_ERR_BAD_VALUE;
7925 break;
7926 }
7927 break;
7928
7929 default:
7930 RetCode = SK_PNMI_ERR_GENERAL;
7931 }
7932
7933 if (RetCode == SK_PNMI_ERR_OK) {
7934 *pLen = sizeof(SK_U32);
7935 }
7936 else {
7937
7938 *pLen = 0;
7939 }
7940 return (RetCode);
7941 }
7942 #endif /* SK_DIAG_SUPPORT */
7943
7944 /*****************************************************************************
7945 *
7946 * Vct - OID handler function of OIDs
7947 *
7948 * Description:
7949 * The code is simple. No description necessary.
7950 *
7951 * Returns:
7952 * SK_PNMI_ERR_OK The request was performed successfully.
7953 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7954 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7955 * the correct data (e.g. a 32bit value is
7956 * needed, but a 16 bit value was passed).
7957 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7958 * exist (e.g. port instance 3 on a two port
7959 * adapter).
7960 * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed.
7961 *
7962 */
7963
Vct(SK_AC * pAC,SK_IOC IoC,int Action,SK_U32 Id,char * pBuf,unsigned int * pLen,SK_U32 Instance,unsigned int TableIndex,SK_U32 NetIndex)7964 PNMI_STATIC int Vct(
7965 SK_AC *pAC, /* Pointer to adapter context */
7966 SK_IOC IoC, /* IO context handle */
7967 int Action, /* GET/PRESET/SET action */
7968 SK_U32 Id, /* Object ID that is to be processed */
7969 char *pBuf, /* Buffer used for the management data transfer */
7970 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
7971 SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */
7972 unsigned int TableIndex, /* Index to the Id table */
7973 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
7974 {
7975 SK_GEPORT *pPrt;
7976 SK_PNMI_VCT *pVctBackupData;
7977 SK_U32 LogPortMax;
7978 SK_U32 PhysPortMax;
7979 SK_U32 PhysPortIndex;
7980 SK_U32 Limit;
7981 SK_U32 Offset;
7982 SK_BOOL Link;
7983 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7984 int i;
7985 SK_EVPARA Para;
7986 SK_U32 CableLength;
7987
7988 /*
7989 * Calculate the port indexes from the instance.
7990 */
7991 PhysPortMax = pAC->GIni.GIMacsFound;
7992 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
7993
7994 /* Dual net mode? */
7995 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
7996 LogPortMax--;
7997 }
7998
7999 if ((Instance != (SK_U32) (-1))) {
8000 /* Check instance range. */
8001 if ((Instance < 2) || (Instance > LogPortMax)) {
8002 *pLen = 0;
8003 return (SK_PNMI_ERR_UNKNOWN_INST);
8004 }
8005
8006 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
8007 PhysPortIndex = NetIndex;
8008 }
8009 else {
8010 PhysPortIndex = Instance - 2;
8011 }
8012 Limit = PhysPortIndex + 1;
8013 }
8014 else {
8015 /*
8016 * Instance == (SK_U32) (-1), get all Instances of that OID.
8017 *
8018 * Not implemented yet. May be used in future releases.
8019 */
8020 PhysPortIndex = 0;
8021 Limit = PhysPortMax;
8022 }
8023
8024 pPrt = &pAC->GIni.GP[PhysPortIndex];
8025 if (pPrt->PHWLinkUp) {
8026 Link = SK_TRUE;
8027 }
8028 else {
8029 Link = SK_FALSE;
8030 }
8031
8032 /* Check MAC type */
8033 if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
8034 *pLen = 0;
8035 return (SK_PNMI_ERR_GENERAL);
8036 }
8037
8038 /* Initialize backup data pointer. */
8039 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
8040
8041 /* Check action type */
8042 if (Action == SK_PNMI_GET) {
8043 /* Check length */
8044 switch (Id) {
8045
8046 case OID_SKGE_VCT_GET:
8047 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
8048 *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
8049 return (SK_PNMI_ERR_TOO_SHORT);
8050 }
8051 break;
8052
8053 case OID_SKGE_VCT_STATUS:
8054 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
8055 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
8056 return (SK_PNMI_ERR_TOO_SHORT);
8057 }
8058 break;
8059
8060 default:
8061 *pLen = 0;
8062 return (SK_PNMI_ERR_GENERAL);
8063 }
8064
8065 /* Get value */
8066 Offset = 0;
8067 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8068 switch (Id) {
8069
8070 case OID_SKGE_VCT_GET:
8071 if ((Link == SK_FALSE) &&
8072 (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
8073 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
8074 if (RetCode == 0) {
8075 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
8076 pAC->Pnmi.VctStatus[PhysPortIndex] |=
8077 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
8078
8079 /* Copy results for later use to PNMI struct. */
8080 for (i = 0; i < 4; i++) {
8081 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
8082 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
8083 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
8084 }
8085 }
8086 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
8087 CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
8088 }
8089 else {
8090 CableLength = 0;
8091 }
8092 pVctBackupData->PMdiPairLen[i] = CableLength;
8093 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
8094 }
8095
8096 Para.Para32[0] = PhysPortIndex;
8097 Para.Para32[1] = -1;
8098 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
8099 SkEventDispatcher(pAC, IoC);
8100 }
8101 else {
8102 ; /* VCT test is running. */
8103 }
8104 }
8105
8106 /* Get all results. */
8107 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
8108 Offset += sizeof(SK_U8);
8109 *(pBuf + Offset) = pPrt->PCableLen;
8110 Offset += sizeof(SK_U8);
8111 for (i = 0; i < 4; i++) {
8112 SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
8113 Offset += sizeof(SK_U32);
8114 }
8115 for (i = 0; i < 4; i++) {
8116 *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
8117 Offset += sizeof(SK_U8);
8118 }
8119
8120 RetCode = SK_PNMI_ERR_OK;
8121 break;
8122
8123 case OID_SKGE_VCT_STATUS:
8124 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
8125 Offset += sizeof(SK_U8);
8126 RetCode = SK_PNMI_ERR_OK;
8127 break;
8128
8129 default:
8130 *pLen = 0;
8131 return (SK_PNMI_ERR_GENERAL);
8132 }
8133 } /* for */
8134 *pLen = Offset;
8135 return (RetCode);
8136
8137 } /* if SK_PNMI_GET */
8138
8139 /*
8140 * From here SET or PRESET action. Check if the passed
8141 * buffer length is plausible.
8142 */
8143
8144 /* Check length */
8145 switch (Id) {
8146 case OID_SKGE_VCT_SET:
8147 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
8148 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
8149 return (SK_PNMI_ERR_TOO_SHORT);
8150 }
8151 break;
8152
8153 default:
8154 *pLen = 0;
8155 return (SK_PNMI_ERR_GENERAL);
8156 }
8157
8158 /*
8159 * Perform preset or set.
8160 */
8161
8162 /* VCT does not support PRESET action. */
8163 if (Action == SK_PNMI_PRESET) {
8164 return (SK_PNMI_ERR_OK);
8165 }
8166
8167 Offset = 0;
8168 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8169 switch (Id) {
8170 case OID_SKGE_VCT_SET: /* Start VCT test. */
8171 if (Link == SK_FALSE) {
8172 SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
8173
8174 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
8175 if (RetCode == 0) { /* RetCode: 0 => Start! */
8176 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
8177 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8178 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
8179
8180 /*
8181 * Start VCT timer counter.
8182 */
8183 SK_MEMSET((char *) &Para, 0, sizeof(Para));
8184 Para.Para32[0] = PhysPortIndex;
8185 Para.Para32[1] = -1;
8186 SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
8187 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
8188 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8189 RetCode = SK_PNMI_ERR_OK;
8190 }
8191 else { /* RetCode: 2 => Running! */
8192 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8193 RetCode = SK_PNMI_ERR_OK;
8194 }
8195 }
8196 else { /* RetCode: 4 => Link! */
8197 RetCode = 4;
8198 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8199 RetCode = SK_PNMI_ERR_OK;
8200 }
8201 Offset += sizeof(SK_U32);
8202 break;
8203
8204 default:
8205 *pLen = 0;
8206 return (SK_PNMI_ERR_GENERAL);
8207 }
8208 } /* for */
8209 *pLen = Offset;
8210 return (RetCode);
8211
8212 } /* Vct */
8213
8214
CheckVctStatus(SK_AC * pAC,SK_IOC IoC,char * pBuf,SK_U32 Offset,SK_U32 PhysPortIndex)8215 PNMI_STATIC void CheckVctStatus(
8216 SK_AC *pAC,
8217 SK_IOC IoC,
8218 char *pBuf,
8219 SK_U32 Offset,
8220 SK_U32 PhysPortIndex)
8221 {
8222 SK_GEPORT *pPrt;
8223 SK_PNMI_VCT *pVctData;
8224 SK_U32 RetCode;
8225
8226 pPrt = &pAC->GIni.GP[PhysPortIndex];
8227
8228 pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
8229 pVctData->VctStatus = SK_PNMI_VCT_NONE;
8230
8231 if (!pPrt->PHWLinkUp) {
8232
8233 /* Was a VCT test ever made before? */
8234 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8235 if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
8236 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8237 }
8238 else {
8239 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8240 }
8241 }
8242
8243 /* Check VCT test status. */
8244 RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
8245 if (RetCode == 2) { /* VCT test is running. */
8246 pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
8247 }
8248 else { /* VCT data was copied to pAC here. Check PENDING state. */
8249 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
8250 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8251 }
8252 }
8253
8254 if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
8255 pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
8256 }
8257 }
8258 else {
8259
8260 /* Was a VCT test ever made before? */
8261 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8262 pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8263 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8264 }
8265
8266 /* DSP only valid in 100/1000 modes. */
8267 if (pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed !=
8268 SK_LSPEED_STAT_10MBPS) {
8269 pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
8270 }
8271 }
8272 } /* CheckVctStatus */
8273
8274
8275 /*****************************************************************************
8276 *
8277 * SkPnmiGenIoctl - Handles new generic PNMI IOCTL, calls the needed
8278 * PNMI function depending on the subcommand and
8279 * returns all data belonging to the complete database
8280 * or OID request.
8281 *
8282 * Description:
8283 * Looks up the requested subcommand, calls the corresponding handler
8284 * function and passes all required parameters to it.
8285 * The function is called by the driver. It is needed to handle the new
8286 * generic PNMI IOCTL. This IOCTL is given to the driver and contains both
8287 * the OID and a subcommand to decide what kind of request has to be done.
8288 *
8289 * Returns:
8290 * SK_PNMI_ERR_OK The request was successfully performed
8291 * SK_PNMI_ERR_GENERAL A general severe internal error occured
8292 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
8293 * the data.
8294 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
8295 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
8296 * exist (e.g. port instance 3 on a two port
8297 * adapter.
8298 */
SkPnmiGenIoctl(SK_AC * pAC,SK_IOC IoC,void * pBuf,unsigned int * pLen,SK_U32 NetIndex)8299 int SkPnmiGenIoctl(
8300 SK_AC *pAC, /* Pointer to adapter context struct */
8301 SK_IOC IoC, /* I/O context */
8302 void *pBuf, /* Buffer used for the management data transfer */
8303 unsigned int *pLen, /* Length of buffer */
8304 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
8305 {
8306 SK_I32 Mode; /* Store value of subcommand. */
8307 SK_U32 Oid; /* Store value of OID. */
8308 int ReturnCode; /* Store return value to show status of PNMI action. */
8309 int HeaderLength; /* Length of desired action plus OID. */
8310
8311 ReturnCode = SK_PNMI_ERR_GENERAL;
8312
8313 SK_MEMCPY(&Mode, pBuf, sizeof(SK_I32));
8314 SK_MEMCPY(&Oid, (char *) pBuf + sizeof(SK_I32), sizeof(SK_U32));
8315 HeaderLength = sizeof(SK_I32) + sizeof(SK_U32);
8316 *pLen = *pLen - HeaderLength;
8317 SK_MEMCPY((char *) pBuf + sizeof(SK_I32), (char *) pBuf + HeaderLength, *pLen);
8318
8319 switch(Mode) {
8320 case SK_GET_SINGLE_VAR:
8321 ReturnCode = SkPnmiGetVar(pAC, IoC, Oid,
8322 (char *) pBuf + sizeof(SK_I32), pLen,
8323 ((SK_U32) (-1)), NetIndex);
8324 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8325 *pLen = *pLen + sizeof(SK_I32);
8326 break;
8327 case SK_PRESET_SINGLE_VAR:
8328 ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid,
8329 (char *) pBuf + sizeof(SK_I32), pLen,
8330 ((SK_U32) (-1)), NetIndex);
8331 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8332 *pLen = *pLen + sizeof(SK_I32);
8333 break;
8334 case SK_SET_SINGLE_VAR:
8335 ReturnCode = SkPnmiSetVar(pAC, IoC, Oid,
8336 (char *) pBuf + sizeof(SK_I32), pLen,
8337 ((SK_U32) (-1)), NetIndex);
8338 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8339 *pLen = *pLen + sizeof(SK_I32);
8340 break;
8341 case SK_GET_FULL_MIB:
8342 ReturnCode = SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8343 break;
8344 case SK_PRESET_FULL_MIB:
8345 ReturnCode = SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8346 break;
8347 case SK_SET_FULL_MIB:
8348 ReturnCode = SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8349 break;
8350 default:
8351 break;
8352 }
8353
8354 return (ReturnCode);
8355
8356 } /* SkGeIocGen */
8357