aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sk98lin
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/net/sk98lin
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/net/sk98lin')
-rw-r--r--drivers/net/sk98lin/Makefile89
-rw-r--r--drivers/net/sk98lin/h/lm80.h179
-rw-r--r--drivers/net/sk98lin/h/skaddr.h333
-rw-r--r--drivers/net/sk98lin/h/skcsum.h219
-rw-r--r--drivers/net/sk98lin/h/skdebug.h74
-rw-r--r--drivers/net/sk98lin/h/skdrv1st.h191
-rw-r--r--drivers/net/sk98lin/h/skdrv2nd.h456
-rw-r--r--drivers/net/sk98lin/h/skerror.h55
-rw-r--r--drivers/net/sk98lin/h/skgedrv.h51
-rw-r--r--drivers/net/sk98lin/h/skgehw.h2126
-rw-r--r--drivers/net/sk98lin/h/skgehwt.h48
-rw-r--r--drivers/net/sk98lin/h/skgei2c.h210
-rw-r--r--drivers/net/sk98lin/h/skgeinit.h853
-rw-r--r--drivers/net/sk98lin/h/skgepnm2.h334
-rw-r--r--drivers/net/sk98lin/h/skgepnmi.h966
-rw-r--r--drivers/net/sk98lin/h/skgesirq.h111
-rw-r--r--drivers/net/sk98lin/h/ski2c.h177
-rw-r--r--drivers/net/sk98lin/h/skqueue.h94
-rw-r--r--drivers/net/sk98lin/h/skrlmt.h438
-rw-r--r--drivers/net/sk98lin/h/sktimer.h63
-rw-r--r--drivers/net/sk98lin/h/sktypes.h69
-rw-r--r--drivers/net/sk98lin/h/skversion.h38
-rw-r--r--drivers/net/sk98lin/h/skvpd.h271
-rw-r--r--drivers/net/sk98lin/h/xmac_ii.h1579
-rw-r--r--drivers/net/sk98lin/skaddr.c1773
-rw-r--r--drivers/net/sk98lin/skcsum.c871
-rw-r--r--drivers/net/sk98lin/skdim.c742
-rw-r--r--drivers/net/sk98lin/skethtool.c552
-rw-r--r--drivers/net/sk98lin/skge.c5186
-rw-r--r--drivers/net/sk98lin/skgehwt.c171
-rw-r--r--drivers/net/sk98lin/skgeinit.c2151
-rw-r--r--drivers/net/sk98lin/skgemib.c1082
-rw-r--r--drivers/net/sk98lin/skgepnmi.c8359
-rw-r--r--drivers/net/sk98lin/skgesirq.c2251
-rw-r--r--drivers/net/sk98lin/ski2c.c1296
-rw-r--r--drivers/net/sk98lin/sklm80.c213
-rw-r--r--drivers/net/sk98lin/skproc.c265
-rw-r--r--drivers/net/sk98lin/skqueue.c179
-rw-r--r--drivers/net/sk98lin/skrlmt.c3258
-rw-r--r--drivers/net/sk98lin/sktimer.c250
-rw-r--r--drivers/net/sk98lin/skvpd.c1197
-rw-r--r--drivers/net/sk98lin/skxmac2.c4607
42 files changed, 43427 insertions, 0 deletions
diff --git a/drivers/net/sk98lin/Makefile b/drivers/net/sk98lin/Makefile
new file mode 100644
index 000000000000..6783039ffb75
--- /dev/null
+++ b/drivers/net/sk98lin/Makefile
@@ -0,0 +1,89 @@
1#
2# Makefile for the SysKonnect SK-98xx device driver.
3#
4
5
6#
7# Standalone driver params
8# SKPARAM += -DSK_KERNEL_24
9# SKPARAM += -DSK_KERNEL_24_26
10# SKPARAM += -DSK_KERNEL_26
11# SKPARAM += -DSK_KERNEL_22_24
12
13obj-$(CONFIG_SK98LIN) += sk98lin.o
14sk98lin-objs := \
15 skge.o \
16 skethtool.o \
17 skdim.o \
18 skaddr.o \
19 skgehwt.o \
20 skgeinit.o \
21 skgepnmi.o \
22 skgesirq.o \
23 ski2c.o \
24 sklm80.o \
25 skqueue.o \
26 skrlmt.o \
27 sktimer.o \
28 skvpd.o \
29 skxmac2.o \
30 skproc.o \
31 skcsum.o
32
33# DBGDEF = \
34# -DDEBUG
35
36ifdef DEBUG
37DBGDEF += \
38-DSK_DEBUG_CHKMOD=0x00000000L \
39-DSK_DEBUG_CHKCAT=0x00000000L
40endif
41
42
43# **** possible debug modules for SK_DEBUG_CHKMOD *****************
44# SK_DBGMOD_MERR 0x00000001L /* general module error indication */
45# SK_DBGMOD_HWM 0x00000002L /* Hardware init module */
46# SK_DBGMOD_RLMT 0x00000004L /* RLMT module */
47# SK_DBGMOD_VPD 0x00000008L /* VPD module */
48# SK_DBGMOD_I2C 0x00000010L /* I2C module */
49# SK_DBGMOD_PNMI 0x00000020L /* PNMI module */
50# SK_DBGMOD_CSUM 0x00000040L /* CSUM module */
51# SK_DBGMOD_ADDR 0x00000080L /* ADDR module */
52# SK_DBGMOD_DRV 0x00010000L /* DRV module */
53
54# **** possible debug categories for SK_DEBUG_CHKCAT **************
55# *** common modules ***
56# SK_DBGCAT_INIT 0x00000001L module/driver initialization
57# SK_DBGCAT_CTRL 0x00000002L controlling: add/rmv MCA/MAC and other controls (IOCTL)
58# SK_DBGCAT_ERR 0x00000004L error handling paths
59# SK_DBGCAT_TX 0x00000008L transmit path
60# SK_DBGCAT_RX 0x00000010L receive path
61# SK_DBGCAT_IRQ 0x00000020L general IRQ handling
62# SK_DBGCAT_QUEUE 0x00000040L any queue management
63# SK_DBGCAT_DUMP 0x00000080L large data output e.g. hex dump
64# SK_DBGCAT_FATAL 0x00000100L large data output e.g. hex dump
65
66# *** driver (file skge.c) ***
67# SK_DBGCAT_DRV_ENTRY 0x00010000 entry points
68# SK_DBGCAT_DRV_??? 0x00020000 not used
69# SK_DBGCAT_DRV_MCA 0x00040000 multicast
70# SK_DBGCAT_DRV_TX_PROGRESS 0x00080000 tx path
71# SK_DBGCAT_DRV_RX_PROGRESS 0x00100000 rx path
72# SK_DBGCAT_DRV_PROGRESS 0x00200000 general runtime
73# SK_DBGCAT_DRV_??? 0x00400000 not used
74# SK_DBGCAT_DRV_PROM 0x00800000 promiscuous mode
75# SK_DBGCAT_DRV_TX_FRAME 0x01000000 display tx frames
76# SK_DBGCAT_DRV_ERROR 0x02000000 error conditions
77# SK_DBGCAT_DRV_INT_SRC 0x04000000 interrupts sources
78# SK_DBGCAT_DRV_EVENT 0x08000000 driver events
79
80EXTRA_CFLAGS += -Idrivers/net/sk98lin -DSK_DIAG_SUPPORT -DSK_USE_CSUM -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM)
81
82clean:
83 rm -f core *.o *.a *.s
84
85
86
87
88
89
diff --git a/drivers/net/sk98lin/h/lm80.h b/drivers/net/sk98lin/h/lm80.h
new file mode 100644
index 000000000000..4e2dbbf78000
--- /dev/null
+++ b/drivers/net/sk98lin/h/lm80.h
@@ -0,0 +1,179 @@
1/******************************************************************************
2 *
3 * Name: lm80.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.6 $
6 * Date: $Date: 2003/05/13 17:26:52 $
7 * Purpose: Contains all defines for the LM80 Chip
8 * (National Semiconductor).
9 *
10 ******************************************************************************/
11
12/******************************************************************************
13 *
14 * (C)Copyright 1998-2002 SysKonnect.
15 * (C)Copyright 2002-2003 Marvell.
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * The information in this file is provided "AS IS" without warranty.
23 *
24 ******************************************************************************/
25
26#ifndef __INC_LM80_H
27#define __INC_LM80_H
28
29#ifdef __cplusplus
30extern "C" {
31#endif /* __cplusplus */
32
33/* defines ********************************************************************/
34
35/*
36 * LM80 register definition
37 *
38 * All registers are 8 bit wide
39 */
40#define LM80_CFG 0x00 /* Configuration Register */
41#define LM80_ISRC_1 0x01 /* Interrupt Status Register 1 */
42#define LM80_ISRC_2 0x02 /* Interrupt Status Register 2 */
43#define LM80_IMSK_1 0x03 /* Interrupt Mask Register 1 */
44#define LM80_IMSK_2 0x04 /* Interrupt Mask Register 2 */
45#define LM80_FAN_CTRL 0x05 /* Fan Devisor/RST#/OS# Register */
46#define LM80_TEMP_CTRL 0x06 /* OS# Config, Temp Res. Reg */
47 /* 0x07 - 0x1f reserved */
48 /* current values */
49#define LM80_VT0_IN 0x20 /* current Voltage 0 value */
50#define LM80_VT1_IN 0x21 /* current Voltage 1 value */
51#define LM80_VT2_IN 0x22 /* current Voltage 2 value */
52#define LM80_VT3_IN 0x23 /* current Voltage 3 value */
53#define LM80_VT4_IN 0x24 /* current Voltage 4 value */
54#define LM80_VT5_IN 0x25 /* current Voltage 5 value */
55#define LM80_VT6_IN 0x26 /* current Voltage 6 value */
56#define LM80_TEMP_IN 0x27 /* current Temperature value */
57#define LM80_FAN1_IN 0x28 /* current Fan 1 count */
58#define LM80_FAN2_IN 0x29 /* current Fan 2 count */
59 /* limit values */
60#define LM80_VT0_HIGH_LIM 0x2a /* high limit val for Voltage 0 */
61#define LM80_VT0_LOW_LIM 0x2b /* low limit val for Voltage 0 */
62#define LM80_VT1_HIGH_LIM 0x2c /* high limit val for Voltage 1 */
63#define LM80_VT1_LOW_LIM 0x2d /* low limit val for Voltage 1 */
64#define LM80_VT2_HIGH_LIM 0x2e /* high limit val for Voltage 2 */
65#define LM80_VT2_LOW_LIM 0x2f /* low limit val for Voltage 2 */
66#define LM80_VT3_HIGH_LIM 0x30 /* high limit val for Voltage 3 */
67#define LM80_VT3_LOW_LIM 0x31 /* low limit val for Voltage 3 */
68#define LM80_VT4_HIGH_LIM 0x32 /* high limit val for Voltage 4 */
69#define LM80_VT4_LOW_LIM 0x33 /* low limit val for Voltage 4 */
70#define LM80_VT5_HIGH_LIM 0x34 /* high limit val for Voltage 5 */
71#define LM80_VT5_LOW_LIM 0x35 /* low limit val for Voltage 5 */
72#define LM80_VT6_HIGH_LIM 0x36 /* high limit val for Voltage 6 */
73#define LM80_VT6_LOW_LIM 0x37 /* low limit val for Voltage 6 */
74#define LM80_THOT_LIM_UP 0x38 /* hot temperature limit (high) */
75#define LM80_THOT_LIM_LO 0x39 /* hot temperature limit (low) */
76#define LM80_TOS_LIM_UP 0x3a /* OS temperature limit (high) */
77#define LM80_TOS_LIM_LO 0x3b /* OS temperature limit (low) */
78#define LM80_FAN1_COUNT_LIM 0x3c /* Fan 1 count limit (high) */
79#define LM80_FAN2_COUNT_LIM 0x3d /* Fan 2 count limit (low) */
80 /* 0x3e - 0x3f reserved */
81
82/*
83 * LM80 bit definitions
84 */
85
86/* LM80_CFG Configuration Register */
87#define LM80_CFG_START (1<<0) /* start monitoring operation */
88#define LM80_CFG_INT_ENA (1<<1) /* enables the INT# Interrupt output */
89#define LM80_CFG_INT_POL (1<<2) /* INT# pol: 0 act low, 1 act high */
90#define LM80_CFG_INT_CLR (1<<3) /* disables INT#/RST_OUT#/OS# outputs */
91#define LM80_CFG_RESET (1<<4) /* signals a reset */
92#define LM80_CFG_CHASS_CLR (1<<5) /* clears Chassis Intrusion (CI) pin */
93#define LM80_CFG_GPO (1<<6) /* drives the GPO# pin */
94#define LM80_CFG_INIT (1<<7) /* restore power on defaults */
95
96/* LM80_ISRC_1 Interrupt Status Register 1 */
97/* LM80_IMSK_1 Interrupt Mask Register 1 */
98#define LM80_IS_VT0 (1<<0) /* limit exceeded for Voltage 0 */
99#define LM80_IS_VT1 (1<<1) /* limit exceeded for Voltage 1 */
100#define LM80_IS_VT2 (1<<2) /* limit exceeded for Voltage 2 */
101#define LM80_IS_VT3 (1<<3) /* limit exceeded for Voltage 3 */
102#define LM80_IS_VT4 (1<<4) /* limit exceeded for Voltage 4 */
103#define LM80_IS_VT5 (1<<5) /* limit exceeded for Voltage 5 */
104#define LM80_IS_VT6 (1<<6) /* limit exceeded for Voltage 6 */
105#define LM80_IS_INT_IN (1<<7) /* state of INT_IN# */
106
107/* LM80_ISRC_2 Interrupt Status Register 2 */
108/* LM80_IMSK_2 Interrupt Mask Register 2 */
109#define LM80_IS_TEMP (1<<0) /* HOT temperature limit exceeded */
110#define LM80_IS_BTI (1<<1) /* state of BTI# pin */
111#define LM80_IS_FAN1 (1<<2) /* count limit exceeded for Fan 1 */
112#define LM80_IS_FAN2 (1<<3) /* count limit exceeded for Fan 2 */
113#define LM80_IS_CI (1<<4) /* Chassis Intrusion occured */
114#define LM80_IS_OS (1<<5) /* OS temperature limit exceeded */
115 /* bit 6 and 7 are reserved in LM80_ISRC_2 */
116#define LM80_IS_HT_IRQ_MD (1<<6) /* Hot temperature interrupt mode */
117#define LM80_IS_OT_IRQ_MD (1<<7) /* OS temperature interrupt mode */
118
119/* LM80_FAN_CTRL Fan Devisor/RST#/OS# Register */
120#define LM80_FAN1_MD_SEL (1<<0) /* Fan 1 mode select */
121#define LM80_FAN2_MD_SEL (1<<1) /* Fan 2 mode select */
122#define LM80_FAN1_PRM_CTL (3<<2) /* Fan 1 speed control */
123#define LM80_FAN2_PRM_CTL (3<<4) /* Fan 2 speed control */
124#define LM80_FAN_OS_ENA (1<<6) /* enable OS mode on RST_OUT#/OS# pins*/
125#define LM80_FAN_RST_ENA (1<<7) /* sets RST_OUT#/OS# pins in RST mode */
126
127/* LM80_TEMP_CTRL OS# Config, Temp Res. Reg */
128#define LM80_TEMP_OS_STAT (1<<0) /* mirrors the state of RST_OUT#/OS# */
129#define LM80_TEMP_OS_POL (1<<1) /* select OS# polarity */
130#define LM80_TEMP_OS_MODE (1<<2) /* selects Interrupt mode */
131#define LM80_TEMP_RES (1<<3) /* selects 9 or 11 bit temp resulution*/
132#define LM80_TEMP_LSB (0xf<<4)/* 4 LSBs of 11 bit temp data */
133#define LM80_TEMP_LSB_9 (1<<7) /* LSB of 9 bit temperature data */
134
135 /* 0x07 - 0x1f reserved */
136/* LM80_VT0_IN current Voltage 0 value */
137/* LM80_VT1_IN current Voltage 1 value */
138/* LM80_VT2_IN current Voltage 2 value */
139/* LM80_VT3_IN current Voltage 3 value */
140/* LM80_VT4_IN current Voltage 4 value */
141/* LM80_VT5_IN current Voltage 5 value */
142/* LM80_VT6_IN current Voltage 6 value */
143/* LM80_TEMP_IN current temperature value */
144/* LM80_FAN1_IN current Fan 1 count */
145/* LM80_FAN2_IN current Fan 2 count */
146/* LM80_VT0_HIGH_LIM high limit val for Voltage 0 */
147/* LM80_VT0_LOW_LIM low limit val for Voltage 0 */
148/* LM80_VT1_HIGH_LIM high limit val for Voltage 1 */
149/* LM80_VT1_LOW_LIM low limit val for Voltage 1 */
150/* LM80_VT2_HIGH_LIM high limit val for Voltage 2 */
151/* LM80_VT2_LOW_LIM low limit val for Voltage 2 */
152/* LM80_VT3_HIGH_LIM high limit val for Voltage 3 */
153/* LM80_VT3_LOW_LIM low limit val for Voltage 3 */
154/* LM80_VT4_HIGH_LIM high limit val for Voltage 4 */
155/* LM80_VT4_LOW_LIM low limit val for Voltage 4 */
156/* LM80_VT5_HIGH_LIM high limit val for Voltage 5 */
157/* LM80_VT5_LOW_LIM low limit val for Voltage 5 */
158/* LM80_VT6_HIGH_LIM high limit val for Voltage 6 */
159/* LM80_VT6_LOW_LIM low limit val for Voltage 6 */
160/* LM80_THOT_LIM_UP hot temperature limit (high) */
161/* LM80_THOT_LIM_LO hot temperature limit (low) */
162/* LM80_TOS_LIM_UP OS temperature limit (high) */
163/* LM80_TOS_LIM_LO OS temperature limit (low) */
164/* LM80_FAN1_COUNT_LIM Fan 1 count limit (high) */
165/* LM80_FAN2_COUNT_LIM Fan 2 count limit (low) */
166 /* 0x3e - 0x3f reserved */
167
168#define LM80_ADDR 0x28 /* LM80 default addr */
169
170/* typedefs *******************************************************************/
171
172
173/* function prototypes ********************************************************/
174
175#ifdef __cplusplus
176}
177#endif /* __cplusplus */
178
179#endif /* __INC_LM80_H */
diff --git a/drivers/net/sk98lin/h/skaddr.h b/drivers/net/sk98lin/h/skaddr.h
new file mode 100644
index 000000000000..3a2ea4a4b539
--- /dev/null
+++ b/drivers/net/sk98lin/h/skaddr.h
@@ -0,0 +1,333 @@
1/******************************************************************************
2 *
3 * Name: skaddr.h
4 * Project: Gigabit Ethernet Adapters, ADDR-Modul
5 * Version: $Revision: 1.29 $
6 * Date: $Date: 2003/05/13 16:57:24 $
7 * Purpose: Header file for Address Management (MC, UC, Prom).
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * This module is intended to manage multicast addresses and promiscuous mode
30 * on GEnesis adapters.
31 *
32 * Include File Hierarchy:
33 *
34 * "skdrv1st.h"
35 * ...
36 * "sktypes.h"
37 * "skqueue.h"
38 * "skaddr.h"
39 * ...
40 * "skdrv2nd.h"
41 *
42 ******************************************************************************/
43
44#ifndef __INC_SKADDR_H
45#define __INC_SKADDR_H
46
47#ifdef __cplusplus
48extern "C" {
49#endif /* cplusplus */
50
51/* defines ********************************************************************/
52
53#define SK_MAC_ADDR_LEN 6 /* Length of MAC address. */
54#define SK_MAX_ADDRS 14 /* #Addrs for exact match. */
55
56/* ----- Common return values ----- */
57
58#define SK_ADDR_SUCCESS 0 /* Function returned successfully. */
59#define SK_ADDR_ILLEGAL_PORT 100 /* Port number too high. */
60#define SK_ADDR_TOO_EARLY 101 /* Function called too early. */
61
62/* ----- Clear/Add flag bits ----- */
63
64#define SK_ADDR_PERMANENT 1 /* RLMT Address */
65
66/* ----- Additional Clear flag bits ----- */
67
68#define SK_MC_SW_ONLY 2 /* Do not update HW when clearing. */
69
70/* ----- Override flag bits ----- */
71
72#define SK_ADDR_LOGICAL_ADDRESS 0
73#define SK_ADDR_VIRTUAL_ADDRESS (SK_ADDR_LOGICAL_ADDRESS) /* old */
74#define SK_ADDR_PHYSICAL_ADDRESS 1
75#define SK_ADDR_CLEAR_LOGICAL 2
76#define SK_ADDR_SET_LOGICAL 4
77
78/* ----- Override return values ----- */
79
80#define SK_ADDR_OVERRIDE_SUCCESS (SK_ADDR_SUCCESS)
81#define SK_ADDR_DUPLICATE_ADDRESS 1
82#define SK_ADDR_MULTICAST_ADDRESS 2
83
84/* ----- Partitioning of excact match table ----- */
85
86#define SK_ADDR_EXACT_MATCHES 16 /* #Exact match entries. */
87
88#define SK_ADDR_FIRST_MATCH_RLMT 1
89#define SK_ADDR_LAST_MATCH_RLMT 2
90#define SK_ADDR_FIRST_MATCH_DRV 3
91#define SK_ADDR_LAST_MATCH_DRV (SK_ADDR_EXACT_MATCHES - 1)
92
93/* ----- SkAddrMcAdd/SkAddrMcUpdate return values ----- */
94
95#define SK_MC_FILTERING_EXACT 0 /* Exact filtering. */
96#define SK_MC_FILTERING_INEXACT 1 /* Inexact filtering. */
97
98/* ----- Additional SkAddrMcAdd return values ----- */
99
100#define SK_MC_ILLEGAL_ADDRESS 2 /* Illegal address. */
101#define SK_MC_ILLEGAL_PORT 3 /* Illegal port (not the active one). */
102#define SK_MC_RLMT_OVERFLOW 4 /* Too many RLMT mc addresses. */
103
104/* Promiscuous mode bits ----- */
105
106#define SK_PROM_MODE_NONE 0 /* Normal receive. */
107#define SK_PROM_MODE_LLC 1 /* Receive all LLC frames. */
108#define SK_PROM_MODE_ALL_MC 2 /* Receive all multicast frames. */
109/* #define SK_PROM_MODE_NON_LLC 4 */ /* Receive all non-LLC frames. */
110
111/* Macros */
112
113#ifdef OLD_STUFF
114#ifndef SK_ADDR_EQUAL
115/*
116 * "&" instead of "&&" allows better optimization on IA-64.
117 * The replacement is safe here, as all bytes exist.
118 */
119#ifndef SK_ADDR_DWORD_COMPARE
120#define SK_ADDR_EQUAL(A1,A2) ( \
121 (((SK_U8 *)(A1))[5] == ((SK_U8 *)(A2))[5]) & \
122 (((SK_U8 *)(A1))[4] == ((SK_U8 *)(A2))[4]) & \
123 (((SK_U8 *)(A1))[3] == ((SK_U8 *)(A2))[3]) & \
124 (((SK_U8 *)(A1))[2] == ((SK_U8 *)(A2))[2]) & \
125 (((SK_U8 *)(A1))[1] == ((SK_U8 *)(A2))[1]) & \
126 (((SK_U8 *)(A1))[0] == ((SK_U8 *)(A2))[0]))
127#else /* SK_ADDR_DWORD_COMPARE */
128#define SK_ADDR_EQUAL(A1,A2) ( \
129 (*(SK_U32 *)&(((SK_U8 *)(A1))[2]) == *(SK_U32 *)&(((SK_U8 *)(A2))[2])) & \
130 (*(SK_U32 *)&(((SK_U8 *)(A1))[0]) == *(SK_U32 *)&(((SK_U8 *)(A2))[0])))
131#endif /* SK_ADDR_DWORD_COMPARE */
132#endif /* SK_ADDR_EQUAL */
133#endif /* 0 */
134
135#ifndef SK_ADDR_EQUAL
136#ifndef SK_ADDR_DWORD_COMPARE
137#define SK_ADDR_EQUAL(A1,A2) ( \
138 (((SK_U8 SK_FAR *)(A1))[5] == ((SK_U8 SK_FAR *)(A2))[5]) & \
139 (((SK_U8 SK_FAR *)(A1))[4] == ((SK_U8 SK_FAR *)(A2))[4]) & \
140 (((SK_U8 SK_FAR *)(A1))[3] == ((SK_U8 SK_FAR *)(A2))[3]) & \
141 (((SK_U8 SK_FAR *)(A1))[2] == ((SK_U8 SK_FAR *)(A2))[2]) & \
142 (((SK_U8 SK_FAR *)(A1))[1] == ((SK_U8 SK_FAR *)(A2))[1]) & \
143 (((SK_U8 SK_FAR *)(A1))[0] == ((SK_U8 SK_FAR *)(A2))[0]))
144#else /* SK_ADDR_DWORD_COMPARE */
145#define SK_ADDR_EQUAL(A1,A2) ( \
146 (*(SK_U16 SK_FAR *)&(((SK_U8 SK_FAR *)(A1))[4]) == \
147 *(SK_U16 SK_FAR *)&(((SK_U8 SK_FAR *)(A2))[4])) && \
148 (*(SK_U32 SK_FAR *)&(((SK_U8 SK_FAR *)(A1))[0]) == \
149 *(SK_U32 SK_FAR *)&(((SK_U8 SK_FAR *)(A2))[0])))
150#endif /* SK_ADDR_DWORD_COMPARE */
151#endif /* SK_ADDR_EQUAL */
152
153/* typedefs *******************************************************************/
154
155typedef struct s_MacAddr {
156 SK_U8 a[SK_MAC_ADDR_LEN];
157} SK_MAC_ADDR;
158
159
160/* SK_FILTER is used to ensure alignment of the filter. */
161typedef union s_InexactFilter {
162 SK_U8 Bytes[8];
163 SK_U64 Val; /* Dummy entry for alignment only. */
164} SK_FILTER64;
165
166
167typedef struct s_AddrNet SK_ADDR_NET;
168
169
170typedef struct s_AddrPort {
171
172/* ----- Public part (read-only) ----- */
173
174 SK_MAC_ADDR CurrentMacAddress; /* Current physical MAC Address. */
175 SK_MAC_ADDR PermanentMacAddress; /* Permanent physical MAC Address. */
176 int PromMode; /* Promiscuous Mode. */
177
178/* ----- Private part ----- */
179
180 SK_MAC_ADDR PreviousMacAddress; /* Prev. phys. MAC Address. */
181 SK_BOOL CurrentMacAddressSet; /* CurrentMacAddress is set. */
182 SK_U8 Align01;
183
184 SK_U32 FirstExactMatchRlmt;
185 SK_U32 NextExactMatchRlmt;
186 SK_U32 FirstExactMatchDrv;
187 SK_U32 NextExactMatchDrv;
188 SK_MAC_ADDR Exact[SK_ADDR_EXACT_MATCHES];
189 SK_FILTER64 InexactFilter; /* For 64-bit hash register. */
190 SK_FILTER64 InexactRlmtFilter; /* For 64-bit hash register. */
191 SK_FILTER64 InexactDrvFilter; /* For 64-bit hash register. */
192} SK_ADDR_PORT;
193
194
195struct s_AddrNet {
196/* ----- Public part (read-only) ----- */
197
198 SK_MAC_ADDR CurrentMacAddress; /* Logical MAC Address. */
199 SK_MAC_ADDR PermanentMacAddress; /* Logical MAC Address. */
200
201/* ----- Private part ----- */
202
203 SK_U32 ActivePort; /* View of module ADDR. */
204 SK_BOOL CurrentMacAddressSet; /* CurrentMacAddress is set. */
205 SK_U8 Align01;
206 SK_U16 Align02;
207};
208
209
210typedef struct s_Addr {
211
212/* ----- Public part (read-only) ----- */
213
214 SK_ADDR_NET Net[SK_MAX_NETS];
215 SK_ADDR_PORT Port[SK_MAX_MACS];
216
217/* ----- Private part ----- */
218} SK_ADDR;
219
220/* function prototypes ********************************************************/
221
222#ifndef SK_KR_PROTO
223
224/* Functions provided by SkAddr */
225
226/* ANSI/C++ compliant function prototypes */
227
228extern int SkAddrInit(
229 SK_AC *pAC,
230 SK_IOC IoC,
231 int Level);
232
233extern int SkAddrMcClear(
234 SK_AC *pAC,
235 SK_IOC IoC,
236 SK_U32 PortNumber,
237 int Flags);
238
239extern int SkAddrXmacMcClear(
240 SK_AC *pAC,
241 SK_IOC IoC,
242 SK_U32 PortNumber,
243 int Flags);
244
245extern int SkAddrGmacMcClear(
246 SK_AC *pAC,
247 SK_IOC IoC,
248 SK_U32 PortNumber,
249 int Flags);
250
251extern int SkAddrMcAdd(
252 SK_AC *pAC,
253 SK_IOC IoC,
254 SK_U32 PortNumber,
255 SK_MAC_ADDR *pMc,
256 int Flags);
257
258extern int SkAddrXmacMcAdd(
259 SK_AC *pAC,
260 SK_IOC IoC,
261 SK_U32 PortNumber,
262 SK_MAC_ADDR *pMc,
263 int Flags);
264
265extern int SkAddrGmacMcAdd(
266 SK_AC *pAC,
267 SK_IOC IoC,
268 SK_U32 PortNumber,
269 SK_MAC_ADDR *pMc,
270 int Flags);
271
272extern int SkAddrMcUpdate(
273 SK_AC *pAC,
274 SK_IOC IoC,
275 SK_U32 PortNumber);
276
277extern int SkAddrXmacMcUpdate(
278 SK_AC *pAC,
279 SK_IOC IoC,
280 SK_U32 PortNumber);
281
282extern int SkAddrGmacMcUpdate(
283 SK_AC *pAC,
284 SK_IOC IoC,
285 SK_U32 PortNumber);
286
287extern int SkAddrOverride(
288 SK_AC *pAC,
289 SK_IOC IoC,
290 SK_U32 PortNumber,
291 SK_MAC_ADDR SK_FAR *pNewAddr,
292 int Flags);
293
294extern int SkAddrPromiscuousChange(
295 SK_AC *pAC,
296 SK_IOC IoC,
297 SK_U32 PortNumber,
298 int NewPromMode);
299
300extern int SkAddrXmacPromiscuousChange(
301 SK_AC *pAC,
302 SK_IOC IoC,
303 SK_U32 PortNumber,
304 int NewPromMode);
305
306extern int SkAddrGmacPromiscuousChange(
307 SK_AC *pAC,
308 SK_IOC IoC,
309 SK_U32 PortNumber,
310 int NewPromMode);
311
312#ifndef SK_SLIM
313extern int SkAddrSwap(
314 SK_AC *pAC,
315 SK_IOC IoC,
316 SK_U32 FromPortNumber,
317 SK_U32 ToPortNumber);
318#endif
319
320#else /* defined(SK_KR_PROTO)) */
321
322/* Non-ANSI/C++ compliant function prototypes */
323
324#error KR-style prototypes are not yet provided.
325
326#endif /* defined(SK_KR_PROTO)) */
327
328
329#ifdef __cplusplus
330}
331#endif /* __cplusplus */
332
333#endif /* __INC_SKADDR_H */
diff --git a/drivers/net/sk98lin/h/skcsum.h b/drivers/net/sk98lin/h/skcsum.h
new file mode 100644
index 000000000000..2b94adb93331
--- /dev/null
+++ b/drivers/net/sk98lin/h/skcsum.h
@@ -0,0 +1,219 @@
1/******************************************************************************
2 *
3 * Name: skcsum.h
4 * Project: GEnesis - SysKonnect SK-NET Gigabit Ethernet (SK-98xx)
5 * Version: $Revision: 1.10 $
6 * Date: $Date: 2003/08/20 13:59:57 $
7 * Purpose: Store/verify Internet checksum in send/receive packets.
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2001 SysKonnect GmbH.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * The information in this file is provided "AS IS" without warranty.
21 *
22 ******************************************************************************/
23
24/******************************************************************************
25 *
26 * Description:
27 *
28 * Public header file for the "GEnesis" common module "CSUM".
29 *
30 * "GEnesis" is an abbreviation of "Gigabit Ethernet Network System in Silicon"
31 * and is the code name of this SysKonnect project.
32 *
33 * Compilation Options:
34 *
35 * SK_USE_CSUM - Define if CSUM is to be used. Otherwise, CSUM will be an
36 * empty module.
37 *
38 * SKCS_OVERWRITE_PROTO - Define to overwrite the default protocol id
39 * definitions. In this case, all SKCS_PROTO_xxx definitions must be made
40 * external.
41 *
42 * SKCS_OVERWRITE_STATUS - Define to overwrite the default return status
43 * definitions. In this case, all SKCS_STATUS_xxx definitions must be made
44 * external.
45 *
46 * Include File Hierarchy:
47 *
48 * "h/skcsum.h"
49 * "h/sktypes.h"
50 * "h/skqueue.h"
51 *
52 ******************************************************************************/
53
54#ifndef __INC_SKCSUM_H
55#define __INC_SKCSUM_H
56
57#include "h/sktypes.h"
58#include "h/skqueue.h"
59
60/* defines ********************************************************************/
61
62/*
63 * Define the default bit flags for 'SKCS_PACKET_INFO.ProtocolFlags' if no user
64 * overwrite.
65 */
66#ifndef SKCS_OVERWRITE_PROTO /* User overwrite? */
67#define SKCS_PROTO_IP 0x1 /* IP (Internet Protocol version 4) */
68#define SKCS_PROTO_TCP 0x2 /* TCP (Transmission Control Protocol) */
69#define SKCS_PROTO_UDP 0x4 /* UDP (User Datagram Protocol) */
70
71/* Indices for protocol statistics. */
72#define SKCS_PROTO_STATS_IP 0
73#define SKCS_PROTO_STATS_UDP 1
74#define SKCS_PROTO_STATS_TCP 2
75#define SKCS_NUM_PROTOCOLS 3 /* Number of supported protocols. */
76#endif /* !SKCS_OVERWRITE_PROTO */
77
78/*
79 * Define the default SKCS_STATUS type and values if no user overwrite.
80 *
81 * SKCS_STATUS_UNKNOWN_IP_VERSION - Not an IP v4 frame.
82 * SKCS_STATUS_IP_CSUM_ERROR - IP checksum error.
83 * SKCS_STATUS_IP_CSUM_ERROR_TCP - IP checksum error in TCP frame.
84 * SKCS_STATUS_IP_CSUM_ERROR_UDP - IP checksum error in UDP frame
85 * SKCS_STATUS_IP_FRAGMENT - IP fragment (IP checksum ok).
86 * SKCS_STATUS_IP_CSUM_OK - IP checksum ok (not a TCP or UDP frame).
87 * SKCS_STATUS_TCP_CSUM_ERROR - TCP checksum error (IP checksum ok).
88 * SKCS_STATUS_UDP_CSUM_ERROR - UDP checksum error (IP checksum ok).
89 * SKCS_STATUS_TCP_CSUM_OK - IP and TCP checksum ok.
90 * SKCS_STATUS_UDP_CSUM_OK - IP and UDP checksum ok.
91 * SKCS_STATUS_IP_CSUM_OK_NO_UDP - IP checksum OK and no UDP checksum.
92 */
93#ifndef SKCS_OVERWRITE_STATUS /* User overwrite? */
94#define SKCS_STATUS int /* Define status type. */
95
96#define SKCS_STATUS_UNKNOWN_IP_VERSION 1
97#define SKCS_STATUS_IP_CSUM_ERROR 2
98#define SKCS_STATUS_IP_FRAGMENT 3
99#define SKCS_STATUS_IP_CSUM_OK 4
100#define SKCS_STATUS_TCP_CSUM_ERROR 5
101#define SKCS_STATUS_UDP_CSUM_ERROR 6
102#define SKCS_STATUS_TCP_CSUM_OK 7
103#define SKCS_STATUS_UDP_CSUM_OK 8
104/* needed for Microsoft */
105#define SKCS_STATUS_IP_CSUM_ERROR_UDP 9
106#define SKCS_STATUS_IP_CSUM_ERROR_TCP 10
107/* UDP checksum may be omitted */
108#define SKCS_STATUS_IP_CSUM_OK_NO_UDP 11
109#endif /* !SKCS_OVERWRITE_STATUS */
110
111/* Clear protocol statistics event. */
112#define SK_CSUM_EVENT_CLEAR_PROTO_STATS 1
113
114/*
115 * Add two values in one's complement.
116 *
117 * Note: One of the two input values may be "longer" than 16-bit, but then the
118 * resulting sum may be 17 bits long. In this case, add zero to the result using
119 * SKCS_OC_ADD() again.
120 *
121 * Result = Value1 + Value2
122 */
123#define SKCS_OC_ADD(Result, Value1, Value2) { \
124 unsigned long Sum; \
125 \
126 Sum = (unsigned long) (Value1) + (unsigned long) (Value2); \
127 /* Add-in any carry. */ \
128 (Result) = (Sum & 0xffff) + (Sum >> 16); \
129}
130
131/*
132 * Subtract two values in one's complement.
133 *
134 * Result = Value1 - Value2
135 */
136#define SKCS_OC_SUB(Result, Value1, Value2) \
137 SKCS_OC_ADD((Result), (Value1), ~(Value2) & 0xffff)
138
139/* typedefs *******************************************************************/
140
141/*
142 * SKCS_PROTO_STATS - The CSUM protocol statistics structure.
143 *
144 * There is one instance of this structure for each protocol supported.
145 */
146typedef struct s_CsProtocolStatistics {
147 SK_U64 RxOkCts; /* Receive checksum ok. */
148 SK_U64 RxUnableCts; /* Unable to verify receive checksum. */
149 SK_U64 RxErrCts; /* Receive checksum error. */
150 SK_U64 TxOkCts; /* Transmit checksum ok. */
151 SK_U64 TxUnableCts; /* Unable to calculate checksum in hw. */
152} SKCS_PROTO_STATS;
153
154/*
155 * s_Csum - The CSUM module context structure.
156 */
157typedef struct s_Csum {
158 /* Enabled receive SK_PROTO_XXX bit flags. */
159 unsigned ReceiveFlags[SK_MAX_NETS];
160#ifdef TX_CSUM
161 unsigned TransmitFlags[SK_MAX_NETS];
162#endif /* TX_CSUM */
163
164 /* The protocol statistics structure; one per supported protocol. */
165 SKCS_PROTO_STATS ProtoStats[SK_MAX_NETS][SKCS_NUM_PROTOCOLS];
166} SK_CSUM;
167
168/*
169 * SKCS_PACKET_INFO - The packet information structure.
170 */
171typedef struct s_CsPacketInfo {
172 /* Bit field specifiying the desired/found protocols. */
173 unsigned ProtocolFlags;
174
175 /* Length of complete IP header, including any option fields. */
176 unsigned IpHeaderLength;
177
178 /* IP header checksum. */
179 unsigned IpHeaderChecksum;
180
181 /* TCP/UDP pseudo header checksum. */
182 unsigned PseudoHeaderChecksum;
183} SKCS_PACKET_INFO;
184
185/* function prototypes ********************************************************/
186
187#ifndef SK_CS_CALCULATE_CHECKSUM
188extern unsigned SkCsCalculateChecksum(
189 void *pData,
190 unsigned Length);
191#endif /* SK_CS_CALCULATE_CHECKSUM */
192
193extern int SkCsEvent(
194 SK_AC *pAc,
195 SK_IOC Ioc,
196 SK_U32 Event,
197 SK_EVPARA Param);
198
199extern SKCS_STATUS SkCsGetReceiveInfo(
200 SK_AC *pAc,
201 void *pIpHeader,
202 unsigned Checksum1,
203 unsigned Checksum2,
204 int NetNumber);
205
206extern void SkCsGetSendInfo(
207 SK_AC *pAc,
208 void *pIpHeader,
209 SKCS_PACKET_INFO *pPacketInfo,
210 int NetNumber);
211
212extern void SkCsSetReceiveFlags(
213 SK_AC *pAc,
214 unsigned ReceiveFlags,
215 unsigned *pChecksum1Offset,
216 unsigned *pChecksum2Offset,
217 int NetNumber);
218
219#endif /* __INC_SKCSUM_H */
diff --git a/drivers/net/sk98lin/h/skdebug.h b/drivers/net/sk98lin/h/skdebug.h
new file mode 100644
index 000000000000..3cba171d74b2
--- /dev/null
+++ b/drivers/net/sk98lin/h/skdebug.h
@@ -0,0 +1,74 @@
1/******************************************************************************
2 *
3 * Name: skdebug.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.14 $
6 * Date: $Date: 2003/05/13 17:26:00 $
7 * Purpose: SK specific DEBUG support
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef __INC_SKDEBUG_H
26#define __INC_SKDEBUG_H
27
28#ifdef DEBUG
29#ifndef SK_DBG_MSG
30#define SK_DBG_MSG(pAC,comp,cat,arg) \
31 if ( ((comp) & SK_DBG_CHKMOD(pAC)) && \
32 ((cat) & SK_DBG_CHKCAT(pAC)) ) { \
33 SK_DBG_PRINTF arg ; \
34 }
35#endif
36#else
37#define SK_DBG_MSG(pAC,comp,lev,arg)
38#endif
39
40/* PLS NOTE:
41 * =========
42 * Due to any restrictions of kernel printf routines do not use other
43 * format identifiers as: %x %d %c %s .
44 * Never use any combined format identifiers such as: %lx %ld in your
45 * printf - argument (arg) because some OS specific kernel printfs may
46 * only support some basic identifiers.
47 */
48
49/* Debug modules */
50
51#define SK_DBGMOD_MERR 0x00000001L /* general module error indication */
52#define SK_DBGMOD_HWM 0x00000002L /* Hardware init module */
53#define SK_DBGMOD_RLMT 0x00000004L /* RLMT module */
54#define SK_DBGMOD_VPD 0x00000008L /* VPD module */
55#define SK_DBGMOD_I2C 0x00000010L /* I2C module */
56#define SK_DBGMOD_PNMI 0x00000020L /* PNMI module */
57#define SK_DBGMOD_CSUM 0x00000040L /* CSUM module */
58#define SK_DBGMOD_ADDR 0x00000080L /* ADDR module */
59#define SK_DBGMOD_PECP 0x00000100L /* PECP module */
60#define SK_DBGMOD_POWM 0x00000200L /* Power Management module */
61
62/* Debug events */
63
64#define SK_DBGCAT_INIT 0x00000001L /* module/driver initialization */
65#define SK_DBGCAT_CTRL 0x00000002L /* controlling devices */
66#define SK_DBGCAT_ERR 0x00000004L /* error handling paths */
67#define SK_DBGCAT_TX 0x00000008L /* transmit path */
68#define SK_DBGCAT_RX 0x00000010L /* receive path */
69#define SK_DBGCAT_IRQ 0x00000020L /* general IRQ handling */
70#define SK_DBGCAT_QUEUE 0x00000040L /* any queue management */
71#define SK_DBGCAT_DUMP 0x00000080L /* large data output e.g. hex dump */
72#define SK_DBGCAT_FATAL 0x00000100L /* fatal error */
73
74#endif /* __INC_SKDEBUG_H */
diff --git a/drivers/net/sk98lin/h/skdrv1st.h b/drivers/net/sk98lin/h/skdrv1st.h
new file mode 100644
index 000000000000..308440bd0e12
--- /dev/null
+++ b/drivers/net/sk98lin/h/skdrv1st.h
@@ -0,0 +1,191 @@
1/******************************************************************************
2 *
3 * Name: skdrv1st.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.4 $
6 * Date: $Date: 2003/11/12 14:28:14 $
7 * Purpose: First header file for driver and all other modules
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * This is the first include file of the driver, which includes all
30 * neccessary system header files and some of the GEnesis header files.
31 * It also defines some basic items.
32 *
33 * Include File Hierarchy:
34 *
35 * see skge.c
36 *
37 ******************************************************************************/
38
39#ifndef __INC_SKDRV1ST_H
40#define __INC_SKDRV1ST_H
41
42/* Check kernel version */
43#include <linux/version.h>
44
45typedef struct s_AC SK_AC;
46
47/* Set card versions */
48#define SK_FAR
49
50/* override some default functions with optimized linux functions */
51
52#define SK_PNMI_STORE_U16(p,v) memcpy((char*)(p),(char*)&(v),2)
53#define SK_PNMI_STORE_U32(p,v) memcpy((char*)(p),(char*)&(v),4)
54#define SK_PNMI_STORE_U64(p,v) memcpy((char*)(p),(char*)&(v),8)
55#define SK_PNMI_READ_U16(p,v) memcpy((char*)&(v),(char*)(p),2)
56#define SK_PNMI_READ_U32(p,v) memcpy((char*)&(v),(char*)(p),4)
57#define SK_PNMI_READ_U64(p,v) memcpy((char*)&(v),(char*)(p),8)
58
59#define SK_ADDR_EQUAL(a1,a2) (!memcmp(a1,a2,6))
60
61#include <linux/types.h>
62#include <linux/kernel.h>
63#include <linux/string.h>
64#include <linux/errno.h>
65#include <linux/ioport.h>
66#include <linux/slab.h>
67#include <linux/interrupt.h>
68#include <linux/pci.h>
69#include <linux/bitops.h>
70#include <asm/byteorder.h>
71#include <asm/io.h>
72#include <asm/irq.h>
73#include <linux/netdevice.h>
74#include <linux/etherdevice.h>
75#include <linux/skbuff.h>
76
77#include <linux/init.h>
78#include <asm/uaccess.h>
79#include <net/checksum.h>
80
81#define SK_CS_CALCULATE_CHECKSUM
82#ifndef CONFIG_X86_64
83#define SkCsCalculateChecksum(p,l) ((~ip_compute_csum(p, l)) & 0xffff)
84#else
85#define SkCsCalculateChecksum(p,l) ((~ip_fast_csum(p, l)) & 0xffff)
86#endif
87
88#include "h/sktypes.h"
89#include "h/skerror.h"
90#include "h/skdebug.h"
91#include "h/lm80.h"
92#include "h/xmac_ii.h"
93
94#ifdef __LITTLE_ENDIAN
95#define SK_LITTLE_ENDIAN
96#else
97#define SK_BIG_ENDIAN
98#endif
99
100#define SK_NET_DEVICE net_device
101
102
103/* we use gethrtime(), return unit: nanoseconds */
104#define SK_TICKS_PER_SEC 100
105
106#define SK_MEM_MAPPED_IO
107
108// #define SK_RLMT_SLOW_LOOKAHEAD
109
110#define SK_MAX_MACS 2
111#define SK_MAX_NETS 2
112
113#define SK_IOC char __iomem *
114
115typedef struct s_DrvRlmtMbuf SK_MBUF;
116
117#define SK_CONST64 INT64_C
118#define SK_CONSTU64 UINT64_C
119
120#define SK_MEMCPY(dest,src,size) memcpy(dest,src,size)
121#define SK_MEMCMP(s1,s2,size) memcmp(s1,s2,size)
122#define SK_MEMSET(dest,val,size) memset(dest,val,size)
123#define SK_STRLEN(pStr) strlen((char*)(pStr))
124#define SK_STRNCPY(pDest,pSrc,size) strncpy((char*)(pDest),(char*)(pSrc),size)
125#define SK_STRCMP(pStr1,pStr2) strcmp((char*)(pStr1),(char*)(pStr2))
126
127/* macros to access the adapter */
128#define SK_OUT8(b,a,v) writeb((v), ((b)+(a)))
129#define SK_OUT16(b,a,v) writew((v), ((b)+(a)))
130#define SK_OUT32(b,a,v) writel((v), ((b)+(a)))
131#define SK_IN8(b,a,pv) (*(pv) = readb((b)+(a)))
132#define SK_IN16(b,a,pv) (*(pv) = readw((b)+(a)))
133#define SK_IN32(b,a,pv) (*(pv) = readl((b)+(a)))
134
135#define int8_t char
136#define int16_t short
137#define int32_t long
138#define int64_t long long
139#define uint8_t u_char
140#define uint16_t u_short
141#define uint32_t u_long
142#define uint64_t unsigned long long
143#define t_scalar_t int
144#define t_uscalar_t unsigned int
145#define uintptr_t unsigned long
146
147#define __CONCAT__(A,B) A##B
148
149#define INT32_C(a) __CONCAT__(a,L)
150#define INT64_C(a) __CONCAT__(a,LL)
151#define UINT32_C(a) __CONCAT__(a,UL)
152#define UINT64_C(a) __CONCAT__(a,ULL)
153
154#ifdef DEBUG
155#define SK_DBG_PRINTF printk
156#ifndef SK_DEBUG_CHKMOD
157#define SK_DEBUG_CHKMOD 0
158#endif
159#ifndef SK_DEBUG_CHKCAT
160#define SK_DEBUG_CHKCAT 0
161#endif
162/* those come from the makefile */
163#define SK_DBG_CHKMOD(pAC) (SK_DEBUG_CHKMOD)
164#define SK_DBG_CHKCAT(pAC) (SK_DEBUG_CHKCAT)
165
166extern void SkDbgPrintf(const char *format,...);
167
168#define SK_DBGMOD_DRV 0x00010000
169
170/**** possible driver debug categories ********************************/
171#define SK_DBGCAT_DRV_ENTRY 0x00010000
172#define SK_DBGCAT_DRV_SAP 0x00020000
173#define SK_DBGCAT_DRV_MCA 0x00040000
174#define SK_DBGCAT_DRV_TX_PROGRESS 0x00080000
175#define SK_DBGCAT_DRV_RX_PROGRESS 0x00100000
176#define SK_DBGCAT_DRV_PROGRESS 0x00200000
177#define SK_DBGCAT_DRV_MSG 0x00400000
178#define SK_DBGCAT_DRV_PROM 0x00800000
179#define SK_DBGCAT_DRV_TX_FRAME 0x01000000
180#define SK_DBGCAT_DRV_ERROR 0x02000000
181#define SK_DBGCAT_DRV_INT_SRC 0x04000000
182#define SK_DBGCAT_DRV_EVENT 0x08000000
183
184#endif
185
186#define SK_ERR_LOG SkErrorLog
187
188extern void SkErrorLog(SK_AC*, int, int, char*);
189
190#endif
191
diff --git a/drivers/net/sk98lin/h/skdrv2nd.h b/drivers/net/sk98lin/h/skdrv2nd.h
new file mode 100644
index 000000000000..542cec57f86a
--- /dev/null
+++ b/drivers/net/sk98lin/h/skdrv2nd.h
@@ -0,0 +1,456 @@
1/******************************************************************************
2 *
3 * Name: skdrv2nd.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.10 $
6 * Date: $Date: 2003/12/11 16:04:45 $
7 * Purpose: Second header file for driver and all other modules
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * This is the second include file of the driver, which includes all other
30 * neccessary files and defines all structures and constants used by the
31 * driver and the common modules.
32 *
33 * Include File Hierarchy:
34 *
35 * see skge.c
36 *
37 ******************************************************************************/
38
39#ifndef __INC_SKDRV2ND_H
40#define __INC_SKDRV2ND_H
41
42#include "h/skqueue.h"
43#include "h/skgehwt.h"
44#include "h/sktimer.h"
45#include "h/ski2c.h"
46#include "h/skgepnmi.h"
47#include "h/skvpd.h"
48#include "h/skgehw.h"
49#include "h/skgeinit.h"
50#include "h/skaddr.h"
51#include "h/skgesirq.h"
52#include "h/skcsum.h"
53#include "h/skrlmt.h"
54#include "h/skgedrv.h"
55
56
57extern SK_MBUF *SkDrvAllocRlmtMbuf(SK_AC*, SK_IOC, unsigned);
58extern void SkDrvFreeRlmtMbuf(SK_AC*, SK_IOC, SK_MBUF*);
59extern SK_U64 SkOsGetTime(SK_AC*);
60extern int SkPciReadCfgDWord(SK_AC*, int, SK_U32*);
61extern int SkPciReadCfgWord(SK_AC*, int, SK_U16*);
62extern int SkPciReadCfgByte(SK_AC*, int, SK_U8*);
63extern int SkPciWriteCfgDWord(SK_AC*, int, SK_U32);
64extern int SkPciWriteCfgWord(SK_AC*, int, SK_U16);
65extern int SkPciWriteCfgByte(SK_AC*, int, SK_U8);
66extern int SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA);
67
68#ifdef SK_DIAG_SUPPORT
69extern int SkDrvEnterDiagMode(SK_AC *pAc);
70extern int SkDrvLeaveDiagMode(SK_AC *pAc);
71#endif
72
73struct s_DrvRlmtMbuf {
74 SK_MBUF *pNext; /* Pointer to next RLMT Mbuf. */
75 SK_U8 *pData; /* Data buffer (virtually contig.). */
76 unsigned Size; /* Data buffer size. */
77 unsigned Length; /* Length of packet (<= Size). */
78 SK_U32 PortIdx; /* Receiving/transmitting port. */
79#ifdef SK_RLMT_MBUF_PRIVATE
80 SK_RLMT_MBUF Rlmt; /* Private part for RLMT. */
81#endif /* SK_RLMT_MBUF_PRIVATE */
82 struct sk_buff *pOs; /* Pointer to message block */
83};
84
85
86/*
87 * Time macros
88 */
89#if SK_TICKS_PER_SEC == 100
90#define SK_PNMI_HUNDREDS_SEC(t) (t)
91#else
92#define SK_PNMI_HUNDREDS_SEC(t) ((((unsigned long)t) * 100) / \
93 (SK_TICKS_PER_SEC))
94#endif
95
96/*
97 * New SkOsGetTime
98 */
99#define SkOsGetTimeCurrent(pAC, pUsec) {\
100 struct timeval t;\
101 do_gettimeofday(&t);\
102 *pUsec = ((((t.tv_sec) * 1000000L)+t.tv_usec)/10000);\
103}
104
105
106/*
107 * ioctl definitions
108 */
109#define SK_IOCTL_BASE (SIOCDEVPRIVATE)
110#define SK_IOCTL_GETMIB (SK_IOCTL_BASE + 0)
111#define SK_IOCTL_SETMIB (SK_IOCTL_BASE + 1)
112#define SK_IOCTL_PRESETMIB (SK_IOCTL_BASE + 2)
113#define SK_IOCTL_GEN (SK_IOCTL_BASE + 3)
114#define SK_IOCTL_DIAG (SK_IOCTL_BASE + 4)
115
116typedef struct s_IOCTL SK_GE_IOCTL;
117
118struct s_IOCTL {
119 char __user * pData;
120 unsigned int Len;
121};
122
123
124/*
125 * define sizes of descriptor rings in bytes
126 */
127
128#define TX_RING_SIZE (8*1024)
129#define RX_RING_SIZE (24*1024)
130
131/*
132 * Buffer size for ethernet packets
133 */
134#define ETH_BUF_SIZE 1540
135#define ETH_MAX_MTU 1514
136#define ETH_MIN_MTU 60
137#define ETH_MULTICAST_BIT 0x01
138#define SK_JUMBO_MTU 9000
139
140/*
141 * transmit priority selects the queue: LOW=asynchron, HIGH=synchron
142 */
143#define TX_PRIO_LOW 0
144#define TX_PRIO_HIGH 1
145
146/*
147 * alignment of rx/tx descriptors
148 */
149#define DESCR_ALIGN 64
150
151/*
152 * definitions for pnmi. TODO
153 */
154#define SK_DRIVER_RESET(pAC, IoC) 0
155#define SK_DRIVER_SENDEVENT(pAC, IoC) 0
156#define SK_DRIVER_SELFTEST(pAC, IoC) 0
157/* For get mtu you must add an own function */
158#define SK_DRIVER_GET_MTU(pAc,IoC,i) 0
159#define SK_DRIVER_SET_MTU(pAc,IoC,i,v) 0
160#define SK_DRIVER_PRESET_MTU(pAc,IoC,i,v) 0
161
162/*
163** Interim definition of SK_DRV_TIMER placed in this file until
164** common modules have boon finallized
165*/
166#define SK_DRV_TIMER 11
167#define SK_DRV_MODERATION_TIMER 1
168#define SK_DRV_MODERATION_TIMER_LENGTH 1000000 /* 1 second */
169#define SK_DRV_RX_CLEANUP_TIMER 2
170#define SK_DRV_RX_CLEANUP_TIMER_LENGTH 1000000 /* 100 millisecs */
171
172/*
173** Definitions regarding transmitting frames
174** any calculating any checksum.
175*/
176#define C_LEN_ETHERMAC_HEADER_DEST_ADDR 6
177#define C_LEN_ETHERMAC_HEADER_SRC_ADDR 6
178#define C_LEN_ETHERMAC_HEADER_LENTYPE 2
179#define C_LEN_ETHERMAC_HEADER ( (C_LEN_ETHERMAC_HEADER_DEST_ADDR) + \
180 (C_LEN_ETHERMAC_HEADER_SRC_ADDR) + \
181 (C_LEN_ETHERMAC_HEADER_LENTYPE) )
182
183#define C_LEN_ETHERMTU_MINSIZE 46
184#define C_LEN_ETHERMTU_MAXSIZE_STD 1500
185#define C_LEN_ETHERMTU_MAXSIZE_JUMBO 9000
186
187#define C_LEN_ETHERNET_MINSIZE ( (C_LEN_ETHERMAC_HEADER) + \
188 (C_LEN_ETHERMTU_MINSIZE) )
189
190#define C_OFFSET_IPHEADER C_LEN_ETHERMAC_HEADER
191#define C_OFFSET_IPHEADER_IPPROTO 9
192#define C_OFFSET_TCPHEADER_TCPCS 16
193#define C_OFFSET_UDPHEADER_UDPCS 6
194
195#define C_OFFSET_IPPROTO ( (C_LEN_ETHERMAC_HEADER) + \
196 (C_OFFSET_IPHEADER_IPPROTO) )
197
198#define C_PROTO_ID_UDP 17 /* refer to RFC 790 or Stevens' */
199#define C_PROTO_ID_TCP 6 /* TCP/IP illustrated for details */
200
201/* TX and RX descriptors *****************************************************/
202
203typedef struct s_RxD RXD; /* the receive descriptor */
204
205struct s_RxD {
206 volatile SK_U32 RBControl; /* Receive Buffer Control */
207 SK_U32 VNextRxd; /* Next receive descriptor,low dword */
208 SK_U32 VDataLow; /* Receive buffer Addr, low dword */
209 SK_U32 VDataHigh; /* Receive buffer Addr, high dword */
210 SK_U32 FrameStat; /* Receive Frame Status word */
211 SK_U32 TimeStamp; /* Time stamp from XMAC */
212 SK_U32 TcpSums; /* TCP Sum 2 / TCP Sum 1 */
213 SK_U32 TcpSumStarts; /* TCP Sum Start 2 / TCP Sum Start 1 */
214 RXD *pNextRxd; /* Pointer to next Rxd */
215 struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */
216};
217
218typedef struct s_TxD TXD; /* the transmit descriptor */
219
220struct s_TxD {
221 volatile SK_U32 TBControl; /* Transmit Buffer Control */
222 SK_U32 VNextTxd; /* Next transmit descriptor,low dword */
223 SK_U32 VDataLow; /* Transmit Buffer Addr, low dword */
224 SK_U32 VDataHigh; /* Transmit Buffer Addr, high dword */
225 SK_U32 FrameStat; /* Transmit Frame Status Word */
226 SK_U32 TcpSumOfs; /* Reserved / TCP Sum Offset */
227 SK_U16 TcpSumSt; /* TCP Sum Start */
228 SK_U16 TcpSumWr; /* TCP Sum Write */
229 SK_U32 TcpReserved; /* not used */
230 TXD *pNextTxd; /* Pointer to next Txd */
231 struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */
232};
233
234/* Used interrupt bits in the interrupts source register *********************/
235
236#define DRIVER_IRQS ((IS_IRQ_SW) | \
237 (IS_R1_F) |(IS_R2_F) | \
238 (IS_XS1_F) |(IS_XA1_F) | \
239 (IS_XS2_F) |(IS_XA2_F))
240
241#define SPECIAL_IRQS ((IS_HW_ERR) |(IS_I2C_READY) | \
242 (IS_EXT_REG) |(IS_TIMINT) | \
243 (IS_PA_TO_RX1) |(IS_PA_TO_RX2) | \
244 (IS_PA_TO_TX1) |(IS_PA_TO_TX2) | \
245 (IS_MAC1) |(IS_LNK_SYNC_M1)| \
246 (IS_MAC2) |(IS_LNK_SYNC_M2)| \
247 (IS_R1_C) |(IS_R2_C) | \
248 (IS_XS1_C) |(IS_XA1_C) | \
249 (IS_XS2_C) |(IS_XA2_C))
250
251#define IRQ_MASK ((IS_IRQ_SW) | \
252 (IS_R1_B) |(IS_R1_F) |(IS_R2_B) |(IS_R2_F) | \
253 (IS_XS1_B) |(IS_XS1_F) |(IS_XA1_B)|(IS_XA1_F)| \
254 (IS_XS2_B) |(IS_XS2_F) |(IS_XA2_B)|(IS_XA2_F)| \
255 (IS_HW_ERR) |(IS_I2C_READY)| \
256 (IS_EXT_REG) |(IS_TIMINT) | \
257 (IS_PA_TO_RX1) |(IS_PA_TO_RX2)| \
258 (IS_PA_TO_TX1) |(IS_PA_TO_TX2)| \
259 (IS_MAC1) |(IS_MAC2) | \
260 (IS_R1_C) |(IS_R2_C) | \
261 (IS_XS1_C) |(IS_XA1_C) | \
262 (IS_XS2_C) |(IS_XA2_C))
263
264#define IRQ_HWE_MASK (IS_ERR_MSK) /* enable all HW irqs */
265
266typedef struct s_DevNet DEV_NET;
267
268struct s_DevNet {
269 int PortNr;
270 int NetNr;
271 int Mtu;
272 int Up;
273 SK_AC *pAC;
274};
275
276typedef struct s_TxPort TX_PORT;
277
278struct s_TxPort {
279 /* the transmit descriptor rings */
280 caddr_t pTxDescrRing; /* descriptor area memory */
281 SK_U64 VTxDescrRing; /* descr. area bus virt. addr. */
282 TXD *pTxdRingHead; /* Head of Tx rings */
283 TXD *pTxdRingTail; /* Tail of Tx rings */
284 TXD *pTxdRingPrev; /* descriptor sent previously */
285 int TxdRingFree; /* # of free entrys */
286 spinlock_t TxDesRingLock; /* serialize descriptor accesses */
287 SK_IOC HwAddr; /* bmu registers address */
288 int PortIndex; /* index number of port (0 or 1) */
289};
290
291typedef struct s_RxPort RX_PORT;
292
293struct s_RxPort {
294 /* the receive descriptor rings */
295 caddr_t pRxDescrRing; /* descriptor area memory */
296 SK_U64 VRxDescrRing; /* descr. area bus virt. addr. */
297 RXD *pRxdRingHead; /* Head of Rx rings */
298 RXD *pRxdRingTail; /* Tail of Rx rings */
299 RXD *pRxdRingPrev; /* descriptor given to BMU previously */
300 int RxdRingFree; /* # of free entrys */
301 spinlock_t RxDesRingLock; /* serialize descriptor accesses */
302 int RxFillLimit; /* limit for buffers in ring */
303 SK_IOC HwAddr; /* bmu registers address */
304 int PortIndex; /* index number of port (0 or 1) */
305};
306
307/* Definitions needed for interrupt moderation *******************************/
308
309#define IRQ_EOF_AS_TX ((IS_XA1_F) | (IS_XA2_F))
310#define IRQ_EOF_SY_TX ((IS_XS1_F) | (IS_XS2_F))
311#define IRQ_MASK_TX_ONLY ((IRQ_EOF_AS_TX)| (IRQ_EOF_SY_TX))
312#define IRQ_MASK_RX_ONLY ((IS_R1_F) | (IS_R2_F))
313#define IRQ_MASK_SP_ONLY (SPECIAL_IRQS)
314#define IRQ_MASK_TX_RX ((IRQ_MASK_TX_ONLY)| (IRQ_MASK_RX_ONLY))
315#define IRQ_MASK_SP_RX ((SPECIAL_IRQS) | (IRQ_MASK_RX_ONLY))
316#define IRQ_MASK_SP_TX ((SPECIAL_IRQS) | (IRQ_MASK_TX_ONLY))
317#define IRQ_MASK_RX_TX_SP ((SPECIAL_IRQS) | (IRQ_MASK_TX_RX))
318
319#define C_INT_MOD_NONE 1
320#define C_INT_MOD_STATIC 2
321#define C_INT_MOD_DYNAMIC 4
322
323#define C_CLK_FREQ_GENESIS 53215000 /* shorter: 53.125 MHz */
324#define C_CLK_FREQ_YUKON 78215000 /* shorter: 78.125 MHz */
325
326#define C_INTS_PER_SEC_DEFAULT 2000
327#define C_INT_MOD_ENABLE_PERCENTAGE 50 /* if higher 50% enable */
328#define C_INT_MOD_DISABLE_PERCENTAGE 50 /* if lower 50% disable */
329#define C_INT_MOD_IPS_LOWER_RANGE 30
330#define C_INT_MOD_IPS_UPPER_RANGE 40000
331
332
333typedef struct s_DynIrqModInfo DIM_INFO;
334struct s_DynIrqModInfo {
335 unsigned long PrevTimeVal;
336 unsigned int PrevSysLoad;
337 unsigned int PrevUsedTime;
338 unsigned int PrevTotalTime;
339 int PrevUsedDescrRatio;
340 int NbrProcessedDescr;
341 SK_U64 PrevPort0RxIntrCts;
342 SK_U64 PrevPort1RxIntrCts;
343 SK_U64 PrevPort0TxIntrCts;
344 SK_U64 PrevPort1TxIntrCts;
345 SK_BOOL ModJustEnabled; /* Moderation just enabled yes/no */
346
347 int MaxModIntsPerSec; /* Moderation Threshold */
348 int MaxModIntsPerSecUpperLimit; /* Upper limit for DIM */
349 int MaxModIntsPerSecLowerLimit; /* Lower limit for DIM */
350
351 long MaskIrqModeration; /* ModIrqType (eg. 'TxRx') */
352 SK_BOOL DisplayStats; /* Stats yes/no */
353 SK_BOOL AutoSizing; /* Resize DIM-timer on/off */
354 int IntModTypeSelect; /* EnableIntMod (eg. 'dynamic') */
355
356 SK_TIMER ModTimer; /* just some timer */
357};
358
359typedef struct s_PerStrm PER_STRM;
360
361#define SK_ALLOC_IRQ 0x00000001
362
363#ifdef SK_DIAG_SUPPORT
364#define DIAG_ACTIVE 1
365#define DIAG_NOTACTIVE 0
366#endif
367
368/****************************************************************************
369 * Per board structure / Adapter Context structure:
370 * Allocated within attach(9e) and freed within detach(9e).
371 * Contains all 'per device' necessary handles, flags, locks etc.:
372 */
373struct s_AC {
374 SK_GEINIT GIni; /* GE init struct */
375 SK_PNMI Pnmi; /* PNMI data struct */
376 SK_VPD vpd; /* vpd data struct */
377 SK_QUEUE Event; /* Event queue */
378 SK_HWT Hwt; /* Hardware Timer control struct */
379 SK_TIMCTRL Tim; /* Software Timer control struct */
380 SK_I2C I2c; /* I2C relevant data structure */
381 SK_ADDR Addr; /* for Address module */
382 SK_CSUM Csum; /* for checksum module */
383 SK_RLMT Rlmt; /* for rlmt module */
384 spinlock_t SlowPathLock; /* Normal IRQ lock */
385 struct timer_list BlinkTimer; /* for LED blinking */
386 int LedsOn;
387 SK_PNMI_STRUCT_DATA PnmiStruct; /* structure to get all Pnmi-Data */
388 int RlmtMode; /* link check mode to set */
389 int RlmtNets; /* Number of nets */
390
391 SK_IOC IoBase; /* register set of adapter */
392 int BoardLevel; /* level of active hw init (0-2) */
393 char DeviceStr[80]; /* adapter string from vpd */
394 SK_U32 AllocFlag; /* flag allocation of resources */
395 struct pci_dev *PciDev; /* for access to pci config space */
396 SK_U32 PciDevId; /* pci device id */
397 struct SK_NET_DEVICE *dev[2]; /* pointer to device struct */
398 char Name[30]; /* driver name */
399
400 int RxBufSize; /* length of receive buffers */
401 struct net_device_stats stats; /* linux 'netstat -i' statistics */
402 int Index; /* internal board index number */
403
404 /* adapter RAM sizes for queues of active port */
405 int RxQueueSize; /* memory used for receive queue */
406 int TxSQueueSize; /* memory used for sync. tx queue */
407 int TxAQueueSize; /* memory used for async. tx queue */
408
409 int PromiscCount; /* promiscuous mode counter */
410 int AllMultiCount; /* allmulticast mode counter */
411 int MulticCount; /* number of different MC */
412 /* addresses for this board */
413 /* (may be more than HW can)*/
414
415 int HWRevision; /* Hardware revision */
416 int ActivePort; /* the active XMAC port */
417 int MaxPorts; /* number of activated ports */
418 int TxDescrPerRing; /* # of descriptors per tx ring */
419 int RxDescrPerRing; /* # of descriptors per rx ring */
420
421 caddr_t pDescrMem; /* Pointer to the descriptor area */
422 dma_addr_t pDescrMemDMA; /* PCI DMA address of area */
423
424 /* the port structures with descriptor rings */
425 TX_PORT TxPort[SK_MAX_MACS][2];
426 RX_PORT RxPort[SK_MAX_MACS];
427
428 unsigned int CsOfs1; /* for checksum calculation */
429 unsigned int CsOfs2; /* for checksum calculation */
430 SK_U32 CsOfs; /* for checksum calculation */
431
432 SK_BOOL CheckQueue; /* check event queue soon */
433 SK_TIMER DrvCleanupTimer;/* to check for pending descriptors */
434 DIM_INFO DynIrqModInfo; /* all data related to DIM */
435
436 /* Only for tests */
437 int PortUp;
438 int PortDown;
439 int ChipsetType; /* Chipset family type
440 * 0 == Genesis family support
441 * 1 == Yukon family support
442 */
443#ifdef SK_DIAG_SUPPORT
444 SK_U32 DiagModeActive; /* is diag active? */
445 SK_BOOL DiagFlowCtrl; /* for control purposes */
446 SK_PNMI_STRUCT_DATA PnmiBackup; /* backup structure for all Pnmi-Data */
447 SK_BOOL WasIfUp[SK_MAX_MACS]; /* for OpenClose while
448 * DIAG is busy with NIC
449 */
450#endif
451
452};
453
454
455#endif /* __INC_SKDRV2ND_H */
456
diff --git a/drivers/net/sk98lin/h/skerror.h b/drivers/net/sk98lin/h/skerror.h
new file mode 100644
index 000000000000..da062f766238
--- /dev/null
+++ b/drivers/net/sk98lin/h/skerror.h
@@ -0,0 +1,55 @@
1/******************************************************************************
2 *
3 * Name: skerror.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.7 $
6 * Date: $Date: 2003/05/13 17:25:13 $
7 * Purpose: SK specific Error log support
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef _INC_SKERROR_H_
26#define _INC_SKERROR_H_
27
28/*
29 * Define Error Classes
30 */
31#define SK_ERRCL_OTHER (0) /* Other error */
32#define SK_ERRCL_CONFIG (1L<<0) /* Configuration error */
33#define SK_ERRCL_INIT (1L<<1) /* Initialization error */
34#define SK_ERRCL_NORES (1L<<2) /* Out of Resources error */
35#define SK_ERRCL_SW (1L<<3) /* Internal Software error */
36#define SK_ERRCL_HW (1L<<4) /* Hardware Failure */
37#define SK_ERRCL_COMM (1L<<5) /* Communication error */
38
39
40/*
41 * Define Error Code Bases
42 */
43#define SK_ERRBASE_RLMT 100 /* Base Error number for RLMT */
44#define SK_ERRBASE_HWINIT 200 /* Base Error number for HWInit */
45#define SK_ERRBASE_VPD 300 /* Base Error number for VPD */
46#define SK_ERRBASE_PNMI 400 /* Base Error number for PNMI */
47#define SK_ERRBASE_CSUM 500 /* Base Error number for Checksum */
48#define SK_ERRBASE_SIRQ 600 /* Base Error number for Special IRQ */
49#define SK_ERRBASE_I2C 700 /* Base Error number for I2C module */
50#define SK_ERRBASE_QUEUE 800 /* Base Error number for Scheduler */
51#define SK_ERRBASE_ADDR 900 /* Base Error number for Address module */
52#define SK_ERRBASE_PECP 1000 /* Base Error number for PECP */
53#define SK_ERRBASE_DRV 1100 /* Base Error number for Driver */
54
55#endif /* _INC_SKERROR_H_ */
diff --git a/drivers/net/sk98lin/h/skgedrv.h b/drivers/net/sk98lin/h/skgedrv.h
new file mode 100644
index 000000000000..44fd4c3de818
--- /dev/null
+++ b/drivers/net/sk98lin/h/skgedrv.h
@@ -0,0 +1,51 @@
1/******************************************************************************
2 *
3 * Name: skgedrv.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.10 $
6 * Date: $Date: 2003/07/04 12:25:01 $
7 * Purpose: Interface with the driver
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef __INC_SKGEDRV_H_
26#define __INC_SKGEDRV_H_
27
28/* defines ********************************************************************/
29
30/*
31 * Define the driver events.
32 * Usually the events are defined by the destination module.
33 * In case of the driver we put the definition of the events here.
34 */
35#define SK_DRV_PORT_RESET 1 /* The port needs to be reset */
36#define SK_DRV_NET_UP 2 /* The net is operational */
37#define SK_DRV_NET_DOWN 3 /* The net is down */
38#define SK_DRV_SWITCH_SOFT 4 /* Ports switch with both links connected */
39#define SK_DRV_SWITCH_HARD 5 /* Port switch due to link failure */
40#define SK_DRV_RLMT_SEND 6 /* Send a RLMT packet */
41#define SK_DRV_ADAP_FAIL 7 /* The whole adapter fails */
42#define SK_DRV_PORT_FAIL 8 /* One port fails */
43#define SK_DRV_SWITCH_INTERN 9 /* Port switch by the driver itself */
44#define SK_DRV_POWER_DOWN 10 /* Power down mode */
45#define SK_DRV_TIMER 11 /* Timer for free use */
46#ifdef SK_NO_RLMT
47#define SK_DRV_LINK_UP 12 /* Link Up event for driver */
48#define SK_DRV_LINK_DOWN 13 /* Link Down event for driver */
49#endif
50#define SK_DRV_DOWNSHIFT_DET 14 /* Downshift 4-Pair / 2-Pair (YUKON only) */
51#endif /* __INC_SKGEDRV_H_ */
diff --git a/drivers/net/sk98lin/h/skgehw.h b/drivers/net/sk98lin/h/skgehw.h
new file mode 100644
index 000000000000..f6282b7956db
--- /dev/null
+++ b/drivers/net/sk98lin/h/skgehw.h
@@ -0,0 +1,2126 @@
1/******************************************************************************
2 *
3 * Name: skgehw.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.56 $
6 * Date: $Date: 2003/09/23 09:01:00 $
7 * Purpose: Defines and Macros for the Gigabit Ethernet Adapter Product Family
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef __INC_SKGEHW_H
26#define __INC_SKGEHW_H
27
28#ifdef __cplusplus
29extern "C" {
30#endif /* __cplusplus */
31
32/* defines ********************************************************************/
33
34#define BIT_31 (1UL << 31)
35#define BIT_30 (1L << 30)
36#define BIT_29 (1L << 29)
37#define BIT_28 (1L << 28)
38#define BIT_27 (1L << 27)
39#define BIT_26 (1L << 26)
40#define BIT_25 (1L << 25)
41#define BIT_24 (1L << 24)
42#define BIT_23 (1L << 23)
43#define BIT_22 (1L << 22)
44#define BIT_21 (1L << 21)
45#define BIT_20 (1L << 20)
46#define BIT_19 (1L << 19)
47#define BIT_18 (1L << 18)
48#define BIT_17 (1L << 17)
49#define BIT_16 (1L << 16)
50#define BIT_15 (1L << 15)
51#define BIT_14 (1L << 14)
52#define BIT_13 (1L << 13)
53#define BIT_12 (1L << 12)
54#define BIT_11 (1L << 11)
55#define BIT_10 (1L << 10)
56#define BIT_9 (1L << 9)
57#define BIT_8 (1L << 8)
58#define BIT_7 (1L << 7)
59#define BIT_6 (1L << 6)
60#define BIT_5 (1L << 5)
61#define BIT_4 (1L << 4)
62#define BIT_3 (1L << 3)
63#define BIT_2 (1L << 2)
64#define BIT_1 (1L << 1)
65#define BIT_0 1L
66
67#define BIT_15S (1U << 15)
68#define BIT_14S (1 << 14)
69#define BIT_13S (1 << 13)
70#define BIT_12S (1 << 12)
71#define BIT_11S (1 << 11)
72#define BIT_10S (1 << 10)
73#define BIT_9S (1 << 9)
74#define BIT_8S (1 << 8)
75#define BIT_7S (1 << 7)
76#define BIT_6S (1 << 6)
77#define BIT_5S (1 << 5)
78#define BIT_4S (1 << 4)
79#define BIT_3S (1 << 3)
80#define BIT_2S (1 << 2)
81#define BIT_1S (1 << 1)
82#define BIT_0S 1
83
84#define SHIFT31(x) ((x) << 31)
85#define SHIFT30(x) ((x) << 30)
86#define SHIFT29(x) ((x) << 29)
87#define SHIFT28(x) ((x) << 28)
88#define SHIFT27(x) ((x) << 27)
89#define SHIFT26(x) ((x) << 26)
90#define SHIFT25(x) ((x) << 25)
91#define SHIFT24(x) ((x) << 24)
92#define SHIFT23(x) ((x) << 23)
93#define SHIFT22(x) ((x) << 22)
94#define SHIFT21(x) ((x) << 21)
95#define SHIFT20(x) ((x) << 20)
96#define SHIFT19(x) ((x) << 19)
97#define SHIFT18(x) ((x) << 18)
98#define SHIFT17(x) ((x) << 17)
99#define SHIFT16(x) ((x) << 16)
100#define SHIFT15(x) ((x) << 15)
101#define SHIFT14(x) ((x) << 14)
102#define SHIFT13(x) ((x) << 13)
103#define SHIFT12(x) ((x) << 12)
104#define SHIFT11(x) ((x) << 11)
105#define SHIFT10(x) ((x) << 10)
106#define SHIFT9(x) ((x) << 9)
107#define SHIFT8(x) ((x) << 8)
108#define SHIFT7(x) ((x) << 7)
109#define SHIFT6(x) ((x) << 6)
110#define SHIFT5(x) ((x) << 5)
111#define SHIFT4(x) ((x) << 4)
112#define SHIFT3(x) ((x) << 3)
113#define SHIFT2(x) ((x) << 2)
114#define SHIFT1(x) ((x) << 1)
115#define SHIFT0(x) ((x) << 0)
116
117/*
118 * Configuration Space header
119 * Since this module is used for different OS', those may be
120 * duplicate on some of them (e.g. Linux). But to keep the
121 * common source, we have to live with this...
122 */
123#define PCI_VENDOR_ID 0x00 /* 16 bit Vendor ID */
124#define PCI_DEVICE_ID 0x02 /* 16 bit Device ID */
125#define PCI_COMMAND 0x04 /* 16 bit Command */
126#define PCI_STATUS 0x06 /* 16 bit Status */
127#define PCI_REV_ID 0x08 /* 8 bit Revision ID */
128#define PCI_CLASS_CODE 0x09 /* 24 bit Class Code */
129#define PCI_CACHE_LSZ 0x0c /* 8 bit Cache Line Size */
130#define PCI_LAT_TIM 0x0d /* 8 bit Latency Timer */
131#define PCI_HEADER_T 0x0e /* 8 bit Header Type */
132#define PCI_BIST 0x0f /* 8 bit Built-in selftest */
133#define PCI_BASE_1ST 0x10 /* 32 bit 1st Base address */
134#define PCI_BASE_2ND 0x14 /* 32 bit 2nd Base address */
135 /* Byte 0x18..0x2b: reserved */
136#define PCI_SUB_VID 0x2c /* 16 bit Subsystem Vendor ID */
137#define PCI_SUB_ID 0x2e /* 16 bit Subsystem ID */
138#define PCI_BASE_ROM 0x30 /* 32 bit Expansion ROM Base Address */
139#define PCI_CAP_PTR 0x34 /* 8 bit Capabilities Ptr */
140 /* Byte 0x35..0x3b: reserved */
141#define PCI_IRQ_LINE 0x3c /* 8 bit Interrupt Line */
142#define PCI_IRQ_PIN 0x3d /* 8 bit Interrupt Pin */
143#define PCI_MIN_GNT 0x3e /* 8 bit Min_Gnt */
144#define PCI_MAX_LAT 0x3f /* 8 bit Max_Lat */
145 /* Device Dependent Region */
146#define PCI_OUR_REG_1 0x40 /* 32 bit Our Register 1 */
147#define PCI_OUR_REG_2 0x44 /* 32 bit Our Register 2 */
148 /* Power Management Region */
149#define PCI_PM_CAP_ID 0x48 /* 8 bit Power Management Cap. ID */
150#define PCI_PM_NITEM 0x49 /* 8 bit Next Item Ptr */
151#define PCI_PM_CAP_REG 0x4a /* 16 bit Power Management Capabilities */
152#define PCI_PM_CTL_STS 0x4c /* 16 bit Power Manag. Control/Status */
153 /* Byte 0x4e: reserved */
154#define PCI_PM_DAT_REG 0x4f /* 8 bit Power Manag. Data Register */
155 /* VPD Region */
156#define PCI_VPD_CAP_ID 0x50 /* 8 bit VPD Cap. ID */
157#define PCI_VPD_NITEM 0x51 /* 8 bit Next Item Ptr */
158#define PCI_VPD_ADR_REG 0x52 /* 16 bit VPD Address Register */
159#define PCI_VPD_DAT_REG 0x54 /* 32 bit VPD Data Register */
160 /* Byte 0x58..0x59: reserved */
161#define PCI_SER_LD_CTRL 0x5a /* 16 bit SEEPROM Loader Ctrl (YUKON only) */
162 /* Byte 0x5c..0xff: reserved */
163
164/*
165 * I2C Address (PCI Config)
166 *
167 * Note: The temperature and voltage sensors are relocated on a different
168 * I2C bus.
169 */
170#define I2C_ADDR_VPD 0xa0 /* I2C address for the VPD EEPROM */
171
172/*
173 * Define Bits and Values of the registers
174 */
175/* PCI_COMMAND 16 bit Command */
176 /* Bit 15..11: reserved */
177#define PCI_INT_DIS BIT_10S /* Interrupt INTx# disable (PCI 2.3) */
178#define PCI_FBTEN BIT_9S /* Fast Back-To-Back enable */
179#define PCI_SERREN BIT_8S /* SERR enable */
180#define PCI_ADSTEP BIT_7S /* Address Stepping */
181#define PCI_PERREN BIT_6S /* Parity Report Response enable */
182#define PCI_VGA_SNOOP BIT_5S /* VGA palette snoop */
183#define PCI_MWIEN BIT_4S /* Memory write an inv cycl ena */
184#define PCI_SCYCEN BIT_3S /* Special Cycle enable */
185#define PCI_BMEN BIT_2S /* Bus Master enable */
186#define PCI_MEMEN BIT_1S /* Memory Space Access enable */
187#define PCI_IOEN BIT_0S /* I/O Space Access enable */
188
189#define PCI_COMMAND_VAL (PCI_FBTEN | PCI_SERREN | PCI_PERREN | PCI_MWIEN |\
190 PCI_BMEN | PCI_MEMEN | PCI_IOEN)
191
192/* PCI_STATUS 16 bit Status */
193#define PCI_PERR BIT_15S /* Parity Error */
194#define PCI_SERR BIT_14S /* Signaled SERR */
195#define PCI_RMABORT BIT_13S /* Received Master Abort */
196#define PCI_RTABORT BIT_12S /* Received Target Abort */
197 /* Bit 11: reserved */
198#define PCI_DEVSEL (3<<9) /* Bit 10.. 9: DEVSEL Timing */
199#define PCI_DEV_FAST (0<<9) /* fast */
200#define PCI_DEV_MEDIUM (1<<9) /* medium */
201#define PCI_DEV_SLOW (2<<9) /* slow */
202#define PCI_DATAPERR BIT_8S /* DATA Parity error detected */
203#define PCI_FB2BCAP BIT_7S /* Fast Back-to-Back Capability */
204#define PCI_UDF BIT_6S /* User Defined Features */
205#define PCI_66MHZCAP BIT_5S /* 66 MHz PCI bus clock capable */
206#define PCI_NEWCAP BIT_4S /* New cap. list implemented */
207#define PCI_INT_STAT BIT_3S /* Interrupt INTx# Status (PCI 2.3) */
208 /* Bit 2.. 0: reserved */
209
210#define PCI_ERRBITS (PCI_PERR | PCI_SERR | PCI_RMABORT | PCI_RTABORT |\
211 PCI_DATAPERR)
212
213/* PCI_CLASS_CODE 24 bit Class Code */
214/* Byte 2: Base Class (02) */
215/* Byte 1: SubClass (00) */
216/* Byte 0: Programming Interface (00) */
217
218/* PCI_CACHE_LSZ 8 bit Cache Line Size */
219/* Possible values: 0,2,4,8,16,32,64,128 */
220
221/* PCI_HEADER_T 8 bit Header Type */
222#define PCI_HD_MF_DEV BIT_7S /* 0= single, 1= multi-func dev */
223#define PCI_HD_TYPE 0x7f /* Bit 6..0: Header Layout 0= normal */
224
225/* PCI_BIST 8 bit Built-in selftest */
226/* Built-in Self test not supported (optional) */
227
228/* PCI_BASE_1ST 32 bit 1st Base address */
229#define PCI_MEMSIZE 0x4000L /* use 16 kB Memory Base */
230#define PCI_MEMBASE_MSK 0xffffc000L /* Bit 31..14: Memory Base Address */
231#define PCI_MEMSIZE_MSK 0x00003ff0L /* Bit 13.. 4: Memory Size Req. */
232#define PCI_PREFEN BIT_3 /* Prefetchable */
233#define PCI_MEM_TYP (3L<<2) /* Bit 2.. 1: Memory Type */
234#define PCI_MEM32BIT (0L<<1) /* Base addr anywhere in 32 Bit range */
235#define PCI_MEM1M (1L<<1) /* Base addr below 1 MegaByte */
236#define PCI_MEM64BIT (2L<<1) /* Base addr anywhere in 64 Bit range */
237#define PCI_MEMSPACE BIT_0 /* Memory Space Indicator */
238
239/* PCI_BASE_2ND 32 bit 2nd Base address */
240#define PCI_IOBASE 0xffffff00L /* Bit 31.. 8: I/O Base address */
241#define PCI_IOSIZE 0x000000fcL /* Bit 7.. 2: I/O Size Requirements */
242 /* Bit 1: reserved */
243#define PCI_IOSPACE BIT_0 /* I/O Space Indicator */
244
245/* PCI_BASE_ROM 32 bit Expansion ROM Base Address */
246#define PCI_ROMBASE_MSK 0xfffe0000L /* Bit 31..17: ROM Base address */
247#define PCI_ROMBASE_SIZ (0x1cL<<14) /* Bit 16..14: Treat as Base or Size */
248#define PCI_ROMSIZE (0x38L<<11) /* Bit 13..11: ROM Size Requirements */
249 /* Bit 10.. 1: reserved */
250#define PCI_ROMEN BIT_0 /* Address Decode enable */
251
252/* Device Dependent Region */
253/* PCI_OUR_REG_1 32 bit Our Register 1 */
254 /* Bit 31..29: reserved */
255#define PCI_PHY_COMA BIT_28 /* Set PHY to Coma Mode (YUKON only) */
256#define PCI_TEST_CAL BIT_27 /* Test PCI buffer calib. (YUKON only) */
257#define PCI_EN_CAL BIT_26 /* Enable PCI buffer calib. (YUKON only) */
258#define PCI_VIO BIT_25 /* PCI I/O Voltage, 0 = 3.3V, 1 = 5V */
259#define PCI_DIS_BOOT BIT_24 /* Disable BOOT via ROM */
260#define PCI_EN_IO BIT_23 /* Mapping to I/O space */
261#define PCI_EN_FPROM BIT_22 /* Enable FLASH mapping to memory */
262 /* 1 = Map Flash to memory */
263 /* 0 = Disable addr. dec */
264#define PCI_PAGESIZE (3L<<20) /* Bit 21..20: FLASH Page Size */
265#define PCI_PAGE_16 (0L<<20) /* 16 k pages */
266#define PCI_PAGE_32K (1L<<20) /* 32 k pages */
267#define PCI_PAGE_64K (2L<<20) /* 64 k pages */
268#define PCI_PAGE_128K (3L<<20) /* 128 k pages */
269 /* Bit 19: reserved */
270#define PCI_PAGEREG (7L<<16) /* Bit 18..16: Page Register */
271#define PCI_NOTAR BIT_15 /* No turnaround cycle */
272#define PCI_FORCE_BE BIT_14 /* Assert all BEs on MR */
273#define PCI_DIS_MRL BIT_13 /* Disable Mem Read Line */
274#define PCI_DIS_MRM BIT_12 /* Disable Mem Read Multiple */
275#define PCI_DIS_MWI BIT_11 /* Disable Mem Write & Invalidate */
276#define PCI_DISC_CLS BIT_10 /* Disc: cacheLsz bound */
277#define PCI_BURST_DIS BIT_9 /* Burst Disable */
278#define PCI_DIS_PCI_CLK BIT_8 /* Disable PCI clock driving */
279#define PCI_SKEW_DAS (0xfL<<4) /* Bit 7.. 4: Skew Ctrl, DAS Ext */
280#define PCI_SKEW_BASE 0xfL /* Bit 3.. 0: Skew Ctrl, Base */
281
282
283/* PCI_OUR_REG_2 32 bit Our Register 2 */
284#define PCI_VPD_WR_THR (0xffL<<24) /* Bit 31..24: VPD Write Threshold */
285#define PCI_DEV_SEL (0x7fL<<17) /* Bit 23..17: EEPROM Device Select */
286#define PCI_VPD_ROM_SZ (7L<<14) /* Bit 16..14: VPD ROM Size */
287 /* Bit 13..12: reserved */
288#define PCI_PATCH_DIR (0xfL<<8) /* Bit 11.. 8: Ext Patches dir 3..0 */
289#define PCI_PATCH_DIR_3 BIT_11
290#define PCI_PATCH_DIR_2 BIT_10
291#define PCI_PATCH_DIR_1 BIT_9
292#define PCI_PATCH_DIR_0 BIT_8
293#define PCI_EXT_PATCHS (0xfL<<4) /* Bit 7.. 4: Extended Patches 3..0 */
294#define PCI_EXT_PATCH_3 BIT_7
295#define PCI_EXT_PATCH_2 BIT_6
296#define PCI_EXT_PATCH_1 BIT_5
297#define PCI_EXT_PATCH_0 BIT_4
298#define PCI_EN_DUMMY_RD BIT_3 /* Enable Dummy Read */
299#define PCI_REV_DESC BIT_2 /* Reverse Desc. Bytes */
300 /* Bit 1: reserved */
301#define PCI_USEDATA64 BIT_0 /* Use 64Bit Data bus ext */
302
303
304/* Power Management Region */
305/* PCI_PM_CAP_REG 16 bit Power Management Capabilities */
306#define PCI_PME_SUP_MSK (0x1f<<11) /* Bit 15..11: PM Event Support Mask */
307#define PCI_PME_D3C_SUP BIT_15S /* PME from D3cold Support (if Vaux) */
308#define PCI_PME_D3H_SUP BIT_14S /* PME from D3hot Support */
309#define PCI_PME_D2_SUP BIT_13S /* PME from D2 Support */
310#define PCI_PME_D1_SUP BIT_12S /* PME from D1 Support */
311#define PCI_PME_D0_SUP BIT_11S /* PME from D0 Support */
312#define PCI_PM_D2_SUP BIT_10S /* D2 Support in 33 MHz mode */
313#define PCI_PM_D1_SUP BIT_9S /* D1 Support */
314 /* Bit 8.. 6: reserved */
315#define PCI_PM_DSI BIT_5S /* Device Specific Initialization */
316#define PCI_PM_APS BIT_4S /* Auxialiary Power Source */
317#define PCI_PME_CLOCK BIT_3S /* PM Event Clock */
318#define PCI_PM_VER_MSK 7 /* Bit 2.. 0: PM PCI Spec. version */
319
320/* PCI_PM_CTL_STS 16 bit Power Management Control/Status */
321#define PCI_PME_STATUS BIT_15S /* PME Status (YUKON only) */
322#define PCI_PM_DAT_SCL (3<<13) /* Bit 14..13: Data Reg. scaling factor */
323#define PCI_PM_DAT_SEL (0xf<<9) /* Bit 12.. 9: PM data selector field */
324#define PCI_PME_EN BIT_8S /* Enable PME# generation (YUKON only) */
325 /* Bit 7.. 2: reserved */
326#define PCI_PM_STATE_MSK 3 /* Bit 1.. 0: Power Management State */
327
328#define PCI_PM_STATE_D0 0 /* D0: Operational (default) */
329#define PCI_PM_STATE_D1 1 /* D1: (YUKON only) */
330#define PCI_PM_STATE_D2 2 /* D2: (YUKON only) */
331#define PCI_PM_STATE_D3 3 /* D3: HOT, Power Down and Reset */
332
333/* VPD Region */
334/* PCI_VPD_ADR_REG 16 bit VPD Address Register */
335#define PCI_VPD_FLAG BIT_15S /* starts VPD rd/wr cycle */
336#define PCI_VPD_ADR_MSK 0x7fffL /* Bit 14.. 0: VPD address mask */
337
338/* Control Register File (Address Map) */
339
340/*
341 * Bank 0
342 */
343#define B0_RAP 0x0000 /* 8 bit Register Address Port */
344 /* 0x0001 - 0x0003: reserved */
345#define B0_CTST 0x0004 /* 16 bit Control/Status register */
346#define B0_LED 0x0006 /* 8 Bit LED register */
347#define B0_POWER_CTRL 0x0007 /* 8 Bit Power Control reg (YUKON only) */
348#define B0_ISRC 0x0008 /* 32 bit Interrupt Source Register */
349#define B0_IMSK 0x000c /* 32 bit Interrupt Mask Register */
350#define B0_HWE_ISRC 0x0010 /* 32 bit HW Error Interrupt Src Reg */
351#define B0_HWE_IMSK 0x0014 /* 32 bit HW Error Interrupt Mask Reg */
352#define B0_SP_ISRC 0x0018 /* 32 bit Special Interrupt Source Reg */
353 /* 0x001c: reserved */
354
355/* B0 XMAC 1 registers (GENESIS only) */
356#define B0_XM1_IMSK 0x0020 /* 16 bit r/w XMAC 1 Interrupt Mask Register*/
357 /* 0x0022 - 0x0027: reserved */
358#define B0_XM1_ISRC 0x0028 /* 16 bit ro XMAC 1 Interrupt Status Reg */
359 /* 0x002a - 0x002f: reserved */
360#define B0_XM1_PHY_ADDR 0x0030 /* 16 bit r/w XMAC 1 PHY Address Register */
361 /* 0x0032 - 0x0033: reserved */
362#define B0_XM1_PHY_DATA 0x0034 /* 16 bit r/w XMAC 1 PHY Data Register */
363 /* 0x0036 - 0x003f: reserved */
364
365/* B0 XMAC 2 registers (GENESIS only) */
366#define B0_XM2_IMSK 0x0040 /* 16 bit r/w XMAC 2 Interrupt Mask Register*/
367 /* 0x0042 - 0x0047: reserved */
368#define B0_XM2_ISRC 0x0048 /* 16 bit ro XMAC 2 Interrupt Status Reg */
369 /* 0x004a - 0x004f: reserved */
370#define B0_XM2_PHY_ADDR 0x0050 /* 16 bit r/w XMAC 2 PHY Address Register */
371 /* 0x0052 - 0x0053: reserved */
372#define B0_XM2_PHY_DATA 0x0054 /* 16 bit r/w XMAC 2 PHY Data Register */
373 /* 0x0056 - 0x005f: reserved */
374
375/* BMU Control Status Registers */
376#define B0_R1_CSR 0x0060 /* 32 bit BMU Ctrl/Stat Rx Queue 1 */
377#define B0_R2_CSR 0x0064 /* 32 bit BMU Ctrl/Stat Rx Queue 2 */
378#define B0_XS1_CSR 0x0068 /* 32 bit BMU Ctrl/Stat Sync Tx Queue 1 */
379#define B0_XA1_CSR 0x006c /* 32 bit BMU Ctrl/Stat Async Tx Queue 1*/
380#define B0_XS2_CSR 0x0070 /* 32 bit BMU Ctrl/Stat Sync Tx Queue 2 */
381#define B0_XA2_CSR 0x0074 /* 32 bit BMU Ctrl/Stat Async Tx Queue 2*/
382 /* 0x0078 - 0x007f: reserved */
383
384/*
385 * Bank 1
386 * - completely empty (this is the RAP Block window)
387 * Note: if RAP = 1 this page is reserved
388 */
389
390/*
391 * Bank 2
392 */
393/* NA reg = 48 bit Network Address Register, 3x16 or 8x8 bit readable */
394#define B2_MAC_1 0x0100 /* NA reg MAC Address 1 */
395 /* 0x0106 - 0x0107: reserved */
396#define B2_MAC_2 0x0108 /* NA reg MAC Address 2 */
397 /* 0x010e - 0x010f: reserved */
398#define B2_MAC_3 0x0110 /* NA reg MAC Address 3 */
399 /* 0x0116 - 0x0117: reserved */
400#define B2_CONN_TYP 0x0118 /* 8 bit Connector type */
401#define B2_PMD_TYP 0x0119 /* 8 bit PMD type */
402#define B2_MAC_CFG 0x011a /* 8 bit MAC Configuration / Chip Revision */
403#define B2_CHIP_ID 0x011b /* 8 bit Chip Identification Number */
404 /* Eprom registers are currently of no use */
405#define B2_E_0 0x011c /* 8 bit EPROM Byte 0 (ext. SRAM size */
406#define B2_E_1 0x011d /* 8 bit EPROM Byte 1 (PHY type) */
407#define B2_E_2 0x011e /* 8 bit EPROM Byte 2 */
408#define B2_E_3 0x011f /* 8 bit EPROM Byte 3 */
409#define B2_FAR 0x0120 /* 32 bit Flash-Prom Addr Reg/Cnt */
410#define B2_FDP 0x0124 /* 8 bit Flash-Prom Data Port */
411 /* 0x0125 - 0x0127: reserved */
412#define B2_LD_CTRL 0x0128 /* 8 bit EPROM loader control register */
413#define B2_LD_TEST 0x0129 /* 8 bit EPROM loader test register */
414 /* 0x012a - 0x012f: reserved */
415#define B2_TI_INI 0x0130 /* 32 bit Timer Init Value */
416#define B2_TI_VAL 0x0134 /* 32 bit Timer Value */
417#define B2_TI_CTRL 0x0138 /* 8 bit Timer Control */
418#define B2_TI_TEST 0x0139 /* 8 Bit Timer Test */
419 /* 0x013a - 0x013f: reserved */
420#define B2_IRQM_INI 0x0140 /* 32 bit IRQ Moderation Timer Init Reg.*/
421#define B2_IRQM_VAL 0x0144 /* 32 bit IRQ Moderation Timer Value */
422#define B2_IRQM_CTRL 0x0148 /* 8 bit IRQ Moderation Timer Control */
423#define B2_IRQM_TEST 0x0149 /* 8 bit IRQ Moderation Timer Test */
424#define B2_IRQM_MSK 0x014c /* 32 bit IRQ Moderation Mask */
425#define B2_IRQM_HWE_MSK 0x0150 /* 32 bit IRQ Moderation HW Error Mask */
426 /* 0x0154 - 0x0157: reserved */
427#define B2_TST_CTRL1 0x0158 /* 8 bit Test Control Register 1 */
428#define B2_TST_CTRL2 0x0159 /* 8 bit Test Control Register 2 */
429 /* 0x015a - 0x015b: reserved */
430#define B2_GP_IO 0x015c /* 32 bit General Purpose I/O Register */
431#define B2_I2C_CTRL 0x0160 /* 32 bit I2C HW Control Register */
432#define B2_I2C_DATA 0x0164 /* 32 bit I2C HW Data Register */
433#define B2_I2C_IRQ 0x0168 /* 32 bit I2C HW IRQ Register */
434#define B2_I2C_SW 0x016c /* 32 bit I2C SW Port Register */
435
436/* Blink Source Counter (GENESIS only) */
437#define B2_BSC_INI 0x0170 /* 32 bit Blink Source Counter Init Val */
438#define B2_BSC_VAL 0x0174 /* 32 bit Blink Source Counter Value */
439#define B2_BSC_CTRL 0x0178 /* 8 bit Blink Source Counter Control */
440#define B2_BSC_STAT 0x0179 /* 8 bit Blink Source Counter Status */
441#define B2_BSC_TST 0x017a /* 16 bit Blink Source Counter Test Reg */
442 /* 0x017c - 0x017f: reserved */
443
444/*
445 * Bank 3
446 */
447/* RAM Random Registers */
448#define B3_RAM_ADDR 0x0180 /* 32 bit RAM Address, to read or write */
449#define B3_RAM_DATA_LO 0x0184 /* 32 bit RAM Data Word (low dWord) */
450#define B3_RAM_DATA_HI 0x0188 /* 32 bit RAM Data Word (high dWord) */
451 /* 0x018c - 0x018f: reserved */
452
453/* RAM Interface Registers */
454/*
455 * The HW-Spec. calls this registers Timeout Value 0..11. But this names are
456 * not usable in SW. Please notice these are NOT real timeouts, these are
457 * the number of qWords transferred continuously.
458 */
459#define B3_RI_WTO_R1 0x0190 /* 8 bit WR Timeout Queue R1 (TO0) */
460#define B3_RI_WTO_XA1 0x0191 /* 8 bit WR Timeout Queue XA1 (TO1) */
461#define B3_RI_WTO_XS1 0x0192 /* 8 bit WR Timeout Queue XS1 (TO2) */
462#define B3_RI_RTO_R1 0x0193 /* 8 bit RD Timeout Queue R1 (TO3) */
463#define B3_RI_RTO_XA1 0x0194 /* 8 bit RD Timeout Queue XA1 (TO4) */
464#define B3_RI_RTO_XS1 0x0195 /* 8 bit RD Timeout Queue XS1 (TO5) */
465#define B3_RI_WTO_R2 0x0196 /* 8 bit WR Timeout Queue R2 (TO6) */
466#define B3_RI_WTO_XA2 0x0197 /* 8 bit WR Timeout Queue XA2 (TO7) */
467#define B3_RI_WTO_XS2 0x0198 /* 8 bit WR Timeout Queue XS2 (TO8) */
468#define B3_RI_RTO_R2 0x0199 /* 8 bit RD Timeout Queue R2 (TO9) */
469#define B3_RI_RTO_XA2 0x019a /* 8 bit RD Timeout Queue XA2 (TO10)*/
470#define B3_RI_RTO_XS2 0x019b /* 8 bit RD Timeout Queue XS2 (TO11)*/
471#define B3_RI_TO_VAL 0x019c /* 8 bit Current Timeout Count Val */
472 /* 0x019d - 0x019f: reserved */
473#define B3_RI_CTRL 0x01a0 /* 16 bit RAM Interface Control Register */
474#define B3_RI_TEST 0x01a2 /* 8 bit RAM Interface Test Register */
475 /* 0x01a3 - 0x01af: reserved */
476
477/* MAC Arbiter Registers (GENESIS only) */
478/* these are the no. of qWord transferred continuously and NOT real timeouts */
479#define B3_MA_TOINI_RX1 0x01b0 /* 8 bit Timeout Init Val Rx Path MAC 1 */
480#define B3_MA_TOINI_RX2 0x01b1 /* 8 bit Timeout Init Val Rx Path MAC 2 */
481#define B3_MA_TOINI_TX1 0x01b2 /* 8 bit Timeout Init Val Tx Path MAC 1 */
482#define B3_MA_TOINI_TX2 0x01b3 /* 8 bit Timeout Init Val Tx Path MAC 2 */
483#define B3_MA_TOVAL_RX1 0x01b4 /* 8 bit Timeout Value Rx Path MAC 1 */
484#define B3_MA_TOVAL_RX2 0x01b5 /* 8 bit Timeout Value Rx Path MAC 1 */
485#define B3_MA_TOVAL_TX1 0x01b6 /* 8 bit Timeout Value Tx Path MAC 2 */
486#define B3_MA_TOVAL_TX2 0x01b7 /* 8 bit Timeout Value Tx Path MAC 2 */
487#define B3_MA_TO_CTRL 0x01b8 /* 16 bit MAC Arbiter Timeout Ctrl Reg */
488#define B3_MA_TO_TEST 0x01ba /* 16 bit MAC Arbiter Timeout Test Reg */
489 /* 0x01bc - 0x01bf: reserved */
490#define B3_MA_RCINI_RX1 0x01c0 /* 8 bit Recovery Init Val Rx Path MAC 1 */
491#define B3_MA_RCINI_RX2 0x01c1 /* 8 bit Recovery Init Val Rx Path MAC 2 */
492#define B3_MA_RCINI_TX1 0x01c2 /* 8 bit Recovery Init Val Tx Path MAC 1 */
493#define B3_MA_RCINI_TX2 0x01c3 /* 8 bit Recovery Init Val Tx Path MAC 2 */
494#define B3_MA_RCVAL_RX1 0x01c4 /* 8 bit Recovery Value Rx Path MAC 1 */
495#define B3_MA_RCVAL_RX2 0x01c5 /* 8 bit Recovery Value Rx Path MAC 1 */
496#define B3_MA_RCVAL_TX1 0x01c6 /* 8 bit Recovery Value Tx Path MAC 2 */
497#define B3_MA_RCVAL_TX2 0x01c7 /* 8 bit Recovery Value Tx Path MAC 2 */
498#define B3_MA_RC_CTRL 0x01c8 /* 16 bit MAC Arbiter Recovery Ctrl Reg */
499#define B3_MA_RC_TEST 0x01ca /* 16 bit MAC Arbiter Recovery Test Reg */
500 /* 0x01cc - 0x01cf: reserved */
501
502/* Packet Arbiter Registers (GENESIS only) */
503/* these are real timeouts */
504#define B3_PA_TOINI_RX1 0x01d0 /* 16 bit Timeout Init Val Rx Path MAC 1 */
505 /* 0x01d2 - 0x01d3: reserved */
506#define B3_PA_TOINI_RX2 0x01d4 /* 16 bit Timeout Init Val Rx Path MAC 2 */
507 /* 0x01d6 - 0x01d7: reserved */
508#define B3_PA_TOINI_TX1 0x01d8 /* 16 bit Timeout Init Val Tx Path MAC 1 */
509 /* 0x01da - 0x01db: reserved */
510#define B3_PA_TOINI_TX2 0x01dc /* 16 bit Timeout Init Val Tx Path MAC 2 */
511 /* 0x01de - 0x01df: reserved */
512#define B3_PA_TOVAL_RX1 0x01e0 /* 16 bit Timeout Val Rx Path MAC 1 */
513 /* 0x01e2 - 0x01e3: reserved */
514#define B3_PA_TOVAL_RX2 0x01e4 /* 16 bit Timeout Val Rx Path MAC 2 */
515 /* 0x01e6 - 0x01e7: reserved */
516#define B3_PA_TOVAL_TX1 0x01e8 /* 16 bit Timeout Val Tx Path MAC 1 */
517 /* 0x01ea - 0x01eb: reserved */
518#define B3_PA_TOVAL_TX2 0x01ec /* 16 bit Timeout Val Tx Path MAC 2 */
519 /* 0x01ee - 0x01ef: reserved */
520#define B3_PA_CTRL 0x01f0 /* 16 bit Packet Arbiter Ctrl Register */
521#define B3_PA_TEST 0x01f2 /* 16 bit Packet Arbiter Test Register */
522 /* 0x01f4 - 0x01ff: reserved */
523
524/*
525 * Bank 4 - 5
526 */
527/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
528#define TXA_ITI_INI 0x0200 /* 32 bit Tx Arb Interval Timer Init Val*/
529#define TXA_ITI_VAL 0x0204 /* 32 bit Tx Arb Interval Timer Value */
530#define TXA_LIM_INI 0x0208 /* 32 bit Tx Arb Limit Counter Init Val */
531#define TXA_LIM_VAL 0x020c /* 32 bit Tx Arb Limit Counter Value */
532#define TXA_CTRL 0x0210 /* 8 bit Tx Arbiter Control Register */
533#define TXA_TEST 0x0211 /* 8 bit Tx Arbiter Test Register */
534#define TXA_STAT 0x0212 /* 8 bit Tx Arbiter Status Register */
535 /* 0x0213 - 0x027f: reserved */
536 /* 0x0280 - 0x0292: MAC 2 */
537 /* 0x0213 - 0x027f: reserved */
538
539/*
540 * Bank 6
541 */
542/* External registers (GENESIS only) */
543#define B6_EXT_REG 0x0300
544
545/*
546 * Bank 7
547 */
548/* This is a copy of the Configuration register file (lower half) */
549#define B7_CFG_SPC 0x0380
550
551/*
552 * Bank 8 - 15
553 */
554/* Receive and Transmit Queue Registers, use Q_ADDR() to access */
555#define B8_Q_REGS 0x0400
556
557/* Queue Register Offsets, use Q_ADDR() to access */
558#define Q_D 0x00 /* 8*32 bit Current Descriptor */
559#define Q_DA_L 0x20 /* 32 bit Current Descriptor Address Low dWord */
560#define Q_DA_H 0x24 /* 32 bit Current Descriptor Address High dWord */
561#define Q_AC_L 0x28 /* 32 bit Current Address Counter Low dWord */
562#define Q_AC_H 0x2c /* 32 bit Current Address Counter High dWord */
563#define Q_BC 0x30 /* 32 bit Current Byte Counter */
564#define Q_CSR 0x34 /* 32 bit BMU Control/Status Register */
565#define Q_F 0x38 /* 32 bit Flag Register */
566#define Q_T1 0x3c /* 32 bit Test Register 1 */
567#define Q_T1_TR 0x3c /* 8 bit Test Register 1 Transfer SM */
568#define Q_T1_WR 0x3d /* 8 bit Test Register 1 Write Descriptor SM */
569#define Q_T1_RD 0x3e /* 8 bit Test Register 1 Read Descriptor SM */
570#define Q_T1_SV 0x3f /* 8 bit Test Register 1 Supervisor SM */
571#define Q_T2 0x40 /* 32 bit Test Register 2 */
572#define Q_T3 0x44 /* 32 bit Test Register 3 */
573 /* 0x48 - 0x7f: reserved */
574
575/*
576 * Bank 16 - 23
577 */
578/* RAM Buffer Registers */
579#define B16_RAM_REGS 0x0800
580
581/* RAM Buffer Register Offsets, use RB_ADDR() to access */
582#define RB_START 0x00 /* 32 bit RAM Buffer Start Address */
583#define RB_END 0x04 /* 32 bit RAM Buffer End Address */
584#define RB_WP 0x08 /* 32 bit RAM Buffer Write Pointer */
585#define RB_RP 0x0c /* 32 bit RAM Buffer Read Pointer */
586#define RB_RX_UTPP 0x10 /* 32 bit Rx Upper Threshold, Pause Pack */
587#define RB_RX_LTPP 0x14 /* 32 bit Rx Lower Threshold, Pause Pack */
588#define RB_RX_UTHP 0x18 /* 32 bit Rx Upper Threshold, High Prio */
589#define RB_RX_LTHP 0x1c /* 32 bit Rx Lower Threshold, High Prio */
590 /* 0x10 - 0x1f: reserved at Tx RAM Buffer Registers */
591#define RB_PC 0x20 /* 32 bit RAM Buffer Packet Counter */
592#define RB_LEV 0x24 /* 32 bit RAM Buffer Level Register */
593#define RB_CTRL 0x28 /* 8 bit RAM Buffer Control Register */
594#define RB_TST1 0x29 /* 8 bit RAM Buffer Test Register 1 */
595#define RB_TST2 0x2A /* 8 bit RAM Buffer Test Register 2 */
596 /* 0x2c - 0x7f: reserved */
597
598/*
599 * Bank 24
600 */
601/*
602 * Receive MAC FIFO, Receive LED, and Link_Sync regs (GENESIS only)
603 * use MR_ADDR() to access
604 */
605#define RX_MFF_EA 0x0c00 /* 32 bit Receive MAC FIFO End Address */
606#define RX_MFF_WP 0x0c04 /* 32 bit Receive MAC FIFO Write Pointer */
607 /* 0x0c08 - 0x0c0b: reserved */
608#define RX_MFF_RP 0x0c0c /* 32 bit Receive MAC FIFO Read Pointer */
609#define RX_MFF_PC 0x0c10 /* 32 bit Receive MAC FIFO Packet Cnt */
610#define RX_MFF_LEV 0x0c14 /* 32 bit Receive MAC FIFO Level */
611#define RX_MFF_CTRL1 0x0c18 /* 16 bit Receive MAC FIFO Control Reg 1*/
612#define RX_MFF_STAT_TO 0x0c1a /* 8 bit Receive MAC Status Timeout */
613#define RX_MFF_TIST_TO 0x0c1b /* 8 bit Receive MAC Time Stamp Timeout */
614#define RX_MFF_CTRL2 0x0c1c /* 8 bit Receive MAC FIFO Control Reg 2*/
615#define RX_MFF_TST1 0x0c1d /* 8 bit Receive MAC FIFO Test Reg 1 */
616#define RX_MFF_TST2 0x0c1e /* 8 bit Receive MAC FIFO Test Reg 2 */
617 /* 0x0c1f: reserved */
618#define RX_LED_INI 0x0c20 /* 32 bit Receive LED Cnt Init Value */
619#define RX_LED_VAL 0x0c24 /* 32 bit Receive LED Cnt Current Value */
620#define RX_LED_CTRL 0x0c28 /* 8 bit Receive LED Cnt Control Reg */
621#define RX_LED_TST 0x0c29 /* 8 bit Receive LED Cnt Test Register */
622 /* 0x0c2a - 0x0c2f: reserved */
623#define LNK_SYNC_INI 0x0c30 /* 32 bit Link Sync Cnt Init Value */
624#define LNK_SYNC_VAL 0x0c34 /* 32 bit Link Sync Cnt Current Value */
625#define LNK_SYNC_CTRL 0x0c38 /* 8 bit Link Sync Cnt Control Register */
626#define LNK_SYNC_TST 0x0c39 /* 8 bit Link Sync Cnt Test Register */
627 /* 0x0c3a - 0x0c3b: reserved */
628#define LNK_LED_REG 0x0c3c /* 8 bit Link LED Register */
629 /* 0x0c3d - 0x0c3f: reserved */
630
631/* Receive GMAC FIFO (YUKON only), use MR_ADDR() to access */
632#define RX_GMF_EA 0x0c40 /* 32 bit Rx GMAC FIFO End Address */
633#define RX_GMF_AF_THR 0x0c44 /* 32 bit Rx GMAC FIFO Almost Full Thresh. */
634#define RX_GMF_CTRL_T 0x0c48 /* 32 bit Rx GMAC FIFO Control/Test */
635#define RX_GMF_FL_MSK 0x0c4c /* 32 bit Rx GMAC FIFO Flush Mask */
636#define RX_GMF_FL_THR 0x0c50 /* 32 bit Rx GMAC FIFO Flush Threshold */
637 /* 0x0c54 - 0x0c5f: reserved */
638#define RX_GMF_WP 0x0c60 /* 32 bit Rx GMAC FIFO Write Pointer */
639 /* 0x0c64 - 0x0c67: reserved */
640#define RX_GMF_WLEV 0x0c68 /* 32 bit Rx GMAC FIFO Write Level */
641 /* 0x0c6c - 0x0c6f: reserved */
642#define RX_GMF_RP 0x0c70 /* 32 bit Rx GMAC FIFO Read Pointer */
643 /* 0x0c74 - 0x0c77: reserved */
644#define RX_GMF_RLEV 0x0c78 /* 32 bit Rx GMAC FIFO Read Level */
645 /* 0x0c7c - 0x0c7f: reserved */
646
647/*
648 * Bank 25
649 */
650 /* 0x0c80 - 0x0cbf: MAC 2 */
651 /* 0x0cc0 - 0x0cff: reserved */
652
653/*
654 * Bank 26
655 */
656/*
657 * Transmit MAC FIFO and Transmit LED Registers (GENESIS only),
658 * use MR_ADDR() to access
659 */
660#define TX_MFF_EA 0x0d00 /* 32 bit Transmit MAC FIFO End Address */
661#define TX_MFF_WP 0x0d04 /* 32 bit Transmit MAC FIFO WR Pointer */
662#define TX_MFF_WSP 0x0d08 /* 32 bit Transmit MAC FIFO WR Shadow Ptr */
663#define TX_MFF_RP 0x0d0c /* 32 bit Transmit MAC FIFO RD Pointer */
664#define TX_MFF_PC 0x0d10 /* 32 bit Transmit MAC FIFO Packet Cnt */
665#define TX_MFF_LEV 0x0d14 /* 32 bit Transmit MAC FIFO Level */
666#define TX_MFF_CTRL1 0x0d18 /* 16 bit Transmit MAC FIFO Ctrl Reg 1 */
667#define TX_MFF_WAF 0x0d1a /* 8 bit Transmit MAC Wait after flush */
668 /* 0x0c1b: reserved */
669#define TX_MFF_CTRL2 0x0d1c /* 8 bit Transmit MAC FIFO Ctrl Reg 2 */
670#define TX_MFF_TST1 0x0d1d /* 8 bit Transmit MAC FIFO Test Reg 1 */
671#define TX_MFF_TST2 0x0d1e /* 8 bit Transmit MAC FIFO Test Reg 2 */
672 /* 0x0d1f: reserved */
673#define TX_LED_INI 0x0d20 /* 32 bit Transmit LED Cnt Init Value */
674#define TX_LED_VAL 0x0d24 /* 32 bit Transmit LED Cnt Current Val */
675#define TX_LED_CTRL 0x0d28 /* 8 bit Transmit LED Cnt Control Reg */
676#define TX_LED_TST 0x0d29 /* 8 bit Transmit LED Cnt Test Reg */
677 /* 0x0d2a - 0x0d3f: reserved */
678
679/* Transmit GMAC FIFO (YUKON only), use MR_ADDR() to access */
680#define TX_GMF_EA 0x0d40 /* 32 bit Tx GMAC FIFO End Address */
681#define TX_GMF_AE_THR 0x0d44 /* 32 bit Tx GMAC FIFO Almost Empty Thresh.*/
682#define TX_GMF_CTRL_T 0x0d48 /* 32 bit Tx GMAC FIFO Control/Test */
683 /* 0x0d4c - 0x0d5f: reserved */
684#define TX_GMF_WP 0x0d60 /* 32 bit Tx GMAC FIFO Write Pointer */
685#define TX_GMF_WSP 0x0d64 /* 32 bit Tx GMAC FIFO Write Shadow Ptr. */
686#define TX_GMF_WLEV 0x0d68 /* 32 bit Tx GMAC FIFO Write Level */
687 /* 0x0d6c - 0x0d6f: reserved */
688#define TX_GMF_RP 0x0d70 /* 32 bit Tx GMAC FIFO Read Pointer */
689#define TX_GMF_RSTP 0x0d74 /* 32 bit Tx GMAC FIFO Restart Pointer */
690#define TX_GMF_RLEV 0x0d78 /* 32 bit Tx GMAC FIFO Read Level */
691 /* 0x0d7c - 0x0d7f: reserved */
692
693/*
694 * Bank 27
695 */
696 /* 0x0d80 - 0x0dbf: MAC 2 */
697 /* 0x0daa - 0x0dff: reserved */
698
699/*
700 * Bank 28
701 */
702/* Descriptor Poll Timer Registers */
703#define B28_DPT_INI 0x0e00 /* 24 bit Descriptor Poll Timer Init Val */
704#define B28_DPT_VAL 0x0e04 /* 24 bit Descriptor Poll Timer Curr Val */
705#define B28_DPT_CTRL 0x0e08 /* 8 bit Descriptor Poll Timer Ctrl Reg */
706 /* 0x0e09: reserved */
707#define B28_DPT_TST 0x0e0a /* 8 bit Descriptor Poll Timer Test Reg */
708 /* 0x0e0b: reserved */
709
710/* Time Stamp Timer Registers (YUKON only) */
711 /* 0x0e10: reserved */
712#define GMAC_TI_ST_VAL 0x0e14 /* 32 bit Time Stamp Timer Curr Val */
713#define GMAC_TI_ST_CTRL 0x0e18 /* 8 bit Time Stamp Timer Ctrl Reg */
714 /* 0x0e19: reserved */
715#define GMAC_TI_ST_TST 0x0e1a /* 8 bit Time Stamp Timer Test Reg */
716 /* 0x0e1b - 0x0e7f: reserved */
717
718/*
719 * Bank 29
720 */
721 /* 0x0e80 - 0x0efc: reserved */
722
723/*
724 * Bank 30
725 */
726/* GMAC and GPHY Control Registers (YUKON only) */
727#define GMAC_CTRL 0x0f00 /* 32 bit GMAC Control Reg */
728#define GPHY_CTRL 0x0f04 /* 32 bit GPHY Control Reg */
729#define GMAC_IRQ_SRC 0x0f08 /* 8 bit GMAC Interrupt Source Reg */
730 /* 0x0f09 - 0x0f0b: reserved */
731#define GMAC_IRQ_MSK 0x0f0c /* 8 bit GMAC Interrupt Mask Reg */
732 /* 0x0f0d - 0x0f0f: reserved */
733#define GMAC_LINK_CTRL 0x0f10 /* 16 bit Link Control Reg */
734 /* 0x0f14 - 0x0f1f: reserved */
735
736/* Wake-up Frame Pattern Match Control Registers (YUKON only) */
737
738#define WOL_REG_OFFS 0x20 /* HW-Bug: Address is + 0x20 against spec. */
739
740#define WOL_CTRL_STAT 0x0f20 /* 16 bit WOL Control/Status Reg */
741#define WOL_MATCH_CTL 0x0f22 /* 8 bit WOL Match Control Reg */
742#define WOL_MATCH_RES 0x0f23 /* 8 bit WOL Match Result Reg */
743#define WOL_MAC_ADDR_LO 0x0f24 /* 32 bit WOL MAC Address Low */
744#define WOL_MAC_ADDR_HI 0x0f28 /* 16 bit WOL MAC Address High */
745#define WOL_PATT_RPTR 0x0f2c /* 8 bit WOL Pattern Read Ptr */
746
747/* use this macro to access above registers */
748#define WOL_REG(Reg) ((Reg) + (pAC->GIni.GIWolOffs))
749
750
751/* WOL Pattern Length Registers (YUKON only) */
752
753#define WOL_PATT_LEN_LO 0x0f30 /* 32 bit WOL Pattern Length 3..0 */
754#define WOL_PATT_LEN_HI 0x0f34 /* 24 bit WOL Pattern Length 6..4 */
755
756/* WOL Pattern Counter Registers (YUKON only) */
757
758#define WOL_PATT_CNT_0 0x0f38 /* 32 bit WOL Pattern Counter 3..0 */
759#define WOL_PATT_CNT_4 0x0f3c /* 24 bit WOL Pattern Counter 6..4 */
760 /* 0x0f40 - 0x0f7f: reserved */
761
762/*
763 * Bank 31
764 */
765/* 0x0f80 - 0x0fff: reserved */
766
767/*
768 * Bank 32 - 33
769 */
770#define WOL_PATT_RAM_1 0x1000 /* WOL Pattern RAM Link 1 */
771
772/*
773 * Bank 0x22 - 0x3f
774 */
775/* 0x1100 - 0x1fff: reserved */
776
777/*
778 * Bank 0x40 - 0x4f
779 */
780#define BASE_XMAC_1 0x2000 /* XMAC 1 registers */
781
782/*
783 * Bank 0x50 - 0x5f
784 */
785
786#define BASE_GMAC_1 0x2800 /* GMAC 1 registers */
787
788/*
789 * Bank 0x60 - 0x6f
790 */
791#define BASE_XMAC_2 0x3000 /* XMAC 2 registers */
792
793/*
794 * Bank 0x70 - 0x7f
795 */
796#define BASE_GMAC_2 0x3800 /* GMAC 2 registers */
797
798/*
799 * Control Register Bit Definitions:
800 */
801/* B0_RAP 8 bit Register Address Port */
802 /* Bit 7: reserved */
803#define RAP_RAP 0x3f /* Bit 6..0: 0 = block 0,..,6f = block 6f */
804
805/* B0_CTST 16 bit Control/Status register */
806 /* Bit 15..14: reserved */
807#define CS_CLK_RUN_HOT BIT_13S /* CLK_RUN hot m. (YUKON-Lite only) */
808#define CS_CLK_RUN_RST BIT_12S /* CLK_RUN reset (YUKON-Lite only) */
809#define CS_CLK_RUN_ENA BIT_11S /* CLK_RUN enable (YUKON-Lite only) */
810#define CS_VAUX_AVAIL BIT_10S /* VAUX available (YUKON only) */
811#define CS_BUS_CLOCK BIT_9S /* Bus Clock 0/1 = 33/66 MHz */
812#define CS_BUS_SLOT_SZ BIT_8S /* Slot Size 0/1 = 32/64 bit slot */
813#define CS_ST_SW_IRQ BIT_7S /* Set IRQ SW Request */
814#define CS_CL_SW_IRQ BIT_6S /* Clear IRQ SW Request */
815#define CS_STOP_DONE BIT_5S /* Stop Master is finished */
816#define CS_STOP_MAST BIT_4S /* Command Bit to stop the master */
817#define CS_MRST_CLR BIT_3S /* Clear Master reset */
818#define CS_MRST_SET BIT_2S /* Set Master reset */
819#define CS_RST_CLR BIT_1S /* Clear Software reset */
820#define CS_RST_SET BIT_0S /* Set Software reset */
821
822/* B0_LED 8 Bit LED register */
823 /* Bit 7.. 2: reserved */
824#define LED_STAT_ON BIT_1S /* Status LED on */
825#define LED_STAT_OFF BIT_0S /* Status LED off */
826
827/* B0_POWER_CTRL 8 Bit Power Control reg (YUKON only) */
828#define PC_VAUX_ENA BIT_7 /* Switch VAUX Enable */
829#define PC_VAUX_DIS BIT_6 /* Switch VAUX Disable */
830#define PC_VCC_ENA BIT_5 /* Switch VCC Enable */
831#define PC_VCC_DIS BIT_4 /* Switch VCC Disable */
832#define PC_VAUX_ON BIT_3 /* Switch VAUX On */
833#define PC_VAUX_OFF BIT_2 /* Switch VAUX Off */
834#define PC_VCC_ON BIT_1 /* Switch VCC On */
835#define PC_VCC_OFF BIT_0 /* Switch VCC Off */
836
837/* B0_ISRC 32 bit Interrupt Source Register */
838/* B0_IMSK 32 bit Interrupt Mask Register */
839/* B0_SP_ISRC 32 bit Special Interrupt Source Reg */
840/* B2_IRQM_MSK 32 bit IRQ Moderation Mask */
841#define IS_ALL_MSK 0xbfffffffUL /* All Interrupt bits */
842#define IS_HW_ERR BIT_31 /* Interrupt HW Error */
843 /* Bit 30: reserved */
844#define IS_PA_TO_RX1 BIT_29 /* Packet Arb Timeout Rx1 */
845#define IS_PA_TO_RX2 BIT_28 /* Packet Arb Timeout Rx2 */
846#define IS_PA_TO_TX1 BIT_27 /* Packet Arb Timeout Tx1 */
847#define IS_PA_TO_TX2 BIT_26 /* Packet Arb Timeout Tx2 */
848#define IS_I2C_READY BIT_25 /* IRQ on end of I2C Tx */
849#define IS_IRQ_SW BIT_24 /* SW forced IRQ */
850#define IS_EXT_REG BIT_23 /* IRQ from LM80 or PHY (GENESIS only) */
851 /* IRQ from PHY (YUKON only) */
852#define IS_TIMINT BIT_22 /* IRQ from Timer */
853#define IS_MAC1 BIT_21 /* IRQ from MAC 1 */
854#define IS_LNK_SYNC_M1 BIT_20 /* Link Sync Cnt wrap MAC 1 */
855#define IS_MAC2 BIT_19 /* IRQ from MAC 2 */
856#define IS_LNK_SYNC_M2 BIT_18 /* Link Sync Cnt wrap MAC 2 */
857/* Receive Queue 1 */
858#define IS_R1_B BIT_17 /* Q_R1 End of Buffer */
859#define IS_R1_F BIT_16 /* Q_R1 End of Frame */
860#define IS_R1_C BIT_15 /* Q_R1 Encoding Error */
861/* Receive Queue 2 */
862#define IS_R2_B BIT_14 /* Q_R2 End of Buffer */
863#define IS_R2_F BIT_13 /* Q_R2 End of Frame */
864#define IS_R2_C BIT_12 /* Q_R2 Encoding Error */
865/* Synchronous Transmit Queue 1 */
866#define IS_XS1_B BIT_11 /* Q_XS1 End of Buffer */
867#define IS_XS1_F BIT_10 /* Q_XS1 End of Frame */
868#define IS_XS1_C BIT_9 /* Q_XS1 Encoding Error */
869/* Asynchronous Transmit Queue 1 */
870#define IS_XA1_B BIT_8 /* Q_XA1 End of Buffer */
871#define IS_XA1_F BIT_7 /* Q_XA1 End of Frame */
872#define IS_XA1_C BIT_6 /* Q_XA1 Encoding Error */
873/* Synchronous Transmit Queue 2 */
874#define IS_XS2_B BIT_5 /* Q_XS2 End of Buffer */
875#define IS_XS2_F BIT_4 /* Q_XS2 End of Frame */
876#define IS_XS2_C BIT_3 /* Q_XS2 Encoding Error */
877/* Asynchronous Transmit Queue 2 */
878#define IS_XA2_B BIT_2 /* Q_XA2 End of Buffer */
879#define IS_XA2_F BIT_1 /* Q_XA2 End of Frame */
880#define IS_XA2_C BIT_0 /* Q_XA2 Encoding Error */
881
882
883/* B0_HWE_ISRC 32 bit HW Error Interrupt Src Reg */
884/* B0_HWE_IMSK 32 bit HW Error Interrupt Mask Reg */
885/* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */
886#define IS_ERR_MSK 0x00000fffL /* All Error bits */
887 /* Bit 31..14: reserved */
888#define IS_IRQ_TIST_OV BIT_13 /* Time Stamp Timer Overflow (YUKON only) */
889#define IS_IRQ_SENSOR BIT_12 /* IRQ from Sensor (YUKON only) */
890#define IS_IRQ_MST_ERR BIT_11 /* IRQ master error detected */
891#define IS_IRQ_STAT BIT_10 /* IRQ status exception */
892#define IS_NO_STAT_M1 BIT_9 /* No Rx Status from MAC 1 */
893#define IS_NO_STAT_M2 BIT_8 /* No Rx Status from MAC 2 */
894#define IS_NO_TIST_M1 BIT_7 /* No Time Stamp from MAC 1 */
895#define IS_NO_TIST_M2 BIT_6 /* No Time Stamp from MAC 2 */
896#define IS_RAM_RD_PAR BIT_5 /* RAM Read Parity Error */
897#define IS_RAM_WR_PAR BIT_4 /* RAM Write Parity Error */
898#define IS_M1_PAR_ERR BIT_3 /* MAC 1 Parity Error */
899#define IS_M2_PAR_ERR BIT_2 /* MAC 2 Parity Error */
900#define IS_R1_PAR_ERR BIT_1 /* Queue R1 Parity Error */
901#define IS_R2_PAR_ERR BIT_0 /* Queue R2 Parity Error */
902
903/* B2_CONN_TYP 8 bit Connector type */
904/* B2_PMD_TYP 8 bit PMD type */
905/* Values of connector and PMD type comply to SysKonnect internal std */
906
907/* B2_MAC_CFG 8 bit MAC Configuration / Chip Revision */
908#define CFG_CHIP_R_MSK (0xf<<4) /* Bit 7.. 4: Chip Revision */
909 /* Bit 3.. 2: reserved */
910#define CFG_DIS_M2_CLK BIT_1S /* Disable Clock for 2nd MAC */
911#define CFG_SNG_MAC BIT_0S /* MAC Config: 0=2 MACs / 1=1 MAC*/
912
913/* B2_CHIP_ID 8 bit Chip Identification Number */
914#define CHIP_ID_GENESIS 0x0a /* Chip ID for GENESIS */
915#define CHIP_ID_YUKON 0xb0 /* Chip ID for YUKON */
916#define CHIP_ID_YUKON_LITE 0xb1 /* Chip ID for YUKON-Lite (Rev. A1-A3) */
917#define CHIP_ID_YUKON_LP 0xb2 /* Chip ID for YUKON-LP */
918
919#define CHIP_REV_YU_LITE_A1 3 /* Chip Rev. for YUKON-Lite A1,A2 */
920#define CHIP_REV_YU_LITE_A3 7 /* Chip Rev. for YUKON-Lite A3 */
921
922/* B2_FAR 32 bit Flash-Prom Addr Reg/Cnt */
923#define FAR_ADDR 0x1ffffL /* Bit 16.. 0: FPROM Address mask */
924
925/* B2_LD_CTRL 8 bit EPROM loader control register */
926/* Bits are currently reserved */
927
928/* B2_LD_TEST 8 bit EPROM loader test register */
929 /* Bit 7.. 4: reserved */
930#define LD_T_ON BIT_3S /* Loader Test mode on */
931#define LD_T_OFF BIT_2S /* Loader Test mode off */
932#define LD_T_STEP BIT_1S /* Decrement FPROM addr. Counter */
933#define LD_START BIT_0S /* Start loading FPROM */
934
935/*
936 * Timer Section
937 */
938/* B2_TI_CTRL 8 bit Timer control */
939/* B2_IRQM_CTRL 8 bit IRQ Moderation Timer Control */
940 /* Bit 7.. 3: reserved */
941#define TIM_START BIT_2S /* Start Timer */
942#define TIM_STOP BIT_1S /* Stop Timer */
943#define TIM_CLR_IRQ BIT_0S /* Clear Timer IRQ (!IRQM) */
944
945/* B2_TI_TEST 8 Bit Timer Test */
946/* B2_IRQM_TEST 8 bit IRQ Moderation Timer Test */
947/* B28_DPT_TST 8 bit Descriptor Poll Timer Test Reg */
948 /* Bit 7.. 3: reserved */
949#define TIM_T_ON BIT_2S /* Test mode on */
950#define TIM_T_OFF BIT_1S /* Test mode off */
951#define TIM_T_STEP BIT_0S /* Test step */
952
953/* B28_DPT_INI 32 bit Descriptor Poll Timer Init Val */
954/* B28_DPT_VAL 32 bit Descriptor Poll Timer Curr Val */
955 /* Bit 31..24: reserved */
956#define DPT_MSK 0x00ffffffL /* Bit 23.. 0: Desc Poll Timer Bits */
957
958/* B28_DPT_CTRL 8 bit Descriptor Poll Timer Ctrl Reg */
959 /* Bit 7.. 2: reserved */
960#define DPT_START BIT_1S /* Start Descriptor Poll Timer */
961#define DPT_STOP BIT_0S /* Stop Descriptor Poll Timer */
962
963/* B2_E_3 8 bit lower 4 bits used for HW self test result */
964#define B2_E3_RES_MASK 0x0f
965
966/* B2_TST_CTRL1 8 bit Test Control Register 1 */
967#define TST_FRC_DPERR_MR BIT_7S /* force DATAPERR on MST RD */
968#define TST_FRC_DPERR_MW BIT_6S /* force DATAPERR on MST WR */
969#define TST_FRC_DPERR_TR BIT_5S /* force DATAPERR on TRG RD */
970#define TST_FRC_DPERR_TW BIT_4S /* force DATAPERR on TRG WR */
971#define TST_FRC_APERR_M BIT_3S /* force ADDRPERR on MST */
972#define TST_FRC_APERR_T BIT_2S /* force ADDRPERR on TRG */
973#define TST_CFG_WRITE_ON BIT_1S /* Enable Config Reg WR */
974#define TST_CFG_WRITE_OFF BIT_0S /* Disable Config Reg WR */
975
976/* B2_TST_CTRL2 8 bit Test Control Register 2 */
977 /* Bit 7.. 4: reserved */
978 /* force the following error on the next master read/write */
979#define TST_FRC_DPERR_MR64 BIT_3S /* DataPERR RD 64 */
980#define TST_FRC_DPERR_MW64 BIT_2S /* DataPERR WR 64 */
981#define TST_FRC_APERR_1M64 BIT_1S /* AddrPERR on 1. phase */
982#define TST_FRC_APERR_2M64 BIT_0S /* AddrPERR on 2. phase */
983
984/* B2_GP_IO 32 bit General Purpose I/O Register */
985 /* Bit 31..26: reserved */
986#define GP_DIR_9 BIT_25 /* IO_9 direct, 0=In/1=Out */
987#define GP_DIR_8 BIT_24 /* IO_8 direct, 0=In/1=Out */
988#define GP_DIR_7 BIT_23 /* IO_7 direct, 0=In/1=Out */
989#define GP_DIR_6 BIT_22 /* IO_6 direct, 0=In/1=Out */
990#define GP_DIR_5 BIT_21 /* IO_5 direct, 0=In/1=Out */
991#define GP_DIR_4 BIT_20 /* IO_4 direct, 0=In/1=Out */
992#define GP_DIR_3 BIT_19 /* IO_3 direct, 0=In/1=Out */
993#define GP_DIR_2 BIT_18 /* IO_2 direct, 0=In/1=Out */
994#define GP_DIR_1 BIT_17 /* IO_1 direct, 0=In/1=Out */
995#define GP_DIR_0 BIT_16 /* IO_0 direct, 0=In/1=Out */
996 /* Bit 15..10: reserved */
997#define GP_IO_9 BIT_9 /* IO_9 pin */
998#define GP_IO_8 BIT_8 /* IO_8 pin */
999#define GP_IO_7 BIT_7 /* IO_7 pin */
1000#define GP_IO_6 BIT_6 /* IO_6 pin */
1001#define GP_IO_5 BIT_5 /* IO_5 pin */
1002#define GP_IO_4 BIT_4 /* IO_4 pin */
1003#define GP_IO_3 BIT_3 /* IO_3 pin */
1004#define GP_IO_2 BIT_2 /* IO_2 pin */
1005#define GP_IO_1 BIT_1 /* IO_1 pin */
1006#define GP_IO_0 BIT_0 /* IO_0 pin */
1007
1008/* B2_I2C_CTRL 32 bit I2C HW Control Register */
1009#define I2C_FLAG BIT_31 /* Start read/write if WR */
1010#define I2C_ADDR (0x7fffL<<16) /* Bit 30..16: Addr to be RD/WR */
1011#define I2C_DEV_SEL (0x7fL<<9) /* Bit 15.. 9: I2C Device Select */
1012 /* Bit 8.. 5: reserved */
1013#define I2C_BURST_LEN BIT_4 /* Burst Len, 1/4 bytes */
1014#define I2C_DEV_SIZE (7<<1) /* Bit 3.. 1: I2C Device Size */
1015#define I2C_025K_DEV (0<<1) /* 0: 256 Bytes or smal. */
1016#define I2C_05K_DEV (1<<1) /* 1: 512 Bytes */
1017#define I2C_1K_DEV (2<<1) /* 2: 1024 Bytes */
1018#define I2C_2K_DEV (3<<1) /* 3: 2048 Bytes */
1019#define I2C_4K_DEV (4<<1) /* 4: 4096 Bytes */
1020#define I2C_8K_DEV (5<<1) /* 5: 8192 Bytes */
1021#define I2C_16K_DEV (6<<1) /* 6: 16384 Bytes */
1022#define I2C_32K_DEV (7<<1) /* 7: 32768 Bytes */
1023#define I2C_STOP BIT_0 /* Interrupt I2C transfer */
1024
1025/* B2_I2C_IRQ 32 bit I2C HW IRQ Register */
1026 /* Bit 31.. 1 reserved */
1027#define I2C_CLR_IRQ BIT_0 /* Clear I2C IRQ */
1028
1029/* B2_I2C_SW 32 bit (8 bit access) I2C HW SW Port Register */
1030 /* Bit 7.. 3: reserved */
1031#define I2C_DATA_DIR BIT_2S /* direction of I2C_DATA */
1032#define I2C_DATA BIT_1S /* I2C Data Port */
1033#define I2C_CLK BIT_0S /* I2C Clock Port */
1034
1035/*
1036 * I2C Address
1037 */
1038#define I2C_SENS_ADDR LM80_ADDR /* I2C Sensor Address, (Volt and Temp)*/
1039
1040
1041/* B2_BSC_CTRL 8 bit Blink Source Counter Control */
1042 /* Bit 7.. 2: reserved */
1043#define BSC_START BIT_1S /* Start Blink Source Counter */
1044#define BSC_STOP BIT_0S /* Stop Blink Source Counter */
1045
1046/* B2_BSC_STAT 8 bit Blink Source Counter Status */
1047 /* Bit 7.. 1: reserved */
1048#define BSC_SRC BIT_0S /* Blink Source, 0=Off / 1=On */
1049
1050/* B2_BSC_TST 16 bit Blink Source Counter Test Reg */
1051#define BSC_T_ON BIT_2S /* Test mode on */
1052#define BSC_T_OFF BIT_1S /* Test mode off */
1053#define BSC_T_STEP BIT_0S /* Test step */
1054
1055
1056/* B3_RAM_ADDR 32 bit RAM Address, to read or write */
1057 /* Bit 31..19: reserved */
1058#define RAM_ADR_RAN 0x0007ffffL /* Bit 18.. 0: RAM Address Range */
1059
1060/* RAM Interface Registers */
1061/* B3_RI_CTRL 16 bit RAM Iface Control Register */
1062 /* Bit 15..10: reserved */
1063#define RI_CLR_RD_PERR BIT_9S /* Clear IRQ RAM Read Parity Err */
1064#define RI_CLR_WR_PERR BIT_8S /* Clear IRQ RAM Write Parity Err*/
1065 /* Bit 7.. 2: reserved */
1066#define RI_RST_CLR BIT_1S /* Clear RAM Interface Reset */
1067#define RI_RST_SET BIT_0S /* Set RAM Interface Reset */
1068
1069/* B3_RI_TEST 8 bit RAM Iface Test Register */
1070 /* Bit 15.. 4: reserved */
1071#define RI_T_EV BIT_3S /* Timeout Event occured */
1072#define RI_T_ON BIT_2S /* Timeout Timer Test On */
1073#define RI_T_OFF BIT_1S /* Timeout Timer Test Off */
1074#define RI_T_STEP BIT_0S /* Timeout Timer Step */
1075
1076/* MAC Arbiter Registers */
1077/* B3_MA_TO_CTRL 16 bit MAC Arbiter Timeout Ctrl Reg */
1078 /* Bit 15.. 4: reserved */
1079#define MA_FOE_ON BIT_3S /* XMAC Fast Output Enable ON */
1080#define MA_FOE_OFF BIT_2S /* XMAC Fast Output Enable OFF */
1081#define MA_RST_CLR BIT_1S /* Clear MAC Arbiter Reset */
1082#define MA_RST_SET BIT_0S /* Set MAC Arbiter Reset */
1083
1084/* B3_MA_RC_CTRL 16 bit MAC Arbiter Recovery Ctrl Reg */
1085 /* Bit 15.. 8: reserved */
1086#define MA_ENA_REC_TX2 BIT_7S /* Enable Recovery Timer TX2 */
1087#define MA_DIS_REC_TX2 BIT_6S /* Disable Recovery Timer TX2 */
1088#define MA_ENA_REC_TX1 BIT_5S /* Enable Recovery Timer TX1 */
1089#define MA_DIS_REC_TX1 BIT_4S /* Disable Recovery Timer TX1 */
1090#define MA_ENA_REC_RX2 BIT_3S /* Enable Recovery Timer RX2 */
1091#define MA_DIS_REC_RX2 BIT_2S /* Disable Recovery Timer RX2 */
1092#define MA_ENA_REC_RX1 BIT_1S /* Enable Recovery Timer RX1 */
1093#define MA_DIS_REC_RX1 BIT_0S /* Disable Recovery Timer RX1 */
1094
1095/* Packet Arbiter Registers */
1096/* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */
1097 /* Bit 15..14: reserved */
1098#define PA_CLR_TO_TX2 BIT_13S /* Clear IRQ Packet Timeout TX2 */
1099#define PA_CLR_TO_TX1 BIT_12S /* Clear IRQ Packet Timeout TX1 */
1100#define PA_CLR_TO_RX2 BIT_11S /* Clear IRQ Packet Timeout RX2 */
1101#define PA_CLR_TO_RX1 BIT_10S /* Clear IRQ Packet Timeout RX1 */
1102#define PA_ENA_TO_TX2 BIT_9S /* Enable Timeout Timer TX2 */
1103#define PA_DIS_TO_TX2 BIT_8S /* Disable Timeout Timer TX2 */
1104#define PA_ENA_TO_TX1 BIT_7S /* Enable Timeout Timer TX1 */
1105#define PA_DIS_TO_TX1 BIT_6S /* Disable Timeout Timer TX1 */
1106#define PA_ENA_TO_RX2 BIT_5S /* Enable Timeout Timer RX2 */
1107#define PA_DIS_TO_RX2 BIT_4S /* Disable Timeout Timer RX2 */
1108#define PA_ENA_TO_RX1 BIT_3S /* Enable Timeout Timer RX1 */
1109#define PA_DIS_TO_RX1 BIT_2S /* Disable Timeout Timer RX1 */
1110#define PA_RST_CLR BIT_1S /* Clear MAC Arbiter Reset */
1111#define PA_RST_SET BIT_0S /* Set MAC Arbiter Reset */
1112
1113#define PA_ENA_TO_ALL (PA_ENA_TO_RX1 | PA_ENA_TO_RX2 |\
1114 PA_ENA_TO_TX1 | PA_ENA_TO_TX2)
1115
1116/* Rx/Tx Path related Arbiter Test Registers */
1117/* B3_MA_TO_TEST 16 bit MAC Arbiter Timeout Test Reg */
1118/* B3_MA_RC_TEST 16 bit MAC Arbiter Recovery Test Reg */
1119/* B3_PA_TEST 16 bit Packet Arbiter Test Register */
1120/* Bit 15, 11, 7, and 3 are reserved in B3_PA_TEST */
1121#define TX2_T_EV BIT_15S /* TX2 Timeout/Recv Event occured */
1122#define TX2_T_ON BIT_14S /* TX2 Timeout/Recv Timer Test On */
1123#define TX2_T_OFF BIT_13S /* TX2 Timeout/Recv Timer Tst Off */
1124#define TX2_T_STEP BIT_12S /* TX2 Timeout/Recv Timer Step */
1125#define TX1_T_EV BIT_11S /* TX1 Timeout/Recv Event occured */
1126#define TX1_T_ON BIT_10S /* TX1 Timeout/Recv Timer Test On */
1127#define TX1_T_OFF BIT_9S /* TX1 Timeout/Recv Timer Tst Off */
1128#define TX1_T_STEP BIT_8S /* TX1 Timeout/Recv Timer Step */
1129#define RX2_T_EV BIT_7S /* RX2 Timeout/Recv Event occured */
1130#define RX2_T_ON BIT_6S /* RX2 Timeout/Recv Timer Test On */
1131#define RX2_T_OFF BIT_5S /* RX2 Timeout/Recv Timer Tst Off */
1132#define RX2_T_STEP BIT_4S /* RX2 Timeout/Recv Timer Step */
1133#define RX1_T_EV BIT_3S /* RX1 Timeout/Recv Event occured */
1134#define RX1_T_ON BIT_2S /* RX1 Timeout/Recv Timer Test On */
1135#define RX1_T_OFF BIT_1S /* RX1 Timeout/Recv Timer Tst Off */
1136#define RX1_T_STEP BIT_0S /* RX1 Timeout/Recv Timer Step */
1137
1138
1139/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
1140/* TXA_ITI_INI 32 bit Tx Arb Interval Timer Init Val */
1141/* TXA_ITI_VAL 32 bit Tx Arb Interval Timer Value */
1142/* TXA_LIM_INI 32 bit Tx Arb Limit Counter Init Val */
1143/* TXA_LIM_VAL 32 bit Tx Arb Limit Counter Value */
1144 /* Bit 31..24: reserved */
1145#define TXA_MAX_VAL 0x00ffffffUL/* Bit 23.. 0: Max TXA Timer/Cnt Val */
1146
1147/* TXA_CTRL 8 bit Tx Arbiter Control Register */
1148#define TXA_ENA_FSYNC BIT_7S /* Enable force of sync Tx queue */
1149#define TXA_DIS_FSYNC BIT_6S /* Disable force of sync Tx queue */
1150#define TXA_ENA_ALLOC BIT_5S /* Enable alloc of free bandwidth */
1151#define TXA_DIS_ALLOC BIT_4S /* Disable alloc of free bandwidth */
1152#define TXA_START_RC BIT_3S /* Start sync Rate Control */
1153#define TXA_STOP_RC BIT_2S /* Stop sync Rate Control */
1154#define TXA_ENA_ARB BIT_1S /* Enable Tx Arbiter */
1155#define TXA_DIS_ARB BIT_0S /* Disable Tx Arbiter */
1156
1157/* TXA_TEST 8 bit Tx Arbiter Test Register */
1158 /* Bit 7.. 6: reserved */
1159#define TXA_INT_T_ON BIT_5S /* Tx Arb Interval Timer Test On */
1160#define TXA_INT_T_OFF BIT_4S /* Tx Arb Interval Timer Test Off */
1161#define TXA_INT_T_STEP BIT_3S /* Tx Arb Interval Timer Step */
1162#define TXA_LIM_T_ON BIT_2S /* Tx Arb Limit Timer Test On */
1163#define TXA_LIM_T_OFF BIT_1S /* Tx Arb Limit Timer Test Off */
1164#define TXA_LIM_T_STEP BIT_0S /* Tx Arb Limit Timer Step */
1165
1166/* TXA_STAT 8 bit Tx Arbiter Status Register */
1167 /* Bit 7.. 1: reserved */
1168#define TXA_PRIO_XS BIT_0S /* sync queue has prio to send */
1169
1170/* Q_BC 32 bit Current Byte Counter */
1171 /* Bit 31..16: reserved */
1172#define BC_MAX 0xffff /* Bit 15.. 0: Byte counter */
1173
1174/* BMU Control Status Registers */
1175/* B0_R1_CSR 32 bit BMU Ctrl/Stat Rx Queue 1 */
1176/* B0_R2_CSR 32 bit BMU Ctrl/Stat Rx Queue 2 */
1177/* B0_XA1_CSR 32 bit BMU Ctrl/Stat Sync Tx Queue 1 */
1178/* B0_XS1_CSR 32 bit BMU Ctrl/Stat Async Tx Queue 1 */
1179/* B0_XA2_CSR 32 bit BMU Ctrl/Stat Sync Tx Queue 2 */
1180/* B0_XS2_CSR 32 bit BMU Ctrl/Stat Async Tx Queue 2 */
1181/* Q_CSR 32 bit BMU Control/Status Register */
1182 /* Bit 31..25: reserved */
1183#define CSR_SV_IDLE BIT_24 /* BMU SM Idle */
1184 /* Bit 23..22: reserved */
1185#define CSR_DESC_CLR BIT_21 /* Clear Reset for Descr */
1186#define CSR_DESC_SET BIT_20 /* Set Reset for Descr */
1187#define CSR_FIFO_CLR BIT_19 /* Clear Reset for FIFO */
1188#define CSR_FIFO_SET BIT_18 /* Set Reset for FIFO */
1189#define CSR_HPI_RUN BIT_17 /* Release HPI SM */
1190#define CSR_HPI_RST BIT_16 /* Reset HPI SM to Idle */
1191#define CSR_SV_RUN BIT_15 /* Release Supervisor SM */
1192#define CSR_SV_RST BIT_14 /* Reset Supervisor SM */
1193#define CSR_DREAD_RUN BIT_13 /* Release Descr Read SM */
1194#define CSR_DREAD_RST BIT_12 /* Reset Descr Read SM */
1195#define CSR_DWRITE_RUN BIT_11 /* Release Descr Write SM */
1196#define CSR_DWRITE_RST BIT_10 /* Reset Descr Write SM */
1197#define CSR_TRANS_RUN BIT_9 /* Release Transfer SM */
1198#define CSR_TRANS_RST BIT_8 /* Reset Transfer SM */
1199#define CSR_ENA_POL BIT_7 /* Enable Descr Polling */
1200#define CSR_DIS_POL BIT_6 /* Disable Descr Polling */
1201#define CSR_STOP BIT_5 /* Stop Rx/Tx Queue */
1202#define CSR_START BIT_4 /* Start Rx/Tx Queue */
1203#define CSR_IRQ_CL_P BIT_3 /* (Rx) Clear Parity IRQ */
1204#define CSR_IRQ_CL_B BIT_2 /* Clear EOB IRQ */
1205#define CSR_IRQ_CL_F BIT_1 /* Clear EOF IRQ */
1206#define CSR_IRQ_CL_C BIT_0 /* Clear ERR IRQ */
1207
1208#define CSR_SET_RESET (CSR_DESC_SET | CSR_FIFO_SET | CSR_HPI_RST |\
1209 CSR_SV_RST | CSR_DREAD_RST | CSR_DWRITE_RST |\
1210 CSR_TRANS_RST)
1211#define CSR_CLR_RESET (CSR_DESC_CLR | CSR_FIFO_CLR | CSR_HPI_RUN |\
1212 CSR_SV_RUN | CSR_DREAD_RUN | CSR_DWRITE_RUN |\
1213 CSR_TRANS_RUN)
1214
1215/* Q_F 32 bit Flag Register */
1216 /* Bit 31..28: reserved */
1217#define F_ALM_FULL BIT_27 /* Rx FIFO: almost full */
1218#define F_EMPTY BIT_27 /* Tx FIFO: empty flag */
1219#define F_FIFO_EOF BIT_26 /* Tag (EOF Flag) bit in FIFO */
1220#define F_WM_REACHED BIT_25 /* Watermark reached */
1221 /* reserved */
1222#define F_FIFO_LEVEL (0x1fL<<16) /* Bit 23..16: # of Qwords in FIFO */
1223 /* Bit 15..11: reserved */
1224#define F_WATER_MARK 0x0007ffL /* Bit 10.. 0: Watermark */
1225
1226/* Q_T1 32 bit Test Register 1 */
1227/* Holds four State Machine control Bytes */
1228#define SM_CTRL_SV_MSK (0xffL<<24) /* Bit 31..24: Control Supervisor SM */
1229#define SM_CTRL_RD_MSK (0xffL<<16) /* Bit 23..16: Control Read Desc SM */
1230#define SM_CTRL_WR_MSK (0xffL<<8) /* Bit 15.. 8: Control Write Desc SM */
1231#define SM_CTRL_TR_MSK 0xffL /* Bit 7.. 0: Control Transfer SM */
1232
1233/* Q_T1_TR 8 bit Test Register 1 Transfer SM */
1234/* Q_T1_WR 8 bit Test Register 1 Write Descriptor SM */
1235/* Q_T1_RD 8 bit Test Register 1 Read Descriptor SM */
1236/* Q_T1_SV 8 bit Test Register 1 Supervisor SM */
1237
1238/* The control status byte of each machine looks like ... */
1239#define SM_STATE 0xf0 /* Bit 7.. 4: State which shall be loaded */
1240#define SM_LOAD BIT_3S /* Load the SM with SM_STATE */
1241#define SM_TEST_ON BIT_2S /* Switch on SM Test Mode */
1242#define SM_TEST_OFF BIT_1S /* Go off the Test Mode */
1243#define SM_STEP BIT_0S /* Step the State Machine */
1244/* The encoding of the states is not supported by the Diagnostics Tool */
1245
1246/* Q_T2 32 bit Test Register 2 */
1247 /* Bit 31.. 8: reserved */
1248#define T2_AC_T_ON BIT_7 /* Address Counter Test Mode on */
1249#define T2_AC_T_OFF BIT_6 /* Address Counter Test Mode off */
1250#define T2_BC_T_ON BIT_5 /* Byte Counter Test Mode on */
1251#define T2_BC_T_OFF BIT_4 /* Byte Counter Test Mode off */
1252#define T2_STEP04 BIT_3 /* Inc AC/Dec BC by 4 */
1253#define T2_STEP03 BIT_2 /* Inc AC/Dec BC by 3 */
1254#define T2_STEP02 BIT_1 /* Inc AC/Dec BC by 2 */
1255#define T2_STEP01 BIT_0 /* Inc AC/Dec BC by 1 */
1256
1257/* Q_T3 32 bit Test Register 3 */
1258 /* Bit 31.. 7: reserved */
1259#define T3_MUX_MSK (7<<4) /* Bit 6.. 4: Mux Position */
1260 /* Bit 3: reserved */
1261#define T3_VRAM_MSK 7 /* Bit 2.. 0: Virtual RAM Buffer Address */
1262
1263/* RAM Buffer Register Offsets, use RB_ADDR(Queue, Offs) to access */
1264/* RB_START 32 bit RAM Buffer Start Address */
1265/* RB_END 32 bit RAM Buffer End Address */
1266/* RB_WP 32 bit RAM Buffer Write Pointer */
1267/* RB_RP 32 bit RAM Buffer Read Pointer */
1268/* RB_RX_UTPP 32 bit Rx Upper Threshold, Pause Pack */
1269/* RB_RX_LTPP 32 bit Rx Lower Threshold, Pause Pack */
1270/* RB_RX_UTHP 32 bit Rx Upper Threshold, High Prio */
1271/* RB_RX_LTHP 32 bit Rx Lower Threshold, High Prio */
1272/* RB_PC 32 bit RAM Buffer Packet Counter */
1273/* RB_LEV 32 bit RAM Buffer Level Register */
1274 /* Bit 31..19: reserved */
1275#define RB_MSK 0x0007ffff /* Bit 18.. 0: RAM Buffer Pointer Bits */
1276
1277/* RB_TST2 8 bit RAM Buffer Test Register 2 */
1278 /* Bit 7.. 4: reserved */
1279#define RB_PC_DEC BIT_3S /* Packet Counter Decrem */
1280#define RB_PC_T_ON BIT_2S /* Packet Counter Test On */
1281#define RB_PC_T_OFF BIT_1S /* Packet Counter Tst Off */
1282#define RB_PC_INC BIT_0S /* Packet Counter Increm */
1283
1284/* RB_TST1 8 bit RAM Buffer Test Register 1 */
1285 /* Bit 7: reserved */
1286#define RB_WP_T_ON BIT_6S /* Write Pointer Test On */
1287#define RB_WP_T_OFF BIT_5S /* Write Pointer Test Off */
1288#define RB_WP_INC BIT_4S /* Write Pointer Increm */
1289 /* Bit 3: reserved */
1290#define RB_RP_T_ON BIT_2S /* Read Pointer Test On */
1291#define RB_RP_T_OFF BIT_1S /* Read Pointer Test Off */
1292#define RB_RP_DEC BIT_0S /* Read Pointer Decrement */
1293
1294/* RB_CTRL 8 bit RAM Buffer Control Register */
1295 /* Bit 7.. 6: reserved */
1296#define RB_ENA_STFWD BIT_5S /* Enable Store & Forward */
1297#define RB_DIS_STFWD BIT_4S /* Disable Store & Forward */
1298#define RB_ENA_OP_MD BIT_3S /* Enable Operation Mode */
1299#define RB_DIS_OP_MD BIT_2S /* Disable Operation Mode */
1300#define RB_RST_CLR BIT_1S /* Clear RAM Buf STM Reset */
1301#define RB_RST_SET BIT_0S /* Set RAM Buf STM Reset */
1302
1303
1304/* Receive and Transmit MAC FIFO Registers (GENESIS only) */
1305
1306/* RX_MFF_EA 32 bit Receive MAC FIFO End Address */
1307/* RX_MFF_WP 32 bit Receive MAC FIFO Write Pointer */
1308/* RX_MFF_RP 32 bit Receive MAC FIFO Read Pointer */
1309/* RX_MFF_PC 32 bit Receive MAC FIFO Packet Counter */
1310/* RX_MFF_LEV 32 bit Receive MAC FIFO Level */
1311/* TX_MFF_EA 32 bit Transmit MAC FIFO End Address */
1312/* TX_MFF_WP 32 bit Transmit MAC FIFO Write Pointer */
1313/* TX_MFF_WSP 32 bit Transmit MAC FIFO WR Shadow Pointer */
1314/* TX_MFF_RP 32 bit Transmit MAC FIFO Read Pointer */
1315/* TX_MFF_PC 32 bit Transmit MAC FIFO Packet Cnt */
1316/* TX_MFF_LEV 32 bit Transmit MAC FIFO Level */
1317 /* Bit 31.. 6: reserved */
1318#define MFF_MSK 0x007fL /* Bit 5.. 0: MAC FIFO Address/Ptr Bits */
1319
1320/* RX_MFF_CTRL1 16 bit Receive MAC FIFO Control Reg 1 */
1321 /* Bit 15..14: reserved */
1322#define MFF_ENA_RDY_PAT BIT_13S /* Enable Ready Patch */
1323#define MFF_DIS_RDY_PAT BIT_12S /* Disable Ready Patch */
1324#define MFF_ENA_TIM_PAT BIT_11S /* Enable Timing Patch */
1325#define MFF_DIS_TIM_PAT BIT_10S /* Disable Timing Patch */
1326#define MFF_ENA_ALM_FUL BIT_9S /* Enable AlmostFull Sign */
1327#define MFF_DIS_ALM_FUL BIT_8S /* Disable AlmostFull Sign */
1328#define MFF_ENA_PAUSE BIT_7S /* Enable Pause Signaling */
1329#define MFF_DIS_PAUSE BIT_6S /* Disable Pause Signaling */
1330#define MFF_ENA_FLUSH BIT_5S /* Enable Frame Flushing */
1331#define MFF_DIS_FLUSH BIT_4S /* Disable Frame Flushing */
1332#define MFF_ENA_TIST BIT_3S /* Enable Time Stamp Gener */
1333#define MFF_DIS_TIST BIT_2S /* Disable Time Stamp Gener */
1334#define MFF_CLR_INTIST BIT_1S /* Clear IRQ No Time Stamp */
1335#define MFF_CLR_INSTAT BIT_0S /* Clear IRQ No Status */
1336
1337#define MFF_RX_CTRL_DEF MFF_ENA_TIM_PAT
1338
1339/* TX_MFF_CTRL1 16 bit Transmit MAC FIFO Control Reg 1 */
1340#define MFF_CLR_PERR BIT_15S /* Clear Parity Error IRQ */
1341 /* Bit 14: reserved */
1342#define MFF_ENA_PKT_REC BIT_13S /* Enable Packet Recovery */
1343#define MFF_DIS_PKT_REC BIT_12S /* Disable Packet Recovery */
1344/* MFF_ENA_TIM_PAT (see RX_MFF_CTRL1) Bit 11: Enable Timing Patch */
1345/* MFF_DIS_TIM_PAT (see RX_MFF_CTRL1) Bit 10: Disable Timing Patch */
1346/* MFF_ENA_ALM_FUL (see RX_MFF_CTRL1) Bit 9: Enable Almost Full Sign */
1347/* MFF_DIS_ALM_FUL (see RX_MFF_CTRL1) Bit 8: Disable Almost Full Sign */
1348#define MFF_ENA_W4E BIT_7S /* Enable Wait for Empty */
1349#define MFF_DIS_W4E BIT_6S /* Disable Wait for Empty */
1350/* MFF_ENA_FLUSH (see RX_MFF_CTRL1) Bit 5: Enable Frame Flushing */
1351/* MFF_DIS_FLUSH (see RX_MFF_CTRL1) Bit 4: Disable Frame Flushing */
1352#define MFF_ENA_LOOPB BIT_3S /* Enable Loopback */
1353#define MFF_DIS_LOOPB BIT_2S /* Disable Loopback */
1354#define MFF_CLR_MAC_RST BIT_1S /* Clear XMAC Reset */
1355#define MFF_SET_MAC_RST BIT_0S /* Set XMAC Reset */
1356
1357#define MFF_TX_CTRL_DEF (MFF_ENA_PKT_REC | MFF_ENA_TIM_PAT | MFF_ENA_FLUSH)
1358
1359/* RX_MFF_TST2 8 bit Receive MAC FIFO Test Register 2 */
1360/* TX_MFF_TST2 8 bit Transmit MAC FIFO Test Register 2 */
1361 /* Bit 7: reserved */
1362#define MFF_WSP_T_ON BIT_6S /* Tx: Write Shadow Ptr TestOn */
1363#define MFF_WSP_T_OFF BIT_5S /* Tx: Write Shadow Ptr TstOff */
1364#define MFF_WSP_INC BIT_4S /* Tx: Write Shadow Ptr Increment */
1365#define MFF_PC_DEC BIT_3S /* Packet Counter Decrement */
1366#define MFF_PC_T_ON BIT_2S /* Packet Counter Test On */
1367#define MFF_PC_T_OFF BIT_1S /* Packet Counter Test Off */
1368#define MFF_PC_INC BIT_0S /* Packet Counter Increment */
1369
1370/* RX_MFF_TST1 8 bit Receive MAC FIFO Test Register 1 */
1371/* TX_MFF_TST1 8 bit Transmit MAC FIFO Test Register 1 */
1372 /* Bit 7: reserved */
1373#define MFF_WP_T_ON BIT_6S /* Write Pointer Test On */
1374#define MFF_WP_T_OFF BIT_5S /* Write Pointer Test Off */
1375#define MFF_WP_INC BIT_4S /* Write Pointer Increm */
1376 /* Bit 3: reserved */
1377#define MFF_RP_T_ON BIT_2S /* Read Pointer Test On */
1378#define MFF_RP_T_OFF BIT_1S /* Read Pointer Test Off */
1379#define MFF_RP_DEC BIT_0S /* Read Pointer Decrement */
1380
1381/* RX_MFF_CTRL2 8 bit Receive MAC FIFO Control Reg 2 */
1382/* TX_MFF_CTRL2 8 bit Transmit MAC FIFO Control Reg 2 */
1383 /* Bit 7..4: reserved */
1384#define MFF_ENA_OP_MD BIT_3S /* Enable Operation Mode */
1385#define MFF_DIS_OP_MD BIT_2S /* Disable Operation Mode */
1386#define MFF_RST_CLR BIT_1S /* Clear MAC FIFO Reset */
1387#define MFF_RST_SET BIT_0S /* Set MAC FIFO Reset */
1388
1389
1390/* Link LED Counter Registers (GENESIS only) */
1391
1392/* RX_LED_CTRL 8 bit Receive LED Cnt Control Reg */
1393/* TX_LED_CTRL 8 bit Transmit LED Cnt Control Reg */
1394/* LNK_SYNC_CTRL 8 bit Link Sync Cnt Control Register */
1395 /* Bit 7.. 3: reserved */
1396#define LED_START BIT_2S /* Start Timer */
1397#define LED_STOP BIT_1S /* Stop Timer */
1398#define LED_STATE BIT_0S /* Rx/Tx: LED State, 1=LED on */
1399#define LED_CLR_IRQ BIT_0S /* Lnk: Clear Link IRQ */
1400
1401/* RX_LED_TST 8 bit Receive LED Cnt Test Register */
1402/* TX_LED_TST 8 bit Transmit LED Cnt Test Register */
1403/* LNK_SYNC_TST 8 bit Link Sync Cnt Test Register */
1404 /* Bit 7.. 3: reserved */
1405#define LED_T_ON BIT_2S /* LED Counter Test mode On */
1406#define LED_T_OFF BIT_1S /* LED Counter Test mode Off */
1407#define LED_T_STEP BIT_0S /* LED Counter Step */
1408
1409/* LNK_LED_REG 8 bit Link LED Register */
1410 /* Bit 7.. 6: reserved */
1411#define LED_BLK_ON BIT_5S /* Link LED Blinking On */
1412#define LED_BLK_OFF BIT_4S /* Link LED Blinking Off */
1413#define LED_SYNC_ON BIT_3S /* Use Sync Wire to switch LED */
1414#define LED_SYNC_OFF BIT_2S /* Disable Sync Wire Input */
1415#define LED_ON BIT_1S /* switch LED on */
1416#define LED_OFF BIT_0S /* switch LED off */
1417
1418/* Receive and Transmit GMAC FIFO Registers (YUKON only) */
1419
1420/* RX_GMF_EA 32 bit Rx GMAC FIFO End Address */
1421/* RX_GMF_AF_THR 32 bit Rx GMAC FIFO Almost Full Thresh. */
1422/* RX_GMF_WP 32 bit Rx GMAC FIFO Write Pointer */
1423/* RX_GMF_WLEV 32 bit Rx GMAC FIFO Write Level */
1424/* RX_GMF_RP 32 bit Rx GMAC FIFO Read Pointer */
1425/* RX_GMF_RLEV 32 bit Rx GMAC FIFO Read Level */
1426/* TX_GMF_EA 32 bit Tx GMAC FIFO End Address */
1427/* TX_GMF_AE_THR 32 bit Tx GMAC FIFO Almost Empty Thresh.*/
1428/* TX_GMF_WP 32 bit Tx GMAC FIFO Write Pointer */
1429/* TX_GMF_WSP 32 bit Tx GMAC FIFO Write Shadow Ptr. */
1430/* TX_GMF_WLEV 32 bit Tx GMAC FIFO Write Level */
1431/* TX_GMF_RP 32 bit Tx GMAC FIFO Read Pointer */
1432/* TX_GMF_RSTP 32 bit Tx GMAC FIFO Restart Pointer */
1433/* TX_GMF_RLEV 32 bit Tx GMAC FIFO Read Level */
1434
1435/* RX_GMF_CTRL_T 32 bit Rx GMAC FIFO Control/Test */
1436 /* Bits 31..15: reserved */
1437#define GMF_WP_TST_ON BIT_14 /* Write Pointer Test On */
1438#define GMF_WP_TST_OFF BIT_13 /* Write Pointer Test Off */
1439#define GMF_WP_STEP BIT_12 /* Write Pointer Step/Increment */
1440 /* Bit 11: reserved */
1441#define GMF_RP_TST_ON BIT_10 /* Read Pointer Test On */
1442#define GMF_RP_TST_OFF BIT_9 /* Read Pointer Test Off */
1443#define GMF_RP_STEP BIT_8 /* Read Pointer Step/Increment */
1444#define GMF_RX_F_FL_ON BIT_7 /* Rx FIFO Flush Mode On */
1445#define GMF_RX_F_FL_OFF BIT_6 /* Rx FIFO Flush Mode Off */
1446#define GMF_CLI_RX_FO BIT_5 /* Clear IRQ Rx FIFO Overrun */
1447#define GMF_CLI_RX_FC BIT_4 /* Clear IRQ Rx Frame Complete */
1448#define GMF_OPER_ON BIT_3 /* Operational Mode On */
1449#define GMF_OPER_OFF BIT_2 /* Operational Mode Off */
1450#define GMF_RST_CLR BIT_1 /* Clear GMAC FIFO Reset */
1451#define GMF_RST_SET BIT_0 /* Set GMAC FIFO Reset */
1452
1453/* TX_GMF_CTRL_T 32 bit Tx GMAC FIFO Control/Test */
1454 /* Bits 31..19: reserved */
1455#define GMF_WSP_TST_ON BIT_18 /* Write Shadow Pointer Test On */
1456#define GMF_WSP_TST_OFF BIT_17 /* Write Shadow Pointer Test Off */
1457#define GMF_WSP_STEP BIT_16 /* Write Shadow Pointer Step/Increment */
1458 /* Bits 15..7: same as for RX_GMF_CTRL_T */
1459#define GMF_CLI_TX_FU BIT_6 /* Clear IRQ Tx FIFO Underrun */
1460#define GMF_CLI_TX_FC BIT_5 /* Clear IRQ Tx Frame Complete */
1461#define GMF_CLI_TX_PE BIT_4 /* Clear IRQ Tx Parity Error */
1462 /* Bits 3..0: same as for RX_GMF_CTRL_T */
1463
1464#define GMF_RX_CTRL_DEF (GMF_OPER_ON | GMF_RX_F_FL_ON)
1465#define GMF_TX_CTRL_DEF GMF_OPER_ON
1466
1467#define RX_GMF_FL_THR_DEF 0x0a /* Rx GMAC FIFO Flush Threshold default */
1468
1469/* GMAC_TI_ST_CTRL 8 bit Time Stamp Timer Ctrl Reg (YUKON only) */
1470 /* Bit 7.. 3: reserved */
1471#define GMT_ST_START BIT_2S /* Start Time Stamp Timer */
1472#define GMT_ST_STOP BIT_1S /* Stop Time Stamp Timer */
1473#define GMT_ST_CLR_IRQ BIT_0S /* Clear Time Stamp Timer IRQ */
1474
1475/* GMAC_CTRL 32 bit GMAC Control Reg (YUKON only) */
1476 /* Bits 31.. 8: reserved */
1477#define GMC_H_BURST_ON BIT_7 /* Half Duplex Burst Mode On */
1478#define GMC_H_BURST_OFF BIT_6 /* Half Duplex Burst Mode Off */
1479#define GMC_F_LOOPB_ON BIT_5 /* FIFO Loopback On */
1480#define GMC_F_LOOPB_OFF BIT_4 /* FIFO Loopback Off */
1481#define GMC_PAUSE_ON BIT_3 /* Pause On */
1482#define GMC_PAUSE_OFF BIT_2 /* Pause Off */
1483#define GMC_RST_CLR BIT_1 /* Clear GMAC Reset */
1484#define GMC_RST_SET BIT_0 /* Set GMAC Reset */
1485
1486/* GPHY_CTRL 32 bit GPHY Control Reg (YUKON only) */
1487 /* Bits 31..29: reserved */
1488#define GPC_SEL_BDT BIT_28 /* Select Bi-Dir. Transfer for MDC/MDIO */
1489#define GPC_INT_POL_HI BIT_27 /* IRQ Polarity is Active HIGH */
1490#define GPC_75_OHM BIT_26 /* Use 75 Ohm Termination instead of 50 */
1491#define GPC_DIS_FC BIT_25 /* Disable Automatic Fiber/Copper Detection */
1492#define GPC_DIS_SLEEP BIT_24 /* Disable Energy Detect */
1493#define GPC_HWCFG_M_3 BIT_23 /* HWCFG_MODE[3] */
1494#define GPC_HWCFG_M_2 BIT_22 /* HWCFG_MODE[2] */
1495#define GPC_HWCFG_M_1 BIT_21 /* HWCFG_MODE[1] */
1496#define GPC_HWCFG_M_0 BIT_20 /* HWCFG_MODE[0] */
1497#define GPC_ANEG_0 BIT_19 /* ANEG[0] */
1498#define GPC_ENA_XC BIT_18 /* Enable MDI crossover */
1499#define GPC_DIS_125 BIT_17 /* Disable 125 MHz clock */
1500#define GPC_ANEG_3 BIT_16 /* ANEG[3] */
1501#define GPC_ANEG_2 BIT_15 /* ANEG[2] */
1502#define GPC_ANEG_1 BIT_14 /* ANEG[1] */
1503#define GPC_ENA_PAUSE BIT_13 /* Enable Pause (SYM_OR_REM) */
1504#define GPC_PHYADDR_4 BIT_12 /* Bit 4 of Phy Addr */
1505#define GPC_PHYADDR_3 BIT_11 /* Bit 3 of Phy Addr */
1506#define GPC_PHYADDR_2 BIT_10 /* Bit 2 of Phy Addr */
1507#define GPC_PHYADDR_1 BIT_9 /* Bit 1 of Phy Addr */
1508#define GPC_PHYADDR_0 BIT_8 /* Bit 0 of Phy Addr */
1509 /* Bits 7..2: reserved */
1510#define GPC_RST_CLR BIT_1 /* Clear GPHY Reset */
1511#define GPC_RST_SET BIT_0 /* Set GPHY Reset */
1512
1513#define GPC_HWCFG_GMII_COP (GPC_HWCFG_M_3 | GPC_HWCFG_M_2 | \
1514 GPC_HWCFG_M_1 | GPC_HWCFG_M_0)
1515
1516#define GPC_HWCFG_GMII_FIB ( GPC_HWCFG_M_2 | \
1517 GPC_HWCFG_M_1 | GPC_HWCFG_M_0)
1518
1519#define GPC_ANEG_ADV_ALL_M (GPC_ANEG_3 | GPC_ANEG_2 | \
1520 GPC_ANEG_1 | GPC_ANEG_0)
1521
1522/* forced speed and duplex mode (don't mix with other ANEG bits) */
1523#define GPC_FRC10MBIT_HALF 0
1524#define GPC_FRC10MBIT_FULL GPC_ANEG_0
1525#define GPC_FRC100MBIT_HALF GPC_ANEG_1
1526#define GPC_FRC100MBIT_FULL (GPC_ANEG_0 | GPC_ANEG_1)
1527
1528/* auto-negotiation with limited advertised speeds */
1529/* mix only with master/slave settings (for copper) */
1530#define GPC_ADV_1000_HALF GPC_ANEG_2
1531#define GPC_ADV_1000_FULL GPC_ANEG_3
1532#define GPC_ADV_ALL (GPC_ANEG_2 | GPC_ANEG_3)
1533
1534/* master/slave settings */
1535/* only for copper with 1000 Mbps */
1536#define GPC_FORCE_MASTER 0
1537#define GPC_FORCE_SLAVE GPC_ANEG_0
1538#define GPC_PREF_MASTER GPC_ANEG_1
1539#define GPC_PREF_SLAVE (GPC_ANEG_1 | GPC_ANEG_0)
1540
1541/* GMAC_IRQ_SRC 8 bit GMAC Interrupt Source Reg (YUKON only) */
1542/* GMAC_IRQ_MSK 8 bit GMAC Interrupt Mask Reg (YUKON only) */
1543#define GM_IS_TX_CO_OV BIT_5 /* Transmit Counter Overflow IRQ */
1544#define GM_IS_RX_CO_OV BIT_4 /* Receive Counter Overflow IRQ */
1545#define GM_IS_TX_FF_UR BIT_3 /* Transmit FIFO Underrun */
1546#define GM_IS_TX_COMPL BIT_2 /* Frame Transmission Complete */
1547#define GM_IS_RX_FF_OR BIT_1 /* Receive FIFO Overrun */
1548#define GM_IS_RX_COMPL BIT_0 /* Frame Reception Complete */
1549
1550#define GMAC_DEF_MSK (GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | \
1551 GM_IS_TX_FF_UR)
1552
1553/* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */
1554 /* Bits 15.. 2: reserved */
1555#define GMLC_RST_CLR BIT_1S /* Clear GMAC Link Reset */
1556#define GMLC_RST_SET BIT_0S /* Set GMAC Link Reset */
1557
1558
1559/* WOL_CTRL_STAT 16 bit WOL Control/Status Reg */
1560#define WOL_CTL_LINK_CHG_OCC BIT_15S
1561#define WOL_CTL_MAGIC_PKT_OCC BIT_14S
1562#define WOL_CTL_PATTERN_OCC BIT_13S
1563
1564#define WOL_CTL_CLEAR_RESULT BIT_12S
1565
1566#define WOL_CTL_ENA_PME_ON_LINK_CHG BIT_11S
1567#define WOL_CTL_DIS_PME_ON_LINK_CHG BIT_10S
1568#define WOL_CTL_ENA_PME_ON_MAGIC_PKT BIT_9S
1569#define WOL_CTL_DIS_PME_ON_MAGIC_PKT BIT_8S
1570#define WOL_CTL_ENA_PME_ON_PATTERN BIT_7S
1571#define WOL_CTL_DIS_PME_ON_PATTERN BIT_6S
1572
1573#define WOL_CTL_ENA_LINK_CHG_UNIT BIT_5S
1574#define WOL_CTL_DIS_LINK_CHG_UNIT BIT_4S
1575#define WOL_CTL_ENA_MAGIC_PKT_UNIT BIT_3S
1576#define WOL_CTL_DIS_MAGIC_PKT_UNIT BIT_2S
1577#define WOL_CTL_ENA_PATTERN_UNIT BIT_1S
1578#define WOL_CTL_DIS_PATTERN_UNIT BIT_0S
1579
1580#define WOL_CTL_DEFAULT \
1581 (WOL_CTL_DIS_PME_ON_LINK_CHG | \
1582 WOL_CTL_DIS_PME_ON_PATTERN | \
1583 WOL_CTL_DIS_PME_ON_MAGIC_PKT | \
1584 WOL_CTL_DIS_LINK_CHG_UNIT | \
1585 WOL_CTL_DIS_PATTERN_UNIT | \
1586 WOL_CTL_DIS_MAGIC_PKT_UNIT)
1587
1588/* WOL_MATCH_CTL 8 bit WOL Match Control Reg */
1589#define WOL_CTL_PATT_ENA(x) (BIT_0 << (x))
1590
1591#define SK_NUM_WOL_PATTERN 7
1592#define SK_PATTERN_PER_WORD 4
1593#define SK_BITMASK_PATTERN 7
1594#define SK_POW_PATTERN_LENGTH 128
1595
1596#define WOL_LENGTH_MSK 0x7f
1597#define WOL_LENGTH_SHIFT 8
1598
1599
1600/* Receive and Transmit Descriptors ******************************************/
1601
1602/* Transmit Descriptor struct */
1603typedef struct s_HwTxd {
1604 SK_U32 volatile TxCtrl; /* Transmit Buffer Control Field */
1605 SK_U32 TxNext; /* Physical Address Pointer to the next TxD */
1606 SK_U32 TxAdrLo; /* Physical Tx Buffer Address lower dword */
1607 SK_U32 TxAdrHi; /* Physical Tx Buffer Address upper dword */
1608 SK_U32 TxStat; /* Transmit Frame Status Word */
1609#ifndef SK_USE_REV_DESC
1610 SK_U16 TxTcpOffs; /* TCP Checksum Calculation Start Value */
1611 SK_U16 TxRes1; /* 16 bit reserved field */
1612 SK_U16 TxTcpWp; /* TCP Checksum Write Position */
1613 SK_U16 TxTcpSp; /* TCP Checksum Calculation Start Position */
1614#else /* SK_USE_REV_DESC */
1615 SK_U16 TxRes1; /* 16 bit reserved field */
1616 SK_U16 TxTcpOffs; /* TCP Checksum Calculation Start Value */
1617 SK_U16 TxTcpSp; /* TCP Checksum Calculation Start Position */
1618 SK_U16 TxTcpWp; /* TCP Checksum Write Position */
1619#endif /* SK_USE_REV_DESC */
1620 SK_U32 TxRes2; /* 32 bit reserved field */
1621} SK_HWTXD;
1622
1623/* Receive Descriptor struct */
1624typedef struct s_HwRxd {
1625 SK_U32 volatile RxCtrl; /* Receive Buffer Control Field */
1626 SK_U32 RxNext; /* Physical Address Pointer to the next RxD */
1627 SK_U32 RxAdrLo; /* Physical Rx Buffer Address lower dword */
1628 SK_U32 RxAdrHi; /* Physical Rx Buffer Address upper dword */
1629 SK_U32 RxStat; /* Receive Frame Status Word */
1630 SK_U32 RxTiSt; /* Receive Time Stamp (from XMAC on GENESIS) */
1631#ifndef SK_USE_REV_DESC
1632 SK_U16 RxTcpSum1; /* TCP Checksum 1 */
1633 SK_U16 RxTcpSum2; /* TCP Checksum 2 */
1634 SK_U16 RxTcpSp1; /* TCP Checksum Calculation Start Position 1 */
1635 SK_U16 RxTcpSp2; /* TCP Checksum Calculation Start Position 2 */
1636#else /* SK_USE_REV_DESC */
1637 SK_U16 RxTcpSum2; /* TCP Checksum 2 */
1638 SK_U16 RxTcpSum1; /* TCP Checksum 1 */
1639 SK_U16 RxTcpSp2; /* TCP Checksum Calculation Start Position 2 */
1640 SK_U16 RxTcpSp1; /* TCP Checksum Calculation Start Position 1 */
1641#endif /* SK_USE_REV_DESC */
1642} SK_HWRXD;
1643
1644/*
1645 * Drivers which use the reverse descriptor feature (PCI_OUR_REG_2)
1646 * should set the define SK_USE_REV_DESC.
1647 * Structures are 'normaly' not endianess dependent. But in
1648 * this case the SK_U16 fields are bound to bit positions inside the
1649 * descriptor. RxTcpSum1 e.g. must start at bit 0 within the 6.th DWord.
1650 * The bit positions inside a DWord are of course endianess dependent and
1651 * swaps if the DWord is swapped by the hardware.
1652 */
1653
1654
1655/* Descriptor Bit Definition */
1656/* TxCtrl Transmit Buffer Control Field */
1657/* RxCtrl Receive Buffer Control Field */
1658#define BMU_OWN BIT_31 /* OWN bit: 0=host/1=BMU */
1659#define BMU_STF BIT_30 /* Start of Frame */
1660#define BMU_EOF BIT_29 /* End of Frame */
1661#define BMU_IRQ_EOB BIT_28 /* Req "End of Buffer" IRQ */
1662#define BMU_IRQ_EOF BIT_27 /* Req "End of Frame" IRQ */
1663/* TxCtrl specific bits */
1664#define BMU_STFWD BIT_26 /* (Tx) Store & Forward Frame */
1665#define BMU_NO_FCS BIT_25 /* (Tx) Disable MAC FCS (CRC) generation */
1666#define BMU_SW BIT_24 /* (Tx) 1 bit res. for SW use */
1667/* RxCtrl specific bits */
1668#define BMU_DEV_0 BIT_26 /* (Rx) Transfer data to Dev0 */
1669#define BMU_STAT_VAL BIT_25 /* (Rx) Rx Status Valid */
1670#define BMU_TIST_VAL BIT_24 /* (Rx) Rx TimeStamp Valid */
1671 /* Bit 23..16: BMU Check Opcodes */
1672#define BMU_CHECK (0x55L<<16) /* Default BMU check */
1673#define BMU_TCP_CHECK (0x56L<<16) /* Descr with TCP ext */
1674#define BMU_UDP_CHECK (0x57L<<16) /* Descr with UDP ext (YUKON only) */
1675#define BMU_BBC 0xffffL /* Bit 15.. 0: Buffer Byte Counter */
1676
1677/* TxStat Transmit Frame Status Word */
1678/* RxStat Receive Frame Status Word */
1679/*
1680 *Note: TxStat is reserved for ASIC loopback mode only
1681 *
1682 * The Bits of the Status words are defined in xmac_ii.h
1683 * (see XMR_FS bits)
1684 */
1685
1686/* macros ********************************************************************/
1687
1688/* Receive and Transmit Queues */
1689#define Q_R1 0x0000 /* Receive Queue 1 */
1690#define Q_R2 0x0080 /* Receive Queue 2 */
1691#define Q_XS1 0x0200 /* Synchronous Transmit Queue 1 */
1692#define Q_XA1 0x0280 /* Asynchronous Transmit Queue 1 */
1693#define Q_XS2 0x0300 /* Synchronous Transmit Queue 2 */
1694#define Q_XA2 0x0380 /* Asynchronous Transmit Queue 2 */
1695
1696/*
1697 * Macro Q_ADDR()
1698 *
1699 * Use this macro to access the Receive and Transmit Queue Registers.
1700 *
1701 * para:
1702 * Queue Queue to access.
1703 * Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2
1704 * Offs Queue register offset.
1705 * Values: Q_D, Q_DA_L ... Q_T2, Q_T3
1706 *
1707 * usage SK_IN32(pAC, Q_ADDR(Q_R2, Q_BC), pVal)
1708 */
1709#define Q_ADDR(Queue, Offs) (B8_Q_REGS + (Queue) + (Offs))
1710
1711/*
1712 * Macro RB_ADDR()
1713 *
1714 * Use this macro to access the RAM Buffer Registers.
1715 *
1716 * para:
1717 * Queue Queue to access.
1718 * Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2
1719 * Offs Queue register offset.
1720 * Values: RB_START, RB_END ... RB_LEV, RB_CTRL
1721 *
1722 * usage SK_IN32(pAC, RB_ADDR(Q_R2, RB_RP), pVal)
1723 */
1724#define RB_ADDR(Queue, Offs) (B16_RAM_REGS + (Queue) + (Offs))
1725
1726
1727/* MAC Related Registers */
1728#define MAC_1 0 /* belongs to the port near the slot */
1729#define MAC_2 1 /* belongs to the port far away from the slot */
1730
1731/*
1732 * Macro MR_ADDR()
1733 *
1734 * Use this macro to access a MAC Related Registers inside the ASIC.
1735 *
1736 * para:
1737 * Mac MAC to access.
1738 * Values: MAC_1, MAC_2
1739 * Offs MAC register offset.
1740 * Values: RX_MFF_EA, RX_MFF_WP ... LNK_LED_REG,
1741 * TX_MFF_EA, TX_MFF_WP ... TX_LED_TST
1742 *
1743 * usage SK_IN32(pAC, MR_ADDR(MAC_1, TX_MFF_EA), pVal)
1744 */
1745#define MR_ADDR(Mac, Offs) (((Mac) << 7) + (Offs))
1746
1747#ifdef SK_LITTLE_ENDIAN
1748#define XM_WORD_LO 0
1749#define XM_WORD_HI 1
1750#else /* !SK_LITTLE_ENDIAN */
1751#define XM_WORD_LO 1
1752#define XM_WORD_HI 0
1753#endif /* !SK_LITTLE_ENDIAN */
1754
1755
1756/*
1757 * macros to access the XMAC (GENESIS only)
1758 *
1759 * XM_IN16(), to read a 16 bit register (e.g. XM_MMU_CMD)
1760 * XM_OUT16(), to write a 16 bit register (e.g. XM_MMU_CMD)
1761 * XM_IN32(), to read a 32 bit register (e.g. XM_TX_EV_CNT)
1762 * XM_OUT32(), to write a 32 bit register (e.g. XM_TX_EV_CNT)
1763 * XM_INADDR(), to read a network address register (e.g. XM_SRC_CHK)
1764 * XM_OUTADDR(), to write a network address register (e.g. XM_SRC_CHK)
1765 * XM_INHASH(), to read the XM_HSM_CHK register
1766 * XM_OUTHASH() to write the XM_HSM_CHK register
1767 *
1768 * para:
1769 * Mac XMAC to access values: MAC_1 or MAC_2
1770 * IoC I/O context needed for SK I/O macros
1771 * Reg XMAC Register to read or write
1772 * (p)Val Value or pointer to the value which should be read or written
1773 *
1774 * usage: XM_OUT16(IoC, MAC_1, XM_MMU_CMD, Value);
1775 */
1776
1777#define XMA(Mac, Reg) \
1778 ((BASE_XMAC_1 + (Mac) * (BASE_XMAC_2 - BASE_XMAC_1)) | ((Reg) << 1))
1779
1780#define XM_IN16(IoC, Mac, Reg, pVal) \
1781 SK_IN16((IoC), XMA((Mac), (Reg)), (pVal))
1782
1783#define XM_OUT16(IoC, Mac, Reg, Val) \
1784 SK_OUT16((IoC), XMA((Mac), (Reg)), (Val))
1785
1786#define XM_IN32(IoC, Mac, Reg, pVal) { \
1787 SK_IN16((IoC), XMA((Mac), (Reg)), \
1788 (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_LO]); \
1789 SK_IN16((IoC), XMA((Mac), (Reg+2)), \
1790 (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_HI]); \
1791}
1792
1793#define XM_OUT32(IoC, Mac, Reg, Val) { \
1794 SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL)); \
1795 SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)(((Val) >> 16) & 0xffffL));\
1796}
1797
1798/* Remember: we are always writing to / reading from LITTLE ENDIAN memory */
1799
1800#define XM_INADDR(IoC, Mac, Reg, pVal) { \
1801 SK_U16 Word; \
1802 SK_U8 *pByte; \
1803 pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \
1804 SK_IN16((IoC), XMA((Mac), (Reg)), &Word); \
1805 pByte[0] = (SK_U8)(Word & 0x00ff); \
1806 pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \
1807 SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word); \
1808 pByte[2] = (SK_U8)(Word & 0x00ff); \
1809 pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \
1810 SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word); \
1811 pByte[4] = (SK_U8)(Word & 0x00ff); \
1812 pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \
1813}
1814
1815#define XM_OUTADDR(IoC, Mac, Reg, pVal) { \
1816 SK_U8 SK_FAR *pByte; \
1817 pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \
1818 SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16) \
1819 (((SK_U16)(pByte[0]) & 0x00ff) | \
1820 (((SK_U16)(pByte[1]) << 8) & 0xff00))); \
1821 SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16) \
1822 (((SK_U16)(pByte[2]) & 0x00ff) | \
1823 (((SK_U16)(pByte[3]) << 8) & 0xff00))); \
1824 SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16) \
1825 (((SK_U16)(pByte[4]) & 0x00ff) | \
1826 (((SK_U16)(pByte[5]) << 8) & 0xff00))); \
1827}
1828
1829#define XM_INHASH(IoC, Mac, Reg, pVal) { \
1830 SK_U16 Word; \
1831 SK_U8 SK_FAR *pByte; \
1832 pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \
1833 SK_IN16((IoC), XMA((Mac), (Reg)), &Word); \
1834 pByte[0] = (SK_U8)(Word & 0x00ff); \
1835 pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \
1836 SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word); \
1837 pByte[2] = (SK_U8)(Word & 0x00ff); \
1838 pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \
1839 SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word); \
1840 pByte[4] = (SK_U8)(Word & 0x00ff); \
1841 pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \
1842 SK_IN16((IoC), XMA((Mac), (Reg+6)), &Word); \
1843 pByte[6] = (SK_U8)(Word & 0x00ff); \
1844 pByte[7] = (SK_U8)((Word >> 8) & 0x00ff); \
1845}
1846
1847#define XM_OUTHASH(IoC, Mac, Reg, pVal) { \
1848 SK_U8 SK_FAR *pByte; \
1849 pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \
1850 SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16) \
1851 (((SK_U16)(pByte[0]) & 0x00ff)| \
1852 (((SK_U16)(pByte[1]) << 8) & 0xff00))); \
1853 SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16) \
1854 (((SK_U16)(pByte[2]) & 0x00ff)| \
1855 (((SK_U16)(pByte[3]) << 8) & 0xff00))); \
1856 SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16) \
1857 (((SK_U16)(pByte[4]) & 0x00ff)| \
1858 (((SK_U16)(pByte[5]) << 8) & 0xff00))); \
1859 SK_OUT16((IoC), XMA((Mac), (Reg+6)), (SK_U16) \
1860 (((SK_U16)(pByte[6]) & 0x00ff)| \
1861 (((SK_U16)(pByte[7]) << 8) & 0xff00))); \
1862}
1863
1864/*
1865 * macros to access the GMAC (YUKON only)
1866 *
1867 * GM_IN16(), to read a 16 bit register (e.g. GM_GP_STAT)
1868 * GM_OUT16(), to write a 16 bit register (e.g. GM_GP_CTRL)
1869 * GM_IN32(), to read a 32 bit register (e.g. GM_)
1870 * GM_OUT32(), to write a 32 bit register (e.g. GM_)
1871 * GM_INADDR(), to read a network address register (e.g. GM_SRC_ADDR_1L)
1872 * GM_OUTADDR(), to write a network address register (e.g. GM_SRC_ADDR_2L)
1873 * GM_INHASH(), to read the GM_MC_ADDR_H1 register
1874 * GM_OUTHASH() to write the GM_MC_ADDR_H1 register
1875 *
1876 * para:
1877 * Mac GMAC to access values: MAC_1 or MAC_2
1878 * IoC I/O context needed for SK I/O macros
1879 * Reg GMAC Register to read or write
1880 * (p)Val Value or pointer to the value which should be read or written
1881 *
1882 * usage: GM_OUT16(IoC, MAC_1, GM_GP_CTRL, Value);
1883 */
1884
1885#define GMA(Mac, Reg) \
1886 ((BASE_GMAC_1 + (Mac) * (BASE_GMAC_2 - BASE_GMAC_1)) | (Reg))
1887
1888#define GM_IN16(IoC, Mac, Reg, pVal) \
1889 SK_IN16((IoC), GMA((Mac), (Reg)), (pVal))
1890
1891#define GM_OUT16(IoC, Mac, Reg, Val) \
1892 SK_OUT16((IoC), GMA((Mac), (Reg)), (Val))
1893
1894#define GM_IN32(IoC, Mac, Reg, pVal) { \
1895 SK_IN16((IoC), GMA((Mac), (Reg)), \
1896 (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_LO]); \
1897 SK_IN16((IoC), GMA((Mac), (Reg+4)), \
1898 (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_HI]); \
1899}
1900
1901#define GM_OUT32(IoC, Mac, Reg, Val) { \
1902 SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL)); \
1903 SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16)(((Val) >> 16) & 0xffffL));\
1904}
1905
1906#define GM_INADDR(IoC, Mac, Reg, pVal) { \
1907 SK_U16 Word; \
1908 SK_U8 *pByte; \
1909 pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \
1910 SK_IN16((IoC), GMA((Mac), (Reg)), &Word); \
1911 pByte[0] = (SK_U8)(Word & 0x00ff); \
1912 pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \
1913 SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word); \
1914 pByte[2] = (SK_U8)(Word & 0x00ff); \
1915 pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \
1916 SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word); \
1917 pByte[4] = (SK_U8)(Word & 0x00ff); \
1918 pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \
1919}
1920
1921#define GM_OUTADDR(IoC, Mac, Reg, pVal) { \
1922 SK_U8 SK_FAR *pByte; \
1923 pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \
1924 SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16) \
1925 (((SK_U16)(pByte[0]) & 0x00ff) | \
1926 (((SK_U16)(pByte[1]) << 8) & 0xff00))); \
1927 SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16) \
1928 (((SK_U16)(pByte[2]) & 0x00ff) | \
1929 (((SK_U16)(pByte[3]) << 8) & 0xff00))); \
1930 SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16) \
1931 (((SK_U16)(pByte[4]) & 0x00ff) | \
1932 (((SK_U16)(pByte[5]) << 8) & 0xff00))); \
1933}
1934
1935#define GM_INHASH(IoC, Mac, Reg, pVal) { \
1936 SK_U16 Word; \
1937 SK_U8 *pByte; \
1938 pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \
1939 SK_IN16((IoC), GMA((Mac), (Reg)), &Word); \
1940 pByte[0] = (SK_U8)(Word & 0x00ff); \
1941 pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \
1942 SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word); \
1943 pByte[2] = (SK_U8)(Word & 0x00ff); \
1944 pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \
1945 SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word); \
1946 pByte[4] = (SK_U8)(Word & 0x00ff); \
1947 pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \
1948 SK_IN16((IoC), GMA((Mac), (Reg+12)), &Word); \
1949 pByte[6] = (SK_U8)(Word & 0x00ff); \
1950 pByte[7] = (SK_U8)((Word >> 8) & 0x00ff); \
1951}
1952
1953#define GM_OUTHASH(IoC, Mac, Reg, pVal) { \
1954 SK_U8 *pByte; \
1955 pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \
1956 SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16) \
1957 (((SK_U16)(pByte[0]) & 0x00ff)| \
1958 (((SK_U16)(pByte[1]) << 8) & 0xff00))); \
1959 SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16) \
1960 (((SK_U16)(pByte[2]) & 0x00ff)| \
1961 (((SK_U16)(pByte[3]) << 8) & 0xff00))); \
1962 SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16) \
1963 (((SK_U16)(pByte[4]) & 0x00ff)| \
1964 (((SK_U16)(pByte[5]) << 8) & 0xff00))); \
1965 SK_OUT16((IoC), GMA((Mac), (Reg+12)), (SK_U16) \
1966 (((SK_U16)(pByte[6]) & 0x00ff)| \
1967 (((SK_U16)(pByte[7]) << 8) & 0xff00))); \
1968}
1969
1970/*
1971 * Different MAC Types
1972 */
1973#define SK_MAC_XMAC 0 /* Xaqti XMAC II */
1974#define SK_MAC_GMAC 1 /* Marvell GMAC */
1975
1976/*
1977 * Different PHY Types
1978 */
1979#define SK_PHY_XMAC 0 /* integrated in XMAC II */
1980#define SK_PHY_BCOM 1 /* Broadcom BCM5400 */
1981#define SK_PHY_LONE 2 /* Level One LXT1000 */
1982#define SK_PHY_NAT 3 /* National DP83891 */
1983#define SK_PHY_MARV_COPPER 4 /* Marvell 88E1011S */
1984#define SK_PHY_MARV_FIBER 5 /* Marvell 88E1011S working on fiber */
1985
1986/*
1987 * PHY addresses (bits 12..8 of PHY address reg)
1988 */
1989#define PHY_ADDR_XMAC (0<<8)
1990#define PHY_ADDR_BCOM (1<<8)
1991#define PHY_ADDR_LONE (3<<8)
1992#define PHY_ADDR_NAT (0<<8)
1993
1994/* GPHY address (bits 15..11 of SMI control reg) */
1995#define PHY_ADDR_MARV 0
1996
1997/*
1998 * macros to access the PHY
1999 *
2000 * PHY_READ() read a 16 bit value from the PHY
2001 * PHY_WRITE() write a 16 bit value to the PHY
2002 *
2003 * para:
2004 * IoC I/O context needed for SK I/O macros
2005 * pPort Pointer to port struct for PhyAddr
2006 * Mac XMAC to access values: MAC_1 or MAC_2
2007 * PhyReg PHY Register to read or write
2008 * (p)Val Value or pointer to the value which should be read or
2009 * written.
2010 *
2011 * usage: PHY_READ(IoC, pPort, MAC_1, PHY_CTRL, Value);
2012 * Warning: a PHY_READ on an uninitialized PHY (PHY still in reset) never
2013 * comes back. This is checked in DEBUG mode.
2014 */
2015#ifndef DEBUG
2016#define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) { \
2017 SK_U16 Mmu; \
2018 \
2019 XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr); \
2020 XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
2021 if ((pPort)->PhyType != SK_PHY_XMAC) { \
2022 do { \
2023 XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \
2024 } while ((Mmu & XM_MMU_PHY_RDY) == 0); \
2025 XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
2026 } \
2027}
2028#else
2029#define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) { \
2030 SK_U16 Mmu; \
2031 int __i = 0; \
2032 \
2033 XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr); \
2034 XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
2035 if ((pPort)->PhyType != SK_PHY_XMAC) { \
2036 do { \
2037 XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \
2038 __i++; \
2039 if (__i > 100000) { \
2040 SK_DBG_PRINTF("*****************************\n"); \
2041 SK_DBG_PRINTF("PHY_READ on uninitialized PHY\n"); \
2042 SK_DBG_PRINTF("*****************************\n"); \
2043 break; \
2044 } \
2045 } while ((Mmu & XM_MMU_PHY_RDY) == 0); \
2046 XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
2047 } \
2048}
2049#endif /* DEBUG */
2050
2051#define PHY_WRITE(IoC, pPort, Mac, PhyReg, Val) { \
2052 SK_U16 Mmu; \
2053 \
2054 if ((pPort)->PhyType != SK_PHY_XMAC) { \
2055 do { \
2056 XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \
2057 } while ((Mmu & XM_MMU_PHY_BUSY) != 0); \
2058 } \
2059 XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr); \
2060 XM_OUT16((IoC), (Mac), XM_PHY_DATA, (Val)); \
2061 if ((pPort)->PhyType != SK_PHY_XMAC) { \
2062 do { \
2063 XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \
2064 } while ((Mmu & XM_MMU_PHY_BUSY) != 0); \
2065 } \
2066}
2067
2068/*
2069 * Macro PCI_C()
2070 *
2071 * Use this macro to access PCI config register from the I/O space.
2072 *
2073 * para:
2074 * Addr PCI configuration register to access.
2075 * Values: PCI_VENDOR_ID ... PCI_VPD_ADR_REG,
2076 *
2077 * usage SK_IN16(pAC, PCI_C(PCI_VENDOR_ID), pVal);
2078 */
2079#define PCI_C(Addr) (B7_CFG_SPC + (Addr)) /* PCI Config Space */
2080
2081/*
2082 * Macro SK_HW_ADDR(Base, Addr)
2083 *
2084 * Calculates the effective HW address
2085 *
2086 * para:
2087 * Base I/O or memory base address
2088 * Addr Address offset
2089 *
2090 * usage: May be used in SK_INxx and SK_OUTxx macros
2091 * #define SK_IN8(pAC, Addr, pVal) ...\
2092 * *pVal = (SK_U8)inp(SK_HW_ADDR(pAC->Hw.Iop, Addr)))
2093 */
2094#ifdef SK_MEM_MAPPED_IO
2095#define SK_HW_ADDR(Base, Addr) ((Base) + (Addr))
2096#else /* SK_MEM_MAPPED_IO */
2097#define SK_HW_ADDR(Base, Addr) \
2098 ((Base) + (((Addr) & 0x7f) | (((Addr) >> 7 > 0) ? 0x80 : 0)))
2099#endif /* SK_MEM_MAPPED_IO */
2100
2101#define SZ_LONG (sizeof(SK_U32))
2102
2103/*
2104 * Macro SK_HWAC_LINK_LED()
2105 *
2106 * Use this macro to set the link LED mode.
2107 * para:
2108 * pAC Pointer to adapter context struct
2109 * IoC I/O context needed for SK I/O macros
2110 * Port Port number
2111 * Mode Mode to set for this LED
2112 */
2113#define SK_HWAC_LINK_LED(pAC, IoC, Port, Mode) \
2114 SK_OUT8(IoC, MR_ADDR(Port, LNK_LED_REG), Mode);
2115
2116
2117/* typedefs *******************************************************************/
2118
2119
2120/* function prototypes ********************************************************/
2121
2122#ifdef __cplusplus
2123}
2124#endif /* __cplusplus */
2125
2126#endif /* __INC_SKGEHW_H */
diff --git a/drivers/net/sk98lin/h/skgehwt.h b/drivers/net/sk98lin/h/skgehwt.h
new file mode 100644
index 000000000000..e6b0016a695c
--- /dev/null
+++ b/drivers/net/sk98lin/h/skgehwt.h
@@ -0,0 +1,48 @@
1/******************************************************************************
2 *
3 * Name: skhwt.h
4 * Project: Gigabit Ethernet Adapters, Event Scheduler Module
5 * Version: $Revision: 1.7 $
6 * Date: $Date: 2003/09/16 12:55:08 $
7 * Purpose: Defines for the hardware timer functions
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * SKGEHWT.H contains all defines and types for the timer functions
27 */
28
29#ifndef _SKGEHWT_H_
30#define _SKGEHWT_H_
31
32/*
33 * SK Hardware Timer
34 * - needed wherever the HWT module is used
35 * - use in Adapters context name pAC->Hwt
36 */
37typedef struct s_Hwt {
38 SK_U32 TStart; /* HWT start */
39 SK_U32 TStop; /* HWT stop */
40 int TActive; /* HWT: flag : active/inactive */
41} SK_HWT;
42
43extern void SkHwtInit(SK_AC *pAC, SK_IOC Ioc);
44extern void SkHwtStart(SK_AC *pAC, SK_IOC Ioc, SK_U32 Time);
45extern void SkHwtStop(SK_AC *pAC, SK_IOC Ioc);
46extern SK_U32 SkHwtRead(SK_AC *pAC, SK_IOC Ioc);
47extern void SkHwtIsr(SK_AC *pAC, SK_IOC Ioc);
48#endif /* _SKGEHWT_H_ */
diff --git a/drivers/net/sk98lin/h/skgei2c.h b/drivers/net/sk98lin/h/skgei2c.h
new file mode 100644
index 000000000000..d9b6f6d8dfe2
--- /dev/null
+++ b/drivers/net/sk98lin/h/skgei2c.h
@@ -0,0 +1,210 @@
1/******************************************************************************
2 *
3 * Name: skgei2c.h
4 * Project: Gigabit Ethernet Adapters, TWSI-Module
5 * Version: $Revision: 1.25 $
6 * Date: $Date: 2003/10/20 09:06:05 $
7 * Purpose: Special defines for TWSI
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * SKGEI2C.H contains all SK-98xx specific defines for the TWSI handling
27 */
28
29#ifndef _INC_SKGEI2C_H_
30#define _INC_SKGEI2C_H_
31
32/*
33 * Macros to access the B2_I2C_CTRL
34 */
35#define SK_I2C_CTL(IoC, flag, dev, dev_size, reg, burst) \
36 SK_OUT32(IoC, B2_I2C_CTRL,\
37 (flag ? 0x80000000UL : 0x0L) | \
38 (((SK_U32)reg << 16) & I2C_ADDR) | \
39 (((SK_U32)dev << 9) & I2C_DEV_SEL) | \
40 (dev_size & I2C_DEV_SIZE) | \
41 ((burst << 4) & I2C_BURST_LEN))
42
43#define SK_I2C_STOP(IoC) { \
44 SK_U32 I2cCtrl; \
45 SK_IN32(IoC, B2_I2C_CTRL, &I2cCtrl); \
46 SK_OUT32(IoC, B2_I2C_CTRL, I2cCtrl | I2C_STOP); \
47}
48
49#define SK_I2C_GET_CTL(IoC, pI2cCtrl) SK_IN32(IoC, B2_I2C_CTRL, pI2cCtrl)
50
51/*
52 * Macros to access the TWSI SW Registers
53 */
54#define SK_I2C_SET_BIT(IoC, SetBits) { \
55 SK_U8 OrgBits; \
56 SK_IN8(IoC, B2_I2C_SW, &OrgBits); \
57 SK_OUT8(IoC, B2_I2C_SW, OrgBits | (SK_U8)(SetBits)); \
58}
59
60#define SK_I2C_CLR_BIT(IoC, ClrBits) { \
61 SK_U8 OrgBits; \
62 SK_IN8(IoC, B2_I2C_SW, &OrgBits); \
63 SK_OUT8(IoC, B2_I2C_SW, OrgBits & ~((SK_U8)(ClrBits))); \
64}
65
66#define SK_I2C_GET_SW(IoC, pI2cSw) SK_IN8(IoC, B2_I2C_SW, pI2cSw)
67
68/*
69 * define the possible sensor states
70 */
71#define SK_SEN_IDLE 0 /* Idle: sensor not read */
72#define SK_SEN_VALUE 1 /* Value Read cycle */
73#define SK_SEN_VALEXT 2 /* Extended Value Read cycle */
74
75/*
76 * Conversion factor to convert read Voltage sensor to milli Volt
77 * Conversion factor to convert read Temperature sensor to 10th degree Celsius
78 */
79#define SK_LM80_VT_LSB 22 /* 22mV LSB resolution */
80#define SK_LM80_TEMP_LSB 10 /* 1 degree LSB resolution */
81#define SK_LM80_TEMPEXT_LSB 5 /* 0.5 degree LSB resolution for ext. val. */
82
83/*
84 * formula: counter = (22500*60)/(rpm * divisor * pulses/2)
85 * assuming: 6500rpm, 4 pulses, divisor 1
86 */
87#define SK_LM80_FAN_FAKTOR ((22500L*60)/(1*2))
88
89/*
90 * Define sensor management data
91 * Maximum is reached on Genesis copper dual port and Yukon-64
92 * Board specific maximum is in pAC->I2c.MaxSens
93 */
94#define SK_MAX_SENSORS 8 /* maximal no. of installed sensors */
95#define SK_MIN_SENSORS 5 /* minimal no. of installed sensors */
96
97/*
98 * To watch the state machine (SM) use the timer in two ways
99 * instead of one as hitherto
100 */
101#define SK_TIMER_WATCH_SM 0 /* Watch the SM to finish in a spec. time */
102#define SK_TIMER_NEW_GAUGING 1 /* Start a new gauging when timer expires */
103
104/*
105 * Defines for the individual thresholds
106 */
107
108/* Temperature sensor */
109#define SK_SEN_TEMP_HIGH_ERR 800 /* Temperature High Err Threshold */
110#define SK_SEN_TEMP_HIGH_WARN 700 /* Temperature High Warn Threshold */
111#define SK_SEN_TEMP_LOW_WARN 100 /* Temperature Low Warn Threshold */
112#define SK_SEN_TEMP_LOW_ERR 0 /* Temperature Low Err Threshold */
113
114/* VCC which should be 5 V */
115#define SK_SEN_PCI_5V_HIGH_ERR 5588 /* Voltage PCI High Err Threshold */
116#define SK_SEN_PCI_5V_HIGH_WARN 5346 /* Voltage PCI High Warn Threshold */
117#define SK_SEN_PCI_5V_LOW_WARN 4664 /* Voltage PCI Low Warn Threshold */
118#define SK_SEN_PCI_5V_LOW_ERR 4422 /* Voltage PCI Low Err Threshold */
119
120/*
121 * VIO may be 5 V or 3.3 V. Initialization takes two parts:
122 * 1. Initialize lowest lower limit and highest higher limit.
123 * 2. After the first value is read correct the upper or the lower limit to
124 * the appropriate C constant.
125 *
126 * Warning limits are +-5% of the exepected voltage.
127 * Error limits are +-10% of the expected voltage.
128 */
129
130/* Bug fix AF: 16.Aug.2001: Correct the init base of LM80 sensor */
131
132#define SK_SEN_PCI_IO_5V_HIGH_ERR 5566 /* + 10% V PCI-IO High Err Threshold */
133#define SK_SEN_PCI_IO_5V_HIGH_WARN 5324 /* + 5% V PCI-IO High Warn Threshold */
134 /* 5000 mVolt */
135#define SK_SEN_PCI_IO_5V_LOW_WARN 4686 /* - 5% V PCI-IO Low Warn Threshold */
136#define SK_SEN_PCI_IO_5V_LOW_ERR 4444 /* - 10% V PCI-IO Low Err Threshold */
137
138#define SK_SEN_PCI_IO_RANGE_LIMITER 4000 /* 4000 mV range delimiter */
139
140/* correction values for the second pass */
141#define SK_SEN_PCI_IO_3V3_HIGH_ERR 3850 /* + 15% V PCI-IO High Err Threshold */
142#define SK_SEN_PCI_IO_3V3_HIGH_WARN 3674 /* + 10% V PCI-IO High Warn Threshold */
143 /* 3300 mVolt */
144#define SK_SEN_PCI_IO_3V3_LOW_WARN 2926 /* - 10% V PCI-IO Low Warn Threshold */
145#define SK_SEN_PCI_IO_3V3_LOW_ERR 2772 /* - 15% V PCI-IO Low Err Threshold */
146
147/*
148 * VDD voltage
149 */
150#define SK_SEN_VDD_HIGH_ERR 3630 /* Voltage ASIC High Err Threshold */
151#define SK_SEN_VDD_HIGH_WARN 3476 /* Voltage ASIC High Warn Threshold */
152#define SK_SEN_VDD_LOW_WARN 3146 /* Voltage ASIC Low Warn Threshold */
153#define SK_SEN_VDD_LOW_ERR 2970 /* Voltage ASIC Low Err Threshold */
154
155/*
156 * PHY PLL 3V3 voltage
157 */
158#define SK_SEN_PLL_3V3_HIGH_ERR 3630 /* Voltage PMA High Err Threshold */
159#define SK_SEN_PLL_3V3_HIGH_WARN 3476 /* Voltage PMA High Warn Threshold */
160#define SK_SEN_PLL_3V3_LOW_WARN 3146 /* Voltage PMA Low Warn Threshold */
161#define SK_SEN_PLL_3V3_LOW_ERR 2970 /* Voltage PMA Low Err Threshold */
162
163/*
164 * VAUX (YUKON only)
165 */
166#define SK_SEN_VAUX_3V3_HIGH_ERR 3630 /* Voltage VAUX High Err Threshold */
167#define SK_SEN_VAUX_3V3_HIGH_WARN 3476 /* Voltage VAUX High Warn Threshold */
168#define SK_SEN_VAUX_3V3_LOW_WARN 3146 /* Voltage VAUX Low Warn Threshold */
169#define SK_SEN_VAUX_3V3_LOW_ERR 2970 /* Voltage VAUX Low Err Threshold */
170#define SK_SEN_VAUX_0V_WARN_ERR 0 /* if VAUX not present */
171#define SK_SEN_VAUX_RANGE_LIMITER 1000 /* 1000 mV range delimiter */
172
173/*
174 * PHY 2V5 voltage
175 */
176#define SK_SEN_PHY_2V5_HIGH_ERR 2750 /* Voltage PHY High Err Threshold */
177#define SK_SEN_PHY_2V5_HIGH_WARN 2640 /* Voltage PHY High Warn Threshold */
178#define SK_SEN_PHY_2V5_LOW_WARN 2376 /* Voltage PHY Low Warn Threshold */
179#define SK_SEN_PHY_2V5_LOW_ERR 2222 /* Voltage PHY Low Err Threshold */
180
181/*
182 * ASIC Core 1V5 voltage (YUKON only)
183 */
184#define SK_SEN_CORE_1V5_HIGH_ERR 1650 /* Voltage ASIC Core High Err Threshold */
185#define SK_SEN_CORE_1V5_HIGH_WARN 1575 /* Voltage ASIC Core High Warn Threshold */
186#define SK_SEN_CORE_1V5_LOW_WARN 1425 /* Voltage ASIC Core Low Warn Threshold */
187#define SK_SEN_CORE_1V5_LOW_ERR 1350 /* Voltage ASIC Core Low Err Threshold */
188
189/*
190 * FAN 1 speed
191 */
192/* assuming: 6500rpm +-15%, 4 pulses,
193 * warning at: 80 %
194 * error at: 70 %
195 * no upper limit
196 */
197#define SK_SEN_FAN_HIGH_ERR 20000 /* FAN Speed High Err Threshold */
198#define SK_SEN_FAN_HIGH_WARN 20000 /* FAN Speed High Warn Threshold */
199#define SK_SEN_FAN_LOW_WARN 5200 /* FAN Speed Low Warn Threshold */
200#define SK_SEN_FAN_LOW_ERR 4550 /* FAN Speed Low Err Threshold */
201
202/*
203 * Some Voltages need dynamic thresholds
204 */
205#define SK_SEN_DYN_INIT_NONE 0 /* No dynamic init of thresholds */
206#define SK_SEN_DYN_INIT_PCI_IO 10 /* Init PCI-IO with new thresholds */
207#define SK_SEN_DYN_INIT_VAUX 11 /* Init VAUX with new thresholds */
208
209extern int SkLm80ReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen);
210#endif /* n_INC_SKGEI2C_H */
diff --git a/drivers/net/sk98lin/h/skgeinit.h b/drivers/net/sk98lin/h/skgeinit.h
new file mode 100644
index 000000000000..184f47c5a60f
--- /dev/null
+++ b/drivers/net/sk98lin/h/skgeinit.h
@@ -0,0 +1,853 @@
1/******************************************************************************
2 *
3 * Name: skgeinit.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.83 $
6 * Date: $Date: 2003/09/16 14:07:37 $
7 * Purpose: Structures and prototypes for the GE Init Module
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef __INC_SKGEINIT_H_
26#define __INC_SKGEINIT_H_
27
28#ifdef __cplusplus
29extern "C" {
30#endif /* __cplusplus */
31
32/* defines ********************************************************************/
33
34#define SK_TEST_VAL 0x11335577UL
35
36/* modifying Link LED behaviour (used with SkGeLinkLED()) */
37#define SK_LNK_OFF LED_OFF
38#define SK_LNK_ON (LED_ON | LED_BLK_OFF | LED_SYNC_OFF)
39#define SK_LNK_BLINK (LED_ON | LED_BLK_ON | LED_SYNC_ON)
40#define SK_LNK_PERM (LED_ON | LED_BLK_OFF | LED_SYNC_ON)
41#define SK_LNK_TST (LED_ON | LED_BLK_ON | LED_SYNC_OFF)
42
43/* parameter 'Mode' when calling SK_HWAC_LINK_LED() */
44#define SK_LED_OFF LED_OFF
45#define SK_LED_ACTIVE (LED_ON | LED_BLK_OFF | LED_SYNC_OFF)
46#define SK_LED_STANDBY (LED_ON | LED_BLK_ON | LED_SYNC_OFF)
47
48/* addressing LED Registers in SkGeXmitLED() */
49#define XMIT_LED_INI 0
50#define XMIT_LED_CNT (RX_LED_VAL - RX_LED_INI)
51#define XMIT_LED_CTRL (RX_LED_CTRL- RX_LED_INI)
52#define XMIT_LED_TST (RX_LED_TST - RX_LED_INI)
53
54/* parameter 'Mode' when calling SkGeXmitLED() */
55#define SK_LED_DIS 0
56#define SK_LED_ENA 1
57#define SK_LED_TST 2
58
59/* Counter and Timer constants, for a host clock of 62.5 MHz */
60#define SK_XMIT_DUR 0x002faf08UL /* 50 ms */
61#define SK_BLK_DUR 0x01dcd650UL /* 500 ms */
62
63#define SK_DPOLL_DEF 0x00ee6b28UL /* 250 ms at 62.5 MHz */
64
65#define SK_DPOLL_MAX 0x00ffffffUL /* 268 ms at 62.5 MHz */
66 /* 215 ms at 78.12 MHz */
67
68#define SK_FACT_62 100 /* is given in percent */
69#define SK_FACT_53 85 /* on GENESIS: 53.12 MHz */
70#define SK_FACT_78 125 /* on YUKON: 78.12 MHz */
71
72/* Timeout values */
73#define SK_MAC_TO_53 72 /* MAC arbiter timeout */
74#define SK_PKT_TO_53 0x2000 /* Packet arbiter timeout */
75#define SK_PKT_TO_MAX 0xffff /* Maximum value */
76#define SK_RI_TO_53 36 /* RAM interface timeout */
77
78#define SK_PHY_ACC_TO 600000 /* PHY access timeout */
79
80/* RAM Buffer High Pause Threshold values */
81#define SK_RB_ULPP ( 8 * 1024) /* Upper Level in kB/8 */
82#define SK_RB_LLPP_S (10 * 1024) /* Lower Level for small Queues */
83#define SK_RB_LLPP_B (16 * 1024) /* Lower Level for big Queues */
84
85#ifndef SK_BMU_RX_WM
86#define SK_BMU_RX_WM 0x600 /* BMU Rx Watermark */
87#endif
88#ifndef SK_BMU_TX_WM
89#define SK_BMU_TX_WM 0x600 /* BMU Tx Watermark */
90#endif
91
92/* XMAC II Rx High Watermark */
93#define SK_XM_RX_HI_WM 0x05aa /* 1450 */
94
95/* XMAC II Tx Threshold */
96#define SK_XM_THR_REDL 0x01fb /* .. for redundant link usage */
97#define SK_XM_THR_SL 0x01fb /* .. for single link adapters */
98#define SK_XM_THR_MULL 0x01fb /* .. for multiple link usage */
99#define SK_XM_THR_JUMBO 0x03fc /* .. for jumbo frame usage */
100
101/* values for GIPortUsage */
102#define SK_RED_LINK 1 /* redundant link usage */
103#define SK_MUL_LINK 2 /* multiple link usage */
104#define SK_JUMBO_LINK 3 /* driver uses jumbo frames */
105
106/* Minimum RAM Buffer Rx Queue Size */
107#define SK_MIN_RXQ_SIZE 16 /* 16 kB */
108
109/* Minimum RAM Buffer Tx Queue Size */
110#define SK_MIN_TXQ_SIZE 16 /* 16 kB */
111
112/* Queue Size units */
113#define QZ_UNITS 0x7
114#define QZ_STEP 8
115
116/* Percentage of queue size from whole memory */
117/* 80 % for receive */
118#define RAM_QUOTA_RX 80L
119/* 0% for sync transfer */
120#define RAM_QUOTA_SYNC 0L
121/* the rest (20%) is taken for async transfer */
122
123/* Get the rounded queue size in Bytes in 8k steps */
124#define ROUND_QUEUE_SIZE(SizeInBytes) \
125 ((((unsigned long) (SizeInBytes) + (QZ_STEP*1024L)-1) / 1024) & \
126 ~(QZ_STEP-1))
127
128/* Get the rounded queue size in KBytes in 8k steps */
129#define ROUND_QUEUE_SIZE_KB(Kilobytes) \
130 ROUND_QUEUE_SIZE((Kilobytes) * 1024L)
131
132/* Types of RAM Buffer Queues */
133#define SK_RX_SRAM_Q 1 /* small receive queue */
134#define SK_RX_BRAM_Q 2 /* big receive queue */
135#define SK_TX_RAM_Q 3 /* small or big transmit queue */
136
137/* parameter 'Dir' when calling SkGeStopPort() */
138#define SK_STOP_TX 1 /* Stops the transmit path, resets the XMAC */
139#define SK_STOP_RX 2 /* Stops the receive path */
140#define SK_STOP_ALL 3 /* Stops Rx and Tx path, resets the XMAC */
141
142/* parameter 'RstMode' when calling SkGeStopPort() */
143#define SK_SOFT_RST 1 /* perform a software reset */
144#define SK_HARD_RST 2 /* perform a hardware reset */
145
146/* Init Levels */
147#define SK_INIT_DATA 0 /* Init level 0: init data structures */
148#define SK_INIT_IO 1 /* Init level 1: init with IOs */
149#define SK_INIT_RUN 2 /* Init level 2: init for run time */
150
151/* Link Mode Parameter */
152#define SK_LMODE_HALF 1 /* Half Duplex Mode */
153#define SK_LMODE_FULL 2 /* Full Duplex Mode */
154#define SK_LMODE_AUTOHALF 3 /* AutoHalf Duplex Mode */
155#define SK_LMODE_AUTOFULL 4 /* AutoFull Duplex Mode */
156#define SK_LMODE_AUTOBOTH 5 /* AutoBoth Duplex Mode */
157#define SK_LMODE_AUTOSENSE 6 /* configured mode auto sensing */
158#define SK_LMODE_INDETERMINATED 7 /* indeterminated */
159
160/* Auto-negotiation timeout in 100ms granularity */
161#define SK_AND_MAX_TO 6 /* Wait 600 msec before link comes up */
162
163/* Auto-negotiation error codes */
164#define SK_AND_OK 0 /* no error */
165#define SK_AND_OTHER 1 /* other error than below */
166#define SK_AND_DUP_CAP 2 /* Duplex capabilities error */
167
168
169/* Link Speed Capabilities */
170#define SK_LSPEED_CAP_AUTO (1<<0) /* Automatic resolution */
171#define SK_LSPEED_CAP_10MBPS (1<<1) /* 10 Mbps */
172#define SK_LSPEED_CAP_100MBPS (1<<2) /* 100 Mbps */
173#define SK_LSPEED_CAP_1000MBPS (1<<3) /* 1000 Mbps */
174#define SK_LSPEED_CAP_INDETERMINATED (1<<4) /* indeterminated */
175
176/* Link Speed Parameter */
177#define SK_LSPEED_AUTO 1 /* Automatic resolution */
178#define SK_LSPEED_10MBPS 2 /* 10 Mbps */
179#define SK_LSPEED_100MBPS 3 /* 100 Mbps */
180#define SK_LSPEED_1000MBPS 4 /* 1000 Mbps */
181#define SK_LSPEED_INDETERMINATED 5 /* indeterminated */
182
183/* Link Speed Current State */
184#define SK_LSPEED_STAT_UNKNOWN 1
185#define SK_LSPEED_STAT_10MBPS 2
186#define SK_LSPEED_STAT_100MBPS 3
187#define SK_LSPEED_STAT_1000MBPS 4
188#define SK_LSPEED_STAT_INDETERMINATED 5
189
190
191/* Link Capability Parameter */
192#define SK_LMODE_CAP_HALF (1<<0) /* Half Duplex Mode */
193#define SK_LMODE_CAP_FULL (1<<1) /* Full Duplex Mode */
194#define SK_LMODE_CAP_AUTOHALF (1<<2) /* AutoHalf Duplex Mode */
195#define SK_LMODE_CAP_AUTOFULL (1<<3) /* AutoFull Duplex Mode */
196#define SK_LMODE_CAP_INDETERMINATED (1<<4) /* indeterminated */
197
198/* Link Mode Current State */
199#define SK_LMODE_STAT_UNKNOWN 1 /* Unknown Duplex Mode */
200#define SK_LMODE_STAT_HALF 2 /* Half Duplex Mode */
201#define SK_LMODE_STAT_FULL 3 /* Full Duplex Mode */
202#define SK_LMODE_STAT_AUTOHALF 4 /* Half Duplex Mode obtained by Auto-Neg */
203#define SK_LMODE_STAT_AUTOFULL 5 /* Full Duplex Mode obtained by Auto-Neg */
204#define SK_LMODE_STAT_INDETERMINATED 6 /* indeterminated */
205
206/* Flow Control Mode Parameter (and capabilities) */
207#define SK_FLOW_MODE_NONE 1 /* No Flow-Control */
208#define SK_FLOW_MODE_LOC_SEND 2 /* Local station sends PAUSE */
209#define SK_FLOW_MODE_SYMMETRIC 3 /* Both stations may send PAUSE */
210#define SK_FLOW_MODE_SYM_OR_REM 4 /* Both stations may send PAUSE or
211 * just the remote station may send PAUSE
212 */
213#define SK_FLOW_MODE_INDETERMINATED 5 /* indeterminated */
214
215/* Flow Control Status Parameter */
216#define SK_FLOW_STAT_NONE 1 /* No Flow Control */
217#define SK_FLOW_STAT_REM_SEND 2 /* Remote Station sends PAUSE */
218#define SK_FLOW_STAT_LOC_SEND 3 /* Local station sends PAUSE */
219#define SK_FLOW_STAT_SYMMETRIC 4 /* Both station may send PAUSE */
220#define SK_FLOW_STAT_INDETERMINATED 5 /* indeterminated */
221
222/* Master/Slave Mode Capabilities */
223#define SK_MS_CAP_AUTO (1<<0) /* Automatic resolution */
224#define SK_MS_CAP_MASTER (1<<1) /* This station is master */
225#define SK_MS_CAP_SLAVE (1<<2) /* This station is slave */
226#define SK_MS_CAP_INDETERMINATED (1<<3) /* indeterminated */
227
228/* Set Master/Slave Mode Parameter (and capabilities) */
229#define SK_MS_MODE_AUTO 1 /* Automatic resolution */
230#define SK_MS_MODE_MASTER 2 /* This station is master */
231#define SK_MS_MODE_SLAVE 3 /* This station is slave */
232#define SK_MS_MODE_INDETERMINATED 4 /* indeterminated */
233
234/* Master/Slave Status Parameter */
235#define SK_MS_STAT_UNSET 1 /* The M/S status is not set */
236#define SK_MS_STAT_MASTER 2 /* This station is master */
237#define SK_MS_STAT_SLAVE 3 /* This station is slave */
238#define SK_MS_STAT_FAULT 4 /* M/S resolution failed */
239#define SK_MS_STAT_INDETERMINATED 5 /* indeterminated */
240
241/* parameter 'Mode' when calling SkXmSetRxCmd() */
242#define SK_STRIP_FCS_ON (1<<0) /* Enable FCS stripping of Rx frames */
243#define SK_STRIP_FCS_OFF (1<<1) /* Disable FCS stripping of Rx frames */
244#define SK_STRIP_PAD_ON (1<<2) /* Enable pad byte stripping of Rx fr */
245#define SK_STRIP_PAD_OFF (1<<3) /* Disable pad byte stripping of Rx fr */
246#define SK_LENERR_OK_ON (1<<4) /* Don't chk fr for in range len error */
247#define SK_LENERR_OK_OFF (1<<5) /* Check frames for in range len error */
248#define SK_BIG_PK_OK_ON (1<<6) /* Don't set Rx Error bit for big frames */
249#define SK_BIG_PK_OK_OFF (1<<7) /* Set Rx Error bit for big frames */
250#define SK_SELF_RX_ON (1<<8) /* Enable Rx of own packets */
251#define SK_SELF_RX_OFF (1<<9) /* Disable Rx of own packets */
252
253/* parameter 'Para' when calling SkMacSetRxTxEn() */
254#define SK_MAC_LOOPB_ON (1<<0) /* Enable MAC Loopback Mode */
255#define SK_MAC_LOOPB_OFF (1<<1) /* Disable MAC Loopback Mode */
256#define SK_PHY_LOOPB_ON (1<<2) /* Enable PHY Loopback Mode */
257#define SK_PHY_LOOPB_OFF (1<<3) /* Disable PHY Loopback Mode */
258#define SK_PHY_FULLD_ON (1<<4) /* Enable GMII Full Duplex */
259#define SK_PHY_FULLD_OFF (1<<5) /* Disable GMII Full Duplex */
260
261/* States of PState */
262#define SK_PRT_RESET 0 /* the port is reset */
263#define SK_PRT_STOP 1 /* the port is stopped (similar to SW reset) */
264#define SK_PRT_INIT 2 /* the port is initialized */
265#define SK_PRT_RUN 3 /* the port has an active link */
266
267/* PHY power down modes */
268#define PHY_PM_OPERATIONAL_MODE 0 /* PHY operational mode */
269#define PHY_PM_DEEP_SLEEP 1 /* coma mode --> minimal power */
270#define PHY_PM_IEEE_POWER_DOWN 2 /* IEEE 22.2.4.1.5 compl. power down */
271#define PHY_PM_ENERGY_DETECT 3 /* energy detect */
272#define PHY_PM_ENERGY_DETECT_PLUS 4 /* energy detect plus */
273
274/* Default receive frame limit for Workaround of XMAC Errata */
275#define SK_DEF_RX_WA_LIM SK_CONSTU64(100)
276
277/* values for GILedBlinkCtrl (LED Blink Control) */
278#define SK_ACT_LED_BLINK (1<<0) /* Active LED blinking */
279#define SK_DUP_LED_NORMAL (1<<1) /* Duplex LED normal */
280#define SK_LED_LINK100_ON (1<<2) /* Link 100M LED on */
281
282/* Link Partner Status */
283#define SK_LIPA_UNKNOWN 0 /* Link partner is in unknown state */
284#define SK_LIPA_MANUAL 1 /* Link partner is in detected manual state */
285#define SK_LIPA_AUTO 2 /* Link partner is in auto-negotiation state */
286
287/* Maximum Restarts before restart is ignored (3Com WA) */
288#define SK_MAX_LRESTART 3 /* Max. 3 times the link is restarted */
289
290/* Max. Auto-neg. timeouts before link detection in sense mode is reset */
291#define SK_MAX_ANEG_TO 10 /* Max. 10 times the sense mode is reset */
292
293/* structures *****************************************************************/
294
295/*
296 * MAC specific functions
297 */
298typedef struct s_GeMacFunc {
299 int (*pFnMacUpdateStats)(SK_AC *pAC, SK_IOC IoC, unsigned int Port);
300 int (*pFnMacStatistic)(SK_AC *pAC, SK_IOC IoC, unsigned int Port,
301 SK_U16 StatAddr, SK_U32 SK_FAR *pVal);
302 int (*pFnMacResetCounter)(SK_AC *pAC, SK_IOC IoC, unsigned int Port);
303 int (*pFnMacOverflow)(SK_AC *pAC, SK_IOC IoC, unsigned int Port,
304 SK_U16 IStatus, SK_U64 SK_FAR *pVal);
305} SK_GEMACFUNC;
306
307/*
308 * Port Structure
309 */
310typedef struct s_GePort {
311#ifndef SK_DIAG
312 SK_TIMER PWaTimer; /* Workaround Timer */
313 SK_TIMER HalfDupChkTimer;
314#endif /* SK_DIAG */
315 SK_U32 PPrevShorts; /* Previous Short Counter checking */
316 SK_U32 PPrevFcs; /* Previous FCS Error Counter checking */
317 SK_U64 PPrevRx; /* Previous RxOk Counter checking */
318 SK_U64 PRxLim; /* Previous RxOk Counter checking */
319 SK_U64 LastOctets; /* For half duplex hang check */
320 int PLinkResCt; /* Link Restart Counter */
321 int PAutoNegTimeOut;/* Auto-negotiation timeout current value */
322 int PAutoNegTOCt; /* Auto-negotiation Timeout Counter */
323 int PRxQSize; /* Port Rx Queue Size in kB */
324 int PXSQSize; /* Port Synchronous Transmit Queue Size in kB */
325 int PXAQSize; /* Port Asynchronous Transmit Queue Size in kB */
326 SK_U32 PRxQRamStart; /* Receive Queue RAM Buffer Start Address */
327 SK_U32 PRxQRamEnd; /* Receive Queue RAM Buffer End Address */
328 SK_U32 PXsQRamStart; /* Sync Tx Queue RAM Buffer Start Address */
329 SK_U32 PXsQRamEnd; /* Sync Tx Queue RAM Buffer End Address */
330 SK_U32 PXaQRamStart; /* Async Tx Queue RAM Buffer Start Address */
331 SK_U32 PXaQRamEnd; /* Async Tx Queue RAM Buffer End Address */
332 SK_U32 PRxOverCnt; /* Receive Overflow Counter */
333 int PRxQOff; /* Rx Queue Address Offset */
334 int PXsQOff; /* Synchronous Tx Queue Address Offset */
335 int PXaQOff; /* Asynchronous Tx Queue Address Offset */
336 int PhyType; /* PHY used on this port */
337 int PState; /* Port status (reset, stop, init, run) */
338 SK_U16 PhyId1; /* PHY Id1 on this port */
339 SK_U16 PhyAddr; /* MDIO/MDC PHY address */
340 SK_U16 PIsave; /* Saved Interrupt status word */
341 SK_U16 PSsave; /* Saved PHY status word */
342 SK_U16 PGmANegAdv; /* Saved GPhy AutoNegAdvertisment register */
343 SK_BOOL PHWLinkUp; /* The hardware Link is up (wiring) */
344 SK_BOOL PLinkBroken; /* Is Link broken ? */
345 SK_BOOL PCheckPar; /* Do we check for parity errors ? */
346 SK_BOOL HalfDupTimerActive;
347 SK_U8 PLinkCap; /* Link Capabilities */
348 SK_U8 PLinkModeConf; /* Link Mode configured */
349 SK_U8 PLinkMode; /* Link Mode currently used */
350 SK_U8 PLinkModeStatus;/* Link Mode Status */
351 SK_U8 PLinkSpeedCap; /* Link Speed Capabilities(10/100/1000 Mbps) */
352 SK_U8 PLinkSpeed; /* configured Link Speed (10/100/1000 Mbps) */
353 SK_U8 PLinkSpeedUsed; /* current Link Speed (10/100/1000 Mbps) */
354 SK_U8 PFlowCtrlCap; /* Flow Control Capabilities */
355 SK_U8 PFlowCtrlMode; /* Flow Control Mode */
356 SK_U8 PFlowCtrlStatus;/* Flow Control Status */
357 SK_U8 PMSCap; /* Master/Slave Capabilities */
358 SK_U8 PMSMode; /* Master/Slave Mode */
359 SK_U8 PMSStatus; /* Master/Slave Status */
360 SK_BOOL PAutoNegFail; /* Auto-negotiation fail flag */
361 SK_U8 PLipaAutoNeg; /* Auto-negotiation possible with Link Partner */
362 SK_U8 PCableLen; /* Cable Length */
363 SK_U8 PMdiPairLen[4]; /* MDI[0..3] Pair Length */
364 SK_U8 PMdiPairSts[4]; /* MDI[0..3] Pair Diagnostic Status */
365 SK_U8 PPhyPowerState; /* PHY current power state */
366 int PMacColThres; /* MAC Collision Threshold */
367 int PMacJamLen; /* MAC Jam length */
368 int PMacJamIpgVal; /* MAC Jam IPG */
369 int PMacJamIpgData; /* MAC IPG Jam to Data */
370 int PMacIpgData; /* MAC Data IPG */
371 SK_BOOL PMacLimit4; /* reset collision counter and backoff algorithm */
372} SK_GEPORT;
373
374/*
375 * Gigabit Ethernet Initialization Struct
376 * (has to be included in the adapter context)
377 */
378typedef struct s_GeInit {
379 int GIChipId; /* Chip Identification Number */
380 int GIChipRev; /* Chip Revision Number */
381 SK_U8 GIPciHwRev; /* PCI HW Revision Number */
382 SK_BOOL GIGenesis; /* Genesis adapter ? */
383 SK_BOOL GIYukon; /* YUKON-A1/Bx chip */
384 SK_BOOL GIYukonLite; /* YUKON-Lite chip */
385 SK_BOOL GICopperType; /* Copper Type adapter ? */
386 SK_BOOL GIPciSlot64; /* 64-bit PCI Slot */
387 SK_BOOL GIPciClock66; /* 66 MHz PCI Clock */
388 SK_BOOL GIVauxAvail; /* VAUX available (YUKON) */
389 SK_BOOL GIYukon32Bit; /* 32-Bit YUKON adapter */
390 SK_U16 GILedBlinkCtrl; /* LED Blink Control */
391 int GIMacsFound; /* Number of MACs found on this adapter */
392 int GIMacType; /* MAC Type used on this adapter */
393 int GIHstClkFact; /* Host Clock Factor (62.5 / HstClk * 100) */
394 int GIPortUsage; /* Driver Port Usage */
395 int GILevel; /* Initialization Level completed */
396 int GIRamSize; /* The RAM size of the adapter in kB */
397 int GIWolOffs; /* WOL Register Offset (HW-Bug in Rev. A) */
398 SK_U32 GIRamOffs; /* RAM Address Offset for addr calculation */
399 SK_U32 GIPollTimerVal; /* Descr. Poll Timer Init Val (HstClk ticks) */
400 SK_U32 GIValIrqMask; /* Value for Interrupt Mask */
401 SK_U32 GITimeStampCnt; /* Time Stamp High Counter (YUKON only) */
402 SK_GEPORT GP[SK_MAX_MACS];/* Port Dependent Information */
403 SK_GEMACFUNC GIFunc; /* MAC depedent functions */
404} SK_GEINIT;
405
406/*
407 * Error numbers and messages for skxmac2.c and skgeinit.c
408 */
409#define SKERR_HWI_E001 (SK_ERRBASE_HWINIT)
410#define SKERR_HWI_E001MSG "SkXmClrExactAddr() has got illegal parameters"
411#define SKERR_HWI_E002 (SKERR_HWI_E001+1)
412#define SKERR_HWI_E002MSG "SkGeInit(): Level 1 call missing"
413#define SKERR_HWI_E003 (SKERR_HWI_E002+1)
414#define SKERR_HWI_E003MSG "SkGeInit() called with illegal init Level"
415#define SKERR_HWI_E004 (SKERR_HWI_E003+1)
416#define SKERR_HWI_E004MSG "SkGeInitPort(): Queue Size illegal configured"
417#define SKERR_HWI_E005 (SKERR_HWI_E004+1)
418#define SKERR_HWI_E005MSG "SkGeInitPort(): cannot init running ports"
419#define SKERR_HWI_E006 (SKERR_HWI_E005+1)
420#define SKERR_HWI_E006MSG "SkGeMacInit(): PState does not match HW state"
421#define SKERR_HWI_E007 (SKERR_HWI_E006+1)
422#define SKERR_HWI_E007MSG "SkXmInitDupMd() called with invalid Dup Mode"
423#define SKERR_HWI_E008 (SKERR_HWI_E007+1)
424#define SKERR_HWI_E008MSG "SkXmSetRxCmd() called with invalid Mode"
425#define SKERR_HWI_E009 (SKERR_HWI_E008+1)
426#define SKERR_HWI_E009MSG "SkGeCfgSync() called although PXSQSize zero"
427#define SKERR_HWI_E010 (SKERR_HWI_E009+1)
428#define SKERR_HWI_E010MSG "SkGeCfgSync() called with invalid parameters"
429#define SKERR_HWI_E011 (SKERR_HWI_E010+1)
430#define SKERR_HWI_E011MSG "SkGeInitPort(): Receive Queue Size too small"
431#define SKERR_HWI_E012 (SKERR_HWI_E011+1)
432#define SKERR_HWI_E012MSG "SkGeInitPort(): invalid Queue Size specified"
433#define SKERR_HWI_E013 (SKERR_HWI_E012+1)
434#define SKERR_HWI_E013MSG "SkGeInitPort(): cfg changed for running queue"
435#define SKERR_HWI_E014 (SKERR_HWI_E013+1)
436#define SKERR_HWI_E014MSG "SkGeInitPort(): unknown GIPortUsage specified"
437#define SKERR_HWI_E015 (SKERR_HWI_E014+1)
438#define SKERR_HWI_E015MSG "Illegal Link mode parameter"
439#define SKERR_HWI_E016 (SKERR_HWI_E015+1)
440#define SKERR_HWI_E016MSG "Illegal Flow control mode parameter"
441#define SKERR_HWI_E017 (SKERR_HWI_E016+1)
442#define SKERR_HWI_E017MSG "Illegal value specified for GIPollTimerVal"
443#define SKERR_HWI_E018 (SKERR_HWI_E017+1)
444#define SKERR_HWI_E018MSG "FATAL: SkGeStopPort() does not terminate (Tx)"
445#define SKERR_HWI_E019 (SKERR_HWI_E018+1)
446#define SKERR_HWI_E019MSG "Illegal Speed parameter"
447#define SKERR_HWI_E020 (SKERR_HWI_E019+1)
448#define SKERR_HWI_E020MSG "Illegal Master/Slave parameter"
449#define SKERR_HWI_E021 (SKERR_HWI_E020+1)
450#define SKERR_HWI_E021MSG "MacUpdateStats(): cannot update statistic counter"
451#define SKERR_HWI_E022 (SKERR_HWI_E021+1)
452#define SKERR_HWI_E022MSG "MacStatistic(): illegal statistic base address"
453#define SKERR_HWI_E023 (SKERR_HWI_E022+1)
454#define SKERR_HWI_E023MSG "SkGeInitPort(): Transmit Queue Size too small"
455#define SKERR_HWI_E024 (SKERR_HWI_E023+1)
456#define SKERR_HWI_E024MSG "FATAL: SkGeStopPort() does not terminate (Rx)"
457#define SKERR_HWI_E025 (SKERR_HWI_E024+1)
458#define SKERR_HWI_E025MSG ""
459
460/* function prototypes ********************************************************/
461
462#ifndef SK_KR_PROTO
463
464/*
465 * public functions in skgeinit.c
466 */
467extern void SkGePollRxD(
468 SK_AC *pAC,
469 SK_IOC IoC,
470 int Port,
471 SK_BOOL PollRxD);
472
473extern void SkGePollTxD(
474 SK_AC *pAC,
475 SK_IOC IoC,
476 int Port,
477 SK_BOOL PollTxD);
478
479extern void SkGeYellowLED(
480 SK_AC *pAC,
481 SK_IOC IoC,
482 int State);
483
484extern int SkGeCfgSync(
485 SK_AC *pAC,
486 SK_IOC IoC,
487 int Port,
488 SK_U32 IntTime,
489 SK_U32 LimCount,
490 int SyncMode);
491
492extern void SkGeLoadLnkSyncCnt(
493 SK_AC *pAC,
494 SK_IOC IoC,
495 int Port,
496 SK_U32 CntVal);
497
498extern void SkGeStopPort(
499 SK_AC *pAC,
500 SK_IOC IoC,
501 int Port,
502 int Dir,
503 int RstMode);
504
505extern int SkGeInit(
506 SK_AC *pAC,
507 SK_IOC IoC,
508 int Level);
509
510extern void SkGeDeInit(
511 SK_AC *pAC,
512 SK_IOC IoC);
513
514extern int SkGeInitPort(
515 SK_AC *pAC,
516 SK_IOC IoC,
517 int Port);
518
519extern void SkGeXmitLED(
520 SK_AC *pAC,
521 SK_IOC IoC,
522 int Led,
523 int Mode);
524
525extern void SkGeInitRamIface(
526 SK_AC *pAC,
527 SK_IOC IoC);
528
529extern int SkGeInitAssignRamToQueues(
530 SK_AC *pAC,
531 int ActivePort,
532 SK_BOOL DualNet);
533
534/*
535 * public functions in skxmac2.c
536 */
537extern void SkMacRxTxDisable(
538 SK_AC *pAC,
539 SK_IOC IoC,
540 int Port);
541
542extern void SkMacSoftRst(
543 SK_AC *pAC,
544 SK_IOC IoC,
545 int Port);
546
547extern void SkMacHardRst(
548 SK_AC *pAC,
549 SK_IOC IoC,
550 int Port);
551
552extern void SkMacClearRst(
553 SK_AC *pAC,
554 SK_IOC IoC,
555 int Port);
556
557extern void SkXmInitMac(
558 SK_AC *pAC,
559 SK_IOC IoC,
560 int Port);
561
562extern void SkGmInitMac(
563 SK_AC *pAC,
564 SK_IOC IoC,
565 int Port);
566
567extern void SkMacInitPhy(
568 SK_AC *pAC,
569 SK_IOC IoC,
570 int Port,
571 SK_BOOL DoLoop);
572
573extern void SkMacIrqDisable(
574 SK_AC *pAC,
575 SK_IOC IoC,
576 int Port);
577
578extern void SkMacFlushTxFifo(
579 SK_AC *pAC,
580 SK_IOC IoC,
581 int Port);
582
583extern void SkMacFlushRxFifo(
584 SK_AC *pAC,
585 SK_IOC IoC,
586 int Port);
587
588extern void SkMacIrq(
589 SK_AC *pAC,
590 SK_IOC IoC,
591 int Port);
592
593extern int SkMacAutoNegDone(
594 SK_AC *pAC,
595 SK_IOC IoC,
596 int Port);
597
598extern void SkMacAutoNegLipaPhy(
599 SK_AC *pAC,
600 SK_IOC IoC,
601 int Port,
602 SK_U16 IStatus);
603
604extern void SkMacSetRxTxEn(
605 SK_AC *pAC,
606 SK_IOC IoC,
607 int Port,
608 int Para);
609
610extern int SkMacRxTxEnable(
611 SK_AC *pAC,
612 SK_IOC IoC,
613 int Port);
614
615extern void SkMacPromiscMode(
616 SK_AC *pAC,
617 SK_IOC IoC,
618 int Port,
619 SK_BOOL Enable);
620
621extern void SkMacHashing(
622 SK_AC *pAC,
623 SK_IOC IoC,
624 int Port,
625 SK_BOOL Enable);
626
627extern void SkXmPhyRead(
628 SK_AC *pAC,
629 SK_IOC IoC,
630 int Port,
631 int Addr,
632 SK_U16 SK_FAR *pVal);
633
634extern void SkXmPhyWrite(
635 SK_AC *pAC,
636 SK_IOC IoC,
637 int Port,
638 int Addr,
639 SK_U16 Val);
640
641extern void SkGmPhyRead(
642 SK_AC *pAC,
643 SK_IOC IoC,
644 int Port,
645 int Addr,
646 SK_U16 SK_FAR *pVal);
647
648extern void SkGmPhyWrite(
649 SK_AC *pAC,
650 SK_IOC IoC,
651 int Port,
652 int Addr,
653 SK_U16 Val);
654
655extern void SkXmClrExactAddr(
656 SK_AC *pAC,
657 SK_IOC IoC,
658 int Port,
659 int StartNum,
660 int StopNum);
661
662extern void SkXmInitDupMd(
663 SK_AC *pAC,
664 SK_IOC IoC,
665 int Port);
666
667extern void SkXmInitPauseMd(
668 SK_AC *pAC,
669 SK_IOC IoC,
670 int Port);
671
672extern void SkXmAutoNegLipaXmac(
673 SK_AC *pAC,
674 SK_IOC IoC,
675 int Port,
676 SK_U16 IStatus);
677
678extern int SkXmUpdateStats(
679 SK_AC *pAC,
680 SK_IOC IoC,
681 unsigned int Port);
682
683extern int SkGmUpdateStats(
684 SK_AC *pAC,
685 SK_IOC IoC,
686 unsigned int Port);
687
688extern int SkXmMacStatistic(
689 SK_AC *pAC,
690 SK_IOC IoC,
691 unsigned int Port,
692 SK_U16 StatAddr,
693 SK_U32 SK_FAR *pVal);
694
695extern int SkGmMacStatistic(
696 SK_AC *pAC,
697 SK_IOC IoC,
698 unsigned int Port,
699 SK_U16 StatAddr,
700 SK_U32 SK_FAR *pVal);
701
702extern int SkXmResetCounter(
703 SK_AC *pAC,
704 SK_IOC IoC,
705 unsigned int Port);
706
707extern int SkGmResetCounter(
708 SK_AC *pAC,
709 SK_IOC IoC,
710 unsigned int Port);
711
712extern int SkXmOverflowStatus(
713 SK_AC *pAC,
714 SK_IOC IoC,
715 unsigned int Port,
716 SK_U16 IStatus,
717 SK_U64 SK_FAR *pStatus);
718
719extern int SkGmOverflowStatus(
720 SK_AC *pAC,
721 SK_IOC IoC,
722 unsigned int Port,
723 SK_U16 MacStatus,
724 SK_U64 SK_FAR *pStatus);
725
726extern int SkGmCableDiagStatus(
727 SK_AC *pAC,
728 SK_IOC IoC,
729 int Port,
730 SK_BOOL StartTest);
731
732extern int SkGmEnterLowPowerMode(
733 SK_AC *pAC,
734 SK_IOC IoC,
735 int Port,
736 SK_U8 Mode);
737
738extern int SkGmLeaveLowPowerMode(
739 SK_AC *pAC,
740 SK_IOC IoC,
741 int Port);
742
743#ifdef SK_DIAG
744extern void SkGePhyRead(
745 SK_AC *pAC,
746 SK_IOC IoC,
747 int Port,
748 int Addr,
749 SK_U16 *pVal);
750
751extern void SkGePhyWrite(
752 SK_AC *pAC,
753 SK_IOC IoC,
754 int Port,
755 int Addr,
756 SK_U16 Val);
757
758extern void SkMacSetRxCmd(
759 SK_AC *pAC,
760 SK_IOC IoC,
761 int Port,
762 int Mode);
763extern void SkMacCrcGener(
764 SK_AC *pAC,
765 SK_IOC IoC,
766 int Port,
767 SK_BOOL Enable);
768extern void SkMacTimeStamp(
769 SK_AC *pAC,
770 SK_IOC IoC,
771 int Port,
772 SK_BOOL Enable);
773extern void SkXmSendCont(
774 SK_AC *pAC,
775 SK_IOC IoC,
776 int Port,
777 SK_BOOL Enable);
778#endif /* SK_DIAG */
779
780#else /* SK_KR_PROTO */
781
782/*
783 * public functions in skgeinit.c
784 */
785extern void SkGePollRxD();
786extern void SkGePollTxD();
787extern void SkGeYellowLED();
788extern int SkGeCfgSync();
789extern void SkGeLoadLnkSyncCnt();
790extern void SkGeStopPort();
791extern int SkGeInit();
792extern void SkGeDeInit();
793extern int SkGeInitPort();
794extern void SkGeXmitLED();
795extern void SkGeInitRamIface();
796extern int SkGeInitAssignRamToQueues();
797
798/*
799 * public functions in skxmac2.c
800 */
801extern void SkMacRxTxDisable();
802extern void SkMacSoftRst();
803extern void SkMacHardRst();
804extern void SkMacClearRst();
805extern void SkMacInitPhy();
806extern int SkMacRxTxEnable();
807extern void SkMacPromiscMode();
808extern void SkMacHashing();
809extern void SkMacIrqDisable();
810extern void SkMacFlushTxFifo();
811extern void SkMacFlushRxFifo();
812extern void SkMacIrq();
813extern int SkMacAutoNegDone();
814extern void SkMacAutoNegLipaPhy();
815extern void SkMacSetRxTxEn();
816extern void SkXmInitMac();
817extern void SkXmPhyRead();
818extern void SkXmPhyWrite();
819extern void SkGmInitMac();
820extern void SkGmPhyRead();
821extern void SkGmPhyWrite();
822extern void SkXmClrExactAddr();
823extern void SkXmInitDupMd();
824extern void SkXmInitPauseMd();
825extern void SkXmAutoNegLipaXmac();
826extern int SkXmUpdateStats();
827extern int SkGmUpdateStats();
828extern int SkXmMacStatistic();
829extern int SkGmMacStatistic();
830extern int SkXmResetCounter();
831extern int SkGmResetCounter();
832extern int SkXmOverflowStatus();
833extern int SkGmOverflowStatus();
834extern int SkGmCableDiagStatus();
835extern int SkGmEnterLowPowerMode();
836extern int SkGmLeaveLowPowerMode();
837
838#ifdef SK_DIAG
839extern void SkGePhyRead();
840extern void SkGePhyWrite();
841extern void SkMacSetRxCmd();
842extern void SkMacCrcGener();
843extern void SkMacTimeStamp();
844extern void SkXmSendCont();
845#endif /* SK_DIAG */
846
847#endif /* SK_KR_PROTO */
848
849#ifdef __cplusplus
850}
851#endif /* __cplusplus */
852
853#endif /* __INC_SKGEINIT_H_ */
diff --git a/drivers/net/sk98lin/h/skgepnm2.h b/drivers/net/sk98lin/h/skgepnm2.h
new file mode 100644
index 000000000000..ddd304f1a48b
--- /dev/null
+++ b/drivers/net/sk98lin/h/skgepnm2.h
@@ -0,0 +1,334 @@
1/*****************************************************************************
2 *
3 * Name: skgepnm2.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.36 $
6 * Date: $Date: 2003/05/23 12:45:13 $
7 * Purpose: Defines for Private Network Management Interface
8 *
9 ****************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef _SKGEPNM2_H_
26#define _SKGEPNM2_H_
27
28/*
29 * General definitions
30 */
31#define SK_PNMI_CHIPSET_XMAC 1 /* XMAC11800FP */
32#define SK_PNMI_CHIPSET_YUKON 2 /* YUKON */
33
34#define SK_PNMI_BUS_PCI 1 /* PCI bus*/
35
36/*
37 * Actions
38 */
39#define SK_PNMI_ACT_IDLE 1
40#define SK_PNMI_ACT_RESET 2
41#define SK_PNMI_ACT_SELFTEST 3
42#define SK_PNMI_ACT_RESETCNT 4
43
44/*
45 * VPD releated defines
46 */
47
48#define SK_PNMI_VPD_RW 1
49#define SK_PNMI_VPD_RO 2
50
51#define SK_PNMI_VPD_OK 0
52#define SK_PNMI_VPD_NOTFOUND 1
53#define SK_PNMI_VPD_CUT 2
54#define SK_PNMI_VPD_TIMEOUT 3
55#define SK_PNMI_VPD_FULL 4
56#define SK_PNMI_VPD_NOWRITE 5
57#define SK_PNMI_VPD_FATAL 6
58
59#define SK_PNMI_VPD_IGNORE 0
60#define SK_PNMI_VPD_CREATE 1
61#define SK_PNMI_VPD_DELETE 2
62
63
64/*
65 * RLMT related defines
66 */
67#define SK_PNMI_DEF_RLMT_CHG_THRES 240 /* 4 changes per minute */
68
69
70/*
71 * VCT internal status values
72 */
73#define SK_PNMI_VCT_PENDING 32
74#define SK_PNMI_VCT_TEST_DONE 64
75#define SK_PNMI_VCT_LINK 128
76
77/*
78 * Internal table definitions
79 */
80#define SK_PNMI_GET 0
81#define SK_PNMI_PRESET 1
82#define SK_PNMI_SET 2
83
84#define SK_PNMI_RO 0
85#define SK_PNMI_RW 1
86#define SK_PNMI_WO 2
87
88typedef struct s_OidTabEntry {
89 SK_U32 Id;
90 SK_U32 InstanceNo;
91 unsigned int StructSize;
92 unsigned int Offset;
93 int Access;
94 int (* Func)(SK_AC *pAc, SK_IOC pIo, int action,
95 SK_U32 Id, char* pBuf, unsigned int* pLen,
96 SK_U32 Instance, unsigned int TableIndex,
97 SK_U32 NetNumber);
98 SK_U16 Param;
99} SK_PNMI_TAB_ENTRY;
100
101
102/*
103 * Trap lengths
104 */
105#define SK_PNMI_TRAP_SIMPLE_LEN 17
106#define SK_PNMI_TRAP_SENSOR_LEN_BASE 46
107#define SK_PNMI_TRAP_RLMT_CHANGE_LEN 23
108#define SK_PNMI_TRAP_RLMT_PORT_LEN 23
109
110/*
111 * Number of MAC types supported
112 */
113#define SK_PNMI_MAC_TYPES (SK_MAC_GMAC + 1)
114
115/*
116 * MAC statistic data list (overall set for MAC types used)
117 */
118enum SK_MACSTATS {
119 SK_PNMI_HTX = 0,
120 SK_PNMI_HTX_OCTET,
121 SK_PNMI_HTX_OCTETHIGH = SK_PNMI_HTX_OCTET,
122 SK_PNMI_HTX_OCTETLOW,
123 SK_PNMI_HTX_BROADCAST,
124 SK_PNMI_HTX_MULTICAST,
125 SK_PNMI_HTX_UNICAST,
126 SK_PNMI_HTX_BURST,
127 SK_PNMI_HTX_PMACC,
128 SK_PNMI_HTX_MACC,
129 SK_PNMI_HTX_COL,
130 SK_PNMI_HTX_SINGLE_COL,
131 SK_PNMI_HTX_MULTI_COL,
132 SK_PNMI_HTX_EXCESS_COL,
133 SK_PNMI_HTX_LATE_COL,
134 SK_PNMI_HTX_DEFFERAL,
135 SK_PNMI_HTX_EXCESS_DEF,
136 SK_PNMI_HTX_UNDERRUN,
137 SK_PNMI_HTX_CARRIER,
138 SK_PNMI_HTX_UTILUNDER,
139 SK_PNMI_HTX_UTILOVER,
140 SK_PNMI_HTX_64,
141 SK_PNMI_HTX_127,
142 SK_PNMI_HTX_255,
143 SK_PNMI_HTX_511,
144 SK_PNMI_HTX_1023,
145 SK_PNMI_HTX_MAX,
146 SK_PNMI_HTX_LONGFRAMES,
147 SK_PNMI_HTX_SYNC,
148 SK_PNMI_HTX_SYNC_OCTET,
149 SK_PNMI_HTX_RESERVED,
150
151 SK_PNMI_HRX,
152 SK_PNMI_HRX_OCTET,
153 SK_PNMI_HRX_OCTETHIGH = SK_PNMI_HRX_OCTET,
154 SK_PNMI_HRX_OCTETLOW,
155 SK_PNMI_HRX_BADOCTET,
156 SK_PNMI_HRX_BADOCTETHIGH = SK_PNMI_HRX_BADOCTET,
157 SK_PNMI_HRX_BADOCTETLOW,
158 SK_PNMI_HRX_BROADCAST,
159 SK_PNMI_HRX_MULTICAST,
160 SK_PNMI_HRX_UNICAST,
161 SK_PNMI_HRX_PMACC,
162 SK_PNMI_HRX_MACC,
163 SK_PNMI_HRX_PMACC_ERR,
164 SK_PNMI_HRX_MACC_UNKWN,
165 SK_PNMI_HRX_BURST,
166 SK_PNMI_HRX_MISSED,
167 SK_PNMI_HRX_FRAMING,
168 SK_PNMI_HRX_UNDERSIZE,
169 SK_PNMI_HRX_OVERFLOW,
170 SK_PNMI_HRX_JABBER,
171 SK_PNMI_HRX_CARRIER,
172 SK_PNMI_HRX_IRLENGTH,
173 SK_PNMI_HRX_SYMBOL,
174 SK_PNMI_HRX_SHORTS,
175 SK_PNMI_HRX_RUNT,
176 SK_PNMI_HRX_TOO_LONG,
177 SK_PNMI_HRX_FCS,
178 SK_PNMI_HRX_CEXT,
179 SK_PNMI_HRX_UTILUNDER,
180 SK_PNMI_HRX_UTILOVER,
181 SK_PNMI_HRX_64,
182 SK_PNMI_HRX_127,
183 SK_PNMI_HRX_255,
184 SK_PNMI_HRX_511,
185 SK_PNMI_HRX_1023,
186 SK_PNMI_HRX_MAX,
187 SK_PNMI_HRX_LONGFRAMES,
188
189 SK_PNMI_HRX_RESERVED,
190
191 SK_PNMI_MAX_IDX /* NOTE: Ensure SK_PNMI_CNT_NO is set to this value */
192};
193
194/*
195 * MAC specific data
196 */
197typedef struct s_PnmiStatAddr {
198 SK_U16 Reg; /* MAC register containing the value */
199 SK_BOOL GetOffset; /* TRUE: Offset managed by PNMI (call GetStatVal())*/
200} SK_PNMI_STATADDR;
201
202
203/*
204 * SK_PNMI_STRUCT_DATA copy offset evaluation macros
205 */
206#define SK_PNMI_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e))
207#define SK_PNMI_MAI_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e))
208#define SK_PNMI_VPD_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_VPD *)0)->e))
209#define SK_PNMI_SEN_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_SENSOR *)0)->e))
210#define SK_PNMI_CHK_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_CHECKSUM *)0)->e))
211#define SK_PNMI_STA_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STAT *)0)->e))
212#define SK_PNMI_CNF_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_CONF *)0)->e))
213#define SK_PNMI_RLM_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT *)0)->e))
214#define SK_PNMI_MON_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT_MONITOR *)0)->e))
215#define SK_PNMI_TRP_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_TRAP *)0)->e))
216
217#define SK_PNMI_SET_STAT(b,s,o) {SK_U32 Val32; char *pVal; \
218 Val32 = (s); \
219 pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \
220 &(((SK_PNMI_STRUCT_DATA *)0)-> \
221 ReturnStatus.ErrorStatus)); \
222 SK_PNMI_STORE_U32(pVal, Val32); \
223 Val32 = (o); \
224 pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \
225 &(((SK_PNMI_STRUCT_DATA *)0)-> \
226 ReturnStatus.ErrorOffset)); \
227 SK_PNMI_STORE_U32(pVal, Val32);}
228
229/*
230 * Time macros
231 */
232#ifndef SK_PNMI_HUNDREDS_SEC
233#if SK_TICKS_PER_SEC == 100
234#define SK_PNMI_HUNDREDS_SEC(t) (t)
235#else
236#define SK_PNMI_HUNDREDS_SEC(t) (((t) * 100) / (SK_TICKS_PER_SEC))
237#endif /* !SK_TICKS_PER_SEC */
238#endif /* !SK_PNMI_HUNDREDS_SEC */
239
240/*
241 * Macros to work around alignment problems
242 */
243#ifndef SK_PNMI_STORE_U16
244#define SK_PNMI_STORE_U16(p,v) {*(char *)(p) = *((char *)&(v)); \
245 *((char *)(p) + 1) = \
246 *(((char *)&(v)) + 1);}
247#endif
248
249#ifndef SK_PNMI_STORE_U32
250#define SK_PNMI_STORE_U32(p,v) {*(char *)(p) = *((char *)&(v)); \
251 *((char *)(p) + 1) = \
252 *(((char *)&(v)) + 1); \
253 *((char *)(p) + 2) = \
254 *(((char *)&(v)) + 2); \
255 *((char *)(p) + 3) = \
256 *(((char *)&(v)) + 3);}
257#endif
258
259#ifndef SK_PNMI_STORE_U64
260#define SK_PNMI_STORE_U64(p,v) {*(char *)(p) = *((char *)&(v)); \
261 *((char *)(p) + 1) = \
262 *(((char *)&(v)) + 1); \
263 *((char *)(p) + 2) = \
264 *(((char *)&(v)) + 2); \
265 *((char *)(p) + 3) = \
266 *(((char *)&(v)) + 3); \
267 *((char *)(p) + 4) = \
268 *(((char *)&(v)) + 4); \
269 *((char *)(p) + 5) = \
270 *(((char *)&(v)) + 5); \
271 *((char *)(p) + 6) = \
272 *(((char *)&(v)) + 6); \
273 *((char *)(p) + 7) = \
274 *(((char *)&(v)) + 7);}
275#endif
276
277#ifndef SK_PNMI_READ_U16
278#define SK_PNMI_READ_U16(p,v) {*((char *)&(v)) = *(char *)(p); \
279 *(((char *)&(v)) + 1) = \
280 *((char *)(p) + 1);}
281#endif
282
283#ifndef SK_PNMI_READ_U32
284#define SK_PNMI_READ_U32(p,v) {*((char *)&(v)) = *(char *)(p); \
285 *(((char *)&(v)) + 1) = \
286 *((char *)(p) + 1); \
287 *(((char *)&(v)) + 2) = \
288 *((char *)(p) + 2); \
289 *(((char *)&(v)) + 3) = \
290 *((char *)(p) + 3);}
291#endif
292
293#ifndef SK_PNMI_READ_U64
294#define SK_PNMI_READ_U64(p,v) {*((char *)&(v)) = *(char *)(p); \
295 *(((char *)&(v)) + 1) = \
296 *((char *)(p) + 1); \
297 *(((char *)&(v)) + 2) = \
298 *((char *)(p) + 2); \
299 *(((char *)&(v)) + 3) = \
300 *((char *)(p) + 3); \
301 *(((char *)&(v)) + 4) = \
302 *((char *)(p) + 4); \
303 *(((char *)&(v)) + 5) = \
304 *((char *)(p) + 5); \
305 *(((char *)&(v)) + 6) = \
306 *((char *)(p) + 6); \
307 *(((char *)&(v)) + 7) = \
308 *((char *)(p) + 7);}
309#endif
310
311/*
312 * Macros for Debug
313 */
314#ifdef DEBUG
315
316#define SK_PNMI_CHECKFLAGS(vSt) {if (pAC->Pnmi.MacUpdatedFlag > 0 || \
317 pAC->Pnmi.RlmtUpdatedFlag > 0 || \
318 pAC->Pnmi.SirqUpdatedFlag > 0) { \
319 SK_DBG_MSG(pAC, \
320 SK_DBGMOD_PNMI, \
321 SK_DBGCAT_CTRL, \
322 ("PNMI: ERR: %s MacUFlag=%d, RlmtUFlag=%d, SirqUFlag=%d\n", \
323 vSt, \
324 pAC->Pnmi.MacUpdatedFlag, \
325 pAC->Pnmi.RlmtUpdatedFlag, \
326 pAC->Pnmi.SirqUpdatedFlag))}}
327
328#else /* !DEBUG */
329
330#define SK_PNMI_CHECKFLAGS(vSt) /* Nothing */
331
332#endif /* !DEBUG */
333
334#endif /* _SKGEPNM2_H_ */
diff --git a/drivers/net/sk98lin/h/skgepnmi.h b/drivers/net/sk98lin/h/skgepnmi.h
new file mode 100644
index 000000000000..3b2773e6f822
--- /dev/null
+++ b/drivers/net/sk98lin/h/skgepnmi.h
@@ -0,0 +1,966 @@
1/*****************************************************************************
2 *
3 * Name: skgepnmi.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.62 $
6 * Date: $Date: 2003/08/15 12:31:52 $
7 * Purpose: Defines for Private Network Management Interface
8 *
9 ****************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef _SKGEPNMI_H_
26#define _SKGEPNMI_H_
27
28/*
29 * Include dependencies
30 */
31#include "h/sktypes.h"
32#include "h/skerror.h"
33#include "h/sktimer.h"
34#include "h/ski2c.h"
35#include "h/skaddr.h"
36#include "h/skrlmt.h"
37#include "h/skvpd.h"
38
39/*
40 * Management Database Version
41 */
42#define SK_PNMI_MDB_VERSION 0x00030001 /* 3.1 */
43
44
45/*
46 * Event definitions
47 */
48#define SK_PNMI_EVT_SIRQ_OVERFLOW 1 /* Counter overflow */
49#define SK_PNMI_EVT_SEN_WAR_LOW 2 /* Lower war thres exceeded */
50#define SK_PNMI_EVT_SEN_WAR_UPP 3 /* Upper war thres exceeded */
51#define SK_PNMI_EVT_SEN_ERR_LOW 4 /* Lower err thres exceeded */
52#define SK_PNMI_EVT_SEN_ERR_UPP 5 /* Upper err thres exceeded */
53#define SK_PNMI_EVT_CHG_EST_TIMER 6 /* Timer event for RLMT Chg */
54#define SK_PNMI_EVT_UTILIZATION_TIMER 7 /* Timer event for Utiliza. */
55#define SK_PNMI_EVT_CLEAR_COUNTER 8 /* Clear statistic counters */
56#define SK_PNMI_EVT_XMAC_RESET 9 /* XMAC will be reset */
57
58#define SK_PNMI_EVT_RLMT_PORT_UP 10 /* Port came logically up */
59#define SK_PNMI_EVT_RLMT_PORT_DOWN 11 /* Port went logically down */
60#define SK_PNMI_EVT_RLMT_SEGMENTATION 13 /* Two SP root bridges found */
61#define SK_PNMI_EVT_RLMT_ACTIVE_DOWN 14 /* Port went logically down */
62#define SK_PNMI_EVT_RLMT_ACTIVE_UP 15 /* Port came logically up */
63#define SK_PNMI_EVT_RLMT_SET_NETS 16 /* 1. Parameter is number of nets
64 1 = single net; 2 = dual net */
65#define SK_PNMI_EVT_VCT_RESET 17 /* VCT port reset timer event started with SET. */
66
67
68/*
69 * Return values
70 */
71#define SK_PNMI_ERR_OK 0
72#define SK_PNMI_ERR_GENERAL 1
73#define SK_PNMI_ERR_TOO_SHORT 2
74#define SK_PNMI_ERR_BAD_VALUE 3
75#define SK_PNMI_ERR_READ_ONLY 4
76#define SK_PNMI_ERR_UNKNOWN_OID 5
77#define SK_PNMI_ERR_UNKNOWN_INST 6
78#define SK_PNMI_ERR_UNKNOWN_NET 7
79#define SK_PNMI_ERR_NOT_SUPPORTED 10
80
81
82/*
83 * Return values of driver reset function SK_DRIVER_RESET() and
84 * driver event function SK_DRIVER_EVENT()
85 */
86#define SK_PNMI_ERR_OK 0
87#define SK_PNMI_ERR_FAIL 1
88
89
90/*
91 * Return values of driver test function SK_DRIVER_SELFTEST()
92 */
93#define SK_PNMI_TST_UNKNOWN (1 << 0)
94#define SK_PNMI_TST_TRANCEIVER (1 << 1)
95#define SK_PNMI_TST_ASIC (1 << 2)
96#define SK_PNMI_TST_SENSOR (1 << 3)
97#define SK_PNMI_TST_POWERMGMT (1 << 4)
98#define SK_PNMI_TST_PCI (1 << 5)
99#define SK_PNMI_TST_MAC (1 << 6)
100
101
102/*
103 * RLMT specific definitions
104 */
105#define SK_PNMI_RLMT_STATUS_STANDBY 1
106#define SK_PNMI_RLMT_STATUS_ACTIVE 2
107#define SK_PNMI_RLMT_STATUS_ERROR 3
108
109#define SK_PNMI_RLMT_LSTAT_PHY_DOWN 1
110#define SK_PNMI_RLMT_LSTAT_AUTONEG 2
111#define SK_PNMI_RLMT_LSTAT_LOG_DOWN 3
112#define SK_PNMI_RLMT_LSTAT_LOG_UP 4
113#define SK_PNMI_RLMT_LSTAT_INDETERMINATED 5
114
115#define SK_PNMI_RLMT_MODE_CHK_LINK (SK_RLMT_CHECK_LINK)
116#define SK_PNMI_RLMT_MODE_CHK_RX (SK_RLMT_CHECK_LOC_LINK)
117#define SK_PNMI_RLMT_MODE_CHK_SPT (SK_RLMT_CHECK_SEG)
118/* #define SK_PNMI_RLMT_MODE_CHK_EX */
119
120/*
121 * OID definition
122 */
123#ifndef _NDIS_ /* Check, whether NDIS already included OIDs */
124
125#define OID_GEN_XMIT_OK 0x00020101
126#define OID_GEN_RCV_OK 0x00020102
127#define OID_GEN_XMIT_ERROR 0x00020103
128#define OID_GEN_RCV_ERROR 0x00020104
129#define OID_GEN_RCV_NO_BUFFER 0x00020105
130
131/* #define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 */
132#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202
133/* #define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 */
134#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204
135/* #define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 */
136#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206
137/* #define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 */
138#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208
139/* #define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 */
140#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A
141/* #define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B */
142#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C
143#define OID_GEN_RCV_CRC_ERROR 0x0002020D
144#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E
145
146#define OID_802_3_PERMANENT_ADDRESS 0x01010101
147#define OID_802_3_CURRENT_ADDRESS 0x01010102
148/* #define OID_802_3_MULTICAST_LIST 0x01010103 */
149/* #define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 */
150/* #define OID_802_3_MAC_OPTIONS 0x01010105 */
151
152#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101
153#define OID_802_3_XMIT_ONE_COLLISION 0x01020102
154#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103
155#define OID_802_3_XMIT_DEFERRED 0x01020201
156#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202
157#define OID_802_3_RCV_OVERRUN 0x01020203
158#define OID_802_3_XMIT_UNDERRUN 0x01020204
159#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206
160#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207
161
162/*
163 * PnP and PM OIDs
164 */
165#ifdef SK_POWER_MGMT
166#define OID_PNP_CAPABILITIES 0xFD010100
167#define OID_PNP_SET_POWER 0xFD010101
168#define OID_PNP_QUERY_POWER 0xFD010102
169#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103
170#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104
171#define OID_PNP_ENABLE_WAKE_UP 0xFD010106
172#endif /* SK_POWER_MGMT */
173
174#endif /* _NDIS_ */
175
176#define OID_SKGE_MDB_VERSION 0xFF010100
177#define OID_SKGE_SUPPORTED_LIST 0xFF010101
178#define OID_SKGE_VPD_FREE_BYTES 0xFF010102
179#define OID_SKGE_VPD_ENTRIES_LIST 0xFF010103
180#define OID_SKGE_VPD_ENTRIES_NUMBER 0xFF010104
181#define OID_SKGE_VPD_KEY 0xFF010105
182#define OID_SKGE_VPD_VALUE 0xFF010106
183#define OID_SKGE_VPD_ACCESS 0xFF010107
184#define OID_SKGE_VPD_ACTION 0xFF010108
185
186#define OID_SKGE_PORT_NUMBER 0xFF010110
187#define OID_SKGE_DEVICE_TYPE 0xFF010111
188#define OID_SKGE_DRIVER_DESCR 0xFF010112
189#define OID_SKGE_DRIVER_VERSION 0xFF010113
190#define OID_SKGE_HW_DESCR 0xFF010114
191#define OID_SKGE_HW_VERSION 0xFF010115
192#define OID_SKGE_CHIPSET 0xFF010116
193#define OID_SKGE_ACTION 0xFF010117
194#define OID_SKGE_RESULT 0xFF010118
195#define OID_SKGE_BUS_TYPE 0xFF010119
196#define OID_SKGE_BUS_SPEED 0xFF01011A
197#define OID_SKGE_BUS_WIDTH 0xFF01011B
198/* 0xFF01011C unused */
199#define OID_SKGE_DIAG_ACTION 0xFF01011D
200#define OID_SKGE_DIAG_RESULT 0xFF01011E
201#define OID_SKGE_MTU 0xFF01011F
202#define OID_SKGE_PHYS_CUR_ADDR 0xFF010120
203#define OID_SKGE_PHYS_FAC_ADDR 0xFF010121
204#define OID_SKGE_PMD 0xFF010122
205#define OID_SKGE_CONNECTOR 0xFF010123
206#define OID_SKGE_LINK_CAP 0xFF010124
207#define OID_SKGE_LINK_MODE 0xFF010125
208#define OID_SKGE_LINK_MODE_STATUS 0xFF010126
209#define OID_SKGE_LINK_STATUS 0xFF010127
210#define OID_SKGE_FLOWCTRL_CAP 0xFF010128
211#define OID_SKGE_FLOWCTRL_MODE 0xFF010129
212#define OID_SKGE_FLOWCTRL_STATUS 0xFF01012A
213#define OID_SKGE_PHY_OPERATION_CAP 0xFF01012B
214#define OID_SKGE_PHY_OPERATION_MODE 0xFF01012C
215#define OID_SKGE_PHY_OPERATION_STATUS 0xFF01012D
216#define OID_SKGE_MULTICAST_LIST 0xFF01012E
217#define OID_SKGE_CURRENT_PACKET_FILTER 0xFF01012F
218
219#define OID_SKGE_TRAP 0xFF010130
220#define OID_SKGE_TRAP_NUMBER 0xFF010131
221
222#define OID_SKGE_RLMT_MODE 0xFF010140
223#define OID_SKGE_RLMT_PORT_NUMBER 0xFF010141
224#define OID_SKGE_RLMT_PORT_ACTIVE 0xFF010142
225#define OID_SKGE_RLMT_PORT_PREFERRED 0xFF010143
226#define OID_SKGE_INTERMEDIATE_SUPPORT 0xFF010160
227
228#define OID_SKGE_SPEED_CAP 0xFF010170
229#define OID_SKGE_SPEED_MODE 0xFF010171
230#define OID_SKGE_SPEED_STATUS 0xFF010172
231
232#define OID_SKGE_BOARDLEVEL 0xFF010180
233
234#define OID_SKGE_SENSOR_NUMBER 0xFF020100
235#define OID_SKGE_SENSOR_INDEX 0xFF020101
236#define OID_SKGE_SENSOR_DESCR 0xFF020102
237#define OID_SKGE_SENSOR_TYPE 0xFF020103
238#define OID_SKGE_SENSOR_VALUE 0xFF020104
239#define OID_SKGE_SENSOR_WAR_THRES_LOW 0xFF020105
240#define OID_SKGE_SENSOR_WAR_THRES_UPP 0xFF020106
241#define OID_SKGE_SENSOR_ERR_THRES_LOW 0xFF020107
242#define OID_SKGE_SENSOR_ERR_THRES_UPP 0xFF020108
243#define OID_SKGE_SENSOR_STATUS 0xFF020109
244#define OID_SKGE_SENSOR_WAR_CTS 0xFF02010A
245#define OID_SKGE_SENSOR_ERR_CTS 0xFF02010B
246#define OID_SKGE_SENSOR_WAR_TIME 0xFF02010C
247#define OID_SKGE_SENSOR_ERR_TIME 0xFF02010D
248
249#define OID_SKGE_CHKSM_NUMBER 0xFF020110
250#define OID_SKGE_CHKSM_RX_OK_CTS 0xFF020111
251#define OID_SKGE_CHKSM_RX_UNABLE_CTS 0xFF020112
252#define OID_SKGE_CHKSM_RX_ERR_CTS 0xFF020113
253#define OID_SKGE_CHKSM_TX_OK_CTS 0xFF020114
254#define OID_SKGE_CHKSM_TX_UNABLE_CTS 0xFF020115
255
256#define OID_SKGE_STAT_TX 0xFF020120
257#define OID_SKGE_STAT_TX_OCTETS 0xFF020121
258#define OID_SKGE_STAT_TX_BROADCAST 0xFF020122
259#define OID_SKGE_STAT_TX_MULTICAST 0xFF020123
260#define OID_SKGE_STAT_TX_UNICAST 0xFF020124
261#define OID_SKGE_STAT_TX_LONGFRAMES 0xFF020125
262#define OID_SKGE_STAT_TX_BURST 0xFF020126
263#define OID_SKGE_STAT_TX_PFLOWC 0xFF020127
264#define OID_SKGE_STAT_TX_FLOWC 0xFF020128
265#define OID_SKGE_STAT_TX_SINGLE_COL 0xFF020129
266#define OID_SKGE_STAT_TX_MULTI_COL 0xFF02012A
267#define OID_SKGE_STAT_TX_EXCESS_COL 0xFF02012B
268#define OID_SKGE_STAT_TX_LATE_COL 0xFF02012C
269#define OID_SKGE_STAT_TX_DEFFERAL 0xFF02012D
270#define OID_SKGE_STAT_TX_EXCESS_DEF 0xFF02012E
271#define OID_SKGE_STAT_TX_UNDERRUN 0xFF02012F
272#define OID_SKGE_STAT_TX_CARRIER 0xFF020130
273/* #define OID_SKGE_STAT_TX_UTIL 0xFF020131 */
274#define OID_SKGE_STAT_TX_64 0xFF020132
275#define OID_SKGE_STAT_TX_127 0xFF020133
276#define OID_SKGE_STAT_TX_255 0xFF020134
277#define OID_SKGE_STAT_TX_511 0xFF020135
278#define OID_SKGE_STAT_TX_1023 0xFF020136
279#define OID_SKGE_STAT_TX_MAX 0xFF020137
280#define OID_SKGE_STAT_TX_SYNC 0xFF020138
281#define OID_SKGE_STAT_TX_SYNC_OCTETS 0xFF020139
282#define OID_SKGE_STAT_RX 0xFF02013A
283#define OID_SKGE_STAT_RX_OCTETS 0xFF02013B
284#define OID_SKGE_STAT_RX_BROADCAST 0xFF02013C
285#define OID_SKGE_STAT_RX_MULTICAST 0xFF02013D
286#define OID_SKGE_STAT_RX_UNICAST 0xFF02013E
287#define OID_SKGE_STAT_RX_PFLOWC 0xFF02013F
288#define OID_SKGE_STAT_RX_FLOWC 0xFF020140
289#define OID_SKGE_STAT_RX_PFLOWC_ERR 0xFF020141
290#define OID_SKGE_STAT_RX_FLOWC_UNKWN 0xFF020142
291#define OID_SKGE_STAT_RX_BURST 0xFF020143
292#define OID_SKGE_STAT_RX_MISSED 0xFF020144
293#define OID_SKGE_STAT_RX_FRAMING 0xFF020145
294#define OID_SKGE_STAT_RX_OVERFLOW 0xFF020146
295#define OID_SKGE_STAT_RX_JABBER 0xFF020147
296#define OID_SKGE_STAT_RX_CARRIER 0xFF020148
297#define OID_SKGE_STAT_RX_IR_LENGTH 0xFF020149
298#define OID_SKGE_STAT_RX_SYMBOL 0xFF02014A
299#define OID_SKGE_STAT_RX_SHORTS 0xFF02014B
300#define OID_SKGE_STAT_RX_RUNT 0xFF02014C
301#define OID_SKGE_STAT_RX_CEXT 0xFF02014D
302#define OID_SKGE_STAT_RX_TOO_LONG 0xFF02014E
303#define OID_SKGE_STAT_RX_FCS 0xFF02014F
304/* #define OID_SKGE_STAT_RX_UTIL 0xFF020150 */
305#define OID_SKGE_STAT_RX_64 0xFF020151
306#define OID_SKGE_STAT_RX_127 0xFF020152
307#define OID_SKGE_STAT_RX_255 0xFF020153
308#define OID_SKGE_STAT_RX_511 0xFF020154
309#define OID_SKGE_STAT_RX_1023 0xFF020155
310#define OID_SKGE_STAT_RX_MAX 0xFF020156
311#define OID_SKGE_STAT_RX_LONGFRAMES 0xFF020157
312
313#define OID_SKGE_RLMT_CHANGE_CTS 0xFF020160
314#define OID_SKGE_RLMT_CHANGE_TIME 0xFF020161
315#define OID_SKGE_RLMT_CHANGE_ESTIM 0xFF020162
316#define OID_SKGE_RLMT_CHANGE_THRES 0xFF020163
317
318#define OID_SKGE_RLMT_PORT_INDEX 0xFF020164
319#define OID_SKGE_RLMT_STATUS 0xFF020165
320#define OID_SKGE_RLMT_TX_HELLO_CTS 0xFF020166
321#define OID_SKGE_RLMT_RX_HELLO_CTS 0xFF020167
322#define OID_SKGE_RLMT_TX_SP_REQ_CTS 0xFF020168
323#define OID_SKGE_RLMT_RX_SP_CTS 0xFF020169
324
325#define OID_SKGE_RLMT_MONITOR_NUMBER 0xFF010150
326#define OID_SKGE_RLMT_MONITOR_INDEX 0xFF010151
327#define OID_SKGE_RLMT_MONITOR_ADDR 0xFF010152
328#define OID_SKGE_RLMT_MONITOR_ERRS 0xFF010153
329#define OID_SKGE_RLMT_MONITOR_TIMESTAMP 0xFF010154
330#define OID_SKGE_RLMT_MONITOR_ADMIN 0xFF010155
331
332#define OID_SKGE_TX_SW_QUEUE_LEN 0xFF020170
333#define OID_SKGE_TX_SW_QUEUE_MAX 0xFF020171
334#define OID_SKGE_TX_RETRY 0xFF020172
335#define OID_SKGE_RX_INTR_CTS 0xFF020173
336#define OID_SKGE_TX_INTR_CTS 0xFF020174
337#define OID_SKGE_RX_NO_BUF_CTS 0xFF020175
338#define OID_SKGE_TX_NO_BUF_CTS 0xFF020176
339#define OID_SKGE_TX_USED_DESCR_NO 0xFF020177
340#define OID_SKGE_RX_DELIVERED_CTS 0xFF020178
341#define OID_SKGE_RX_OCTETS_DELIV_CTS 0xFF020179
342#define OID_SKGE_RX_HW_ERROR_CTS 0xFF02017A
343#define OID_SKGE_TX_HW_ERROR_CTS 0xFF02017B
344#define OID_SKGE_IN_ERRORS_CTS 0xFF02017C
345#define OID_SKGE_OUT_ERROR_CTS 0xFF02017D
346#define OID_SKGE_ERR_RECOVERY_CTS 0xFF02017E
347#define OID_SKGE_SYSUPTIME 0xFF02017F
348
349#define OID_SKGE_ALL_DATA 0xFF020190
350
351/* Defines for VCT. */
352#define OID_SKGE_VCT_GET 0xFF020200
353#define OID_SKGE_VCT_SET 0xFF020201
354#define OID_SKGE_VCT_STATUS 0xFF020202
355
356#ifdef SK_DIAG_SUPPORT
357/* Defines for driver DIAG mode. */
358#define OID_SKGE_DIAG_MODE 0xFF020204
359#endif /* SK_DIAG_SUPPORT */
360
361/* New OIDs */
362#define OID_SKGE_DRIVER_RELDATE 0xFF020210
363#define OID_SKGE_DRIVER_FILENAME 0xFF020211
364#define OID_SKGE_CHIPID 0xFF020212
365#define OID_SKGE_RAMSIZE 0xFF020213
366#define OID_SKGE_VAUXAVAIL 0xFF020214
367#define OID_SKGE_PHY_TYPE 0xFF020215
368#define OID_SKGE_PHY_LP_MODE 0xFF020216
369
370/* VCT struct to store a backup copy of VCT data after a port reset. */
371typedef struct s_PnmiVct {
372 SK_U8 VctStatus;
373 SK_U8 PCableLen;
374 SK_U32 PMdiPairLen[4];
375 SK_U8 PMdiPairSts[4];
376} SK_PNMI_VCT;
377
378
379/* VCT status values (to be given to CPA via OID_SKGE_VCT_STATUS). */
380#define SK_PNMI_VCT_NONE 0
381#define SK_PNMI_VCT_OLD_VCT_DATA 1
382#define SK_PNMI_VCT_NEW_VCT_DATA 2
383#define SK_PNMI_VCT_OLD_DSP_DATA 4
384#define SK_PNMI_VCT_NEW_DSP_DATA 8
385#define SK_PNMI_VCT_RUNNING 16
386
387
388/* VCT cable test status. */
389#define SK_PNMI_VCT_NORMAL_CABLE 0
390#define SK_PNMI_VCT_SHORT_CABLE 1
391#define SK_PNMI_VCT_OPEN_CABLE 2
392#define SK_PNMI_VCT_TEST_FAIL 3
393#define SK_PNMI_VCT_IMPEDANCE_MISMATCH 4
394
395#define OID_SKGE_TRAP_SEN_WAR_LOW 500
396#define OID_SKGE_TRAP_SEN_WAR_UPP 501
397#define OID_SKGE_TRAP_SEN_ERR_LOW 502
398#define OID_SKGE_TRAP_SEN_ERR_UPP 503
399#define OID_SKGE_TRAP_RLMT_CHANGE_THRES 520
400#define OID_SKGE_TRAP_RLMT_CHANGE_PORT 521
401#define OID_SKGE_TRAP_RLMT_PORT_DOWN 522
402#define OID_SKGE_TRAP_RLMT_PORT_UP 523
403#define OID_SKGE_TRAP_RLMT_SEGMENTATION 524
404
405#ifdef SK_DIAG_SUPPORT
406/* Defines for driver DIAG mode. */
407#define SK_DIAG_ATTACHED 2
408#define SK_DIAG_RUNNING 1
409#define SK_DIAG_IDLE 0
410#endif /* SK_DIAG_SUPPORT */
411
412/*
413 * Generic PNMI IOCTL subcommand definitions.
414 */
415#define SK_GET_SINGLE_VAR 1
416#define SK_SET_SINGLE_VAR 2
417#define SK_PRESET_SINGLE_VAR 3
418#define SK_GET_FULL_MIB 4
419#define SK_SET_FULL_MIB 5
420#define SK_PRESET_FULL_MIB 6
421
422
423/*
424 * Define error numbers and messages for syslog
425 */
426#define SK_PNMI_ERR001 (SK_ERRBASE_PNMI + 1)
427#define SK_PNMI_ERR001MSG "SkPnmiGetStruct: Unknown OID"
428#define SK_PNMI_ERR002 (SK_ERRBASE_PNMI + 2)
429#define SK_PNMI_ERR002MSG "SkPnmiGetStruct: Cannot read VPD keys"
430#define SK_PNMI_ERR003 (SK_ERRBASE_PNMI + 3)
431#define SK_PNMI_ERR003MSG "OidStruct: Called with wrong OID"
432#define SK_PNMI_ERR004 (SK_ERRBASE_PNMI + 4)
433#define SK_PNMI_ERR004MSG "OidStruct: Called with wrong action"
434#define SK_PNMI_ERR005 (SK_ERRBASE_PNMI + 5)
435#define SK_PNMI_ERR005MSG "Perform: Cannot reset driver"
436#define SK_PNMI_ERR006 (SK_ERRBASE_PNMI + 6)
437#define SK_PNMI_ERR006MSG "Perform: Unknown OID action command"
438#define SK_PNMI_ERR007 (SK_ERRBASE_PNMI + 7)
439#define SK_PNMI_ERR007MSG "General: Driver description not initialized"
440#define SK_PNMI_ERR008 (SK_ERRBASE_PNMI + 8)
441#define SK_PNMI_ERR008MSG "Addr: Tried to get unknown OID"
442#define SK_PNMI_ERR009 (SK_ERRBASE_PNMI + 9)
443#define SK_PNMI_ERR009MSG "Addr: Unknown OID"
444#define SK_PNMI_ERR010 (SK_ERRBASE_PNMI + 10)
445#define SK_PNMI_ERR010MSG "CsumStat: Unknown OID"
446#define SK_PNMI_ERR011 (SK_ERRBASE_PNMI + 11)
447#define SK_PNMI_ERR011MSG "SensorStat: Sensor descr string too long"
448#define SK_PNMI_ERR012 (SK_ERRBASE_PNMI + 12)
449#define SK_PNMI_ERR012MSG "SensorStat: Unknown OID"
450#define SK_PNMI_ERR013 (SK_ERRBASE_PNMI + 13)
451#define SK_PNMI_ERR013MSG ""
452#define SK_PNMI_ERR014 (SK_ERRBASE_PNMI + 14)
453#define SK_PNMI_ERR014MSG "Vpd: Cannot read VPD keys"
454#define SK_PNMI_ERR015 (SK_ERRBASE_PNMI + 15)
455#define SK_PNMI_ERR015MSG "Vpd: Internal array for VPD keys to small"
456#define SK_PNMI_ERR016 (SK_ERRBASE_PNMI + 16)
457#define SK_PNMI_ERR016MSG "Vpd: Key string too long"
458#define SK_PNMI_ERR017 (SK_ERRBASE_PNMI + 17)
459#define SK_PNMI_ERR017MSG "Vpd: Invalid VPD status pointer"
460#define SK_PNMI_ERR018 (SK_ERRBASE_PNMI + 18)
461#define SK_PNMI_ERR018MSG "Vpd: VPD data not valid"
462#define SK_PNMI_ERR019 (SK_ERRBASE_PNMI + 19)
463#define SK_PNMI_ERR019MSG "Vpd: VPD entries list string too long"
464#define SK_PNMI_ERR021 (SK_ERRBASE_PNMI + 21)
465#define SK_PNMI_ERR021MSG "Vpd: VPD data string too long"
466#define SK_PNMI_ERR022 (SK_ERRBASE_PNMI + 22)
467#define SK_PNMI_ERR022MSG "Vpd: VPD data string too long should be errored before"
468#define SK_PNMI_ERR023 (SK_ERRBASE_PNMI + 23)
469#define SK_PNMI_ERR023MSG "Vpd: Unknown OID in get action"
470#define SK_PNMI_ERR024 (SK_ERRBASE_PNMI + 24)
471#define SK_PNMI_ERR024MSG "Vpd: Unknown OID in preset/set action"
472#define SK_PNMI_ERR025 (SK_ERRBASE_PNMI + 25)
473#define SK_PNMI_ERR025MSG "Vpd: Cannot write VPD after modify entry"
474#define SK_PNMI_ERR026 (SK_ERRBASE_PNMI + 26)
475#define SK_PNMI_ERR026MSG "Vpd: Cannot update VPD"
476#define SK_PNMI_ERR027 (SK_ERRBASE_PNMI + 27)
477#define SK_PNMI_ERR027MSG "Vpd: Cannot delete VPD entry"
478#define SK_PNMI_ERR028 (SK_ERRBASE_PNMI + 28)
479#define SK_PNMI_ERR028MSG "Vpd: Cannot update VPD after delete entry"
480#define SK_PNMI_ERR029 (SK_ERRBASE_PNMI + 29)
481#define SK_PNMI_ERR029MSG "General: Driver description string too long"
482#define SK_PNMI_ERR030 (SK_ERRBASE_PNMI + 30)
483#define SK_PNMI_ERR030MSG "General: Driver version not initialized"
484#define SK_PNMI_ERR031 (SK_ERRBASE_PNMI + 31)
485#define SK_PNMI_ERR031MSG "General: Driver version string too long"
486#define SK_PNMI_ERR032 (SK_ERRBASE_PNMI + 32)
487#define SK_PNMI_ERR032MSG "General: Cannot read VPD Name for HW descr"
488#define SK_PNMI_ERR033 (SK_ERRBASE_PNMI + 33)
489#define SK_PNMI_ERR033MSG "General: HW description string too long"
490#define SK_PNMI_ERR034 (SK_ERRBASE_PNMI + 34)
491#define SK_PNMI_ERR034MSG "General: Unknown OID"
492#define SK_PNMI_ERR035 (SK_ERRBASE_PNMI + 35)
493#define SK_PNMI_ERR035MSG "Rlmt: Unknown OID"
494#define SK_PNMI_ERR036 (SK_ERRBASE_PNMI + 36)
495#define SK_PNMI_ERR036MSG ""
496#define SK_PNMI_ERR037 (SK_ERRBASE_PNMI + 37)
497#define SK_PNMI_ERR037MSG "Rlmt: SK_RLMT_MODE_CHANGE event return not 0"
498#define SK_PNMI_ERR038 (SK_ERRBASE_PNMI + 38)
499#define SK_PNMI_ERR038MSG "Rlmt: SK_RLMT_PREFPORT_CHANGE event return not 0"
500#define SK_PNMI_ERR039 (SK_ERRBASE_PNMI + 39)
501#define SK_PNMI_ERR039MSG "RlmtStat: Unknown OID"
502#define SK_PNMI_ERR040 (SK_ERRBASE_PNMI + 40)
503#define SK_PNMI_ERR040MSG "PowerManagement: Unknown OID"
504#define SK_PNMI_ERR041 (SK_ERRBASE_PNMI + 41)
505#define SK_PNMI_ERR041MSG "MacPrivateConf: Unknown OID"
506#define SK_PNMI_ERR042 (SK_ERRBASE_PNMI + 42)
507#define SK_PNMI_ERR042MSG "MacPrivateConf: SK_HWEV_SET_ROLE returned not 0"
508#define SK_PNMI_ERR043 (SK_ERRBASE_PNMI + 43)
509#define SK_PNMI_ERR043MSG "MacPrivateConf: SK_HWEV_SET_LMODE returned not 0"
510#define SK_PNMI_ERR044 (SK_ERRBASE_PNMI + 44)
511#define SK_PNMI_ERR044MSG "MacPrivateConf: SK_HWEV_SET_FLOWMODE returned not 0"
512#define SK_PNMI_ERR045 (SK_ERRBASE_PNMI + 45)
513#define SK_PNMI_ERR045MSG "MacPrivateConf: SK_HWEV_SET_SPEED returned not 0"
514#define SK_PNMI_ERR046 (SK_ERRBASE_PNMI + 46)
515#define SK_PNMI_ERR046MSG "Monitor: Unknown OID"
516#define SK_PNMI_ERR047 (SK_ERRBASE_PNMI + 47)
517#define SK_PNMI_ERR047MSG "SirqUpdate: Event function returns not 0"
518#define SK_PNMI_ERR048 (SK_ERRBASE_PNMI + 48)
519#define SK_PNMI_ERR048MSG "RlmtUpdate: Event function returns not 0"
520#define SK_PNMI_ERR049 (SK_ERRBASE_PNMI + 49)
521#define SK_PNMI_ERR049MSG "SkPnmiInit: Invalid size of 'CounterOffset' struct!!"
522#define SK_PNMI_ERR050 (SK_ERRBASE_PNMI + 50)
523#define SK_PNMI_ERR050MSG "SkPnmiInit: Invalid size of 'StatAddr' table!!"
524#define SK_PNMI_ERR051 (SK_ERRBASE_PNMI + 51)
525#define SK_PNMI_ERR051MSG "SkPnmiEvent: Port switch suspicious"
526#define SK_PNMI_ERR052 (SK_ERRBASE_PNMI + 52)
527#define SK_PNMI_ERR052MSG ""
528#define SK_PNMI_ERR053 (SK_ERRBASE_PNMI + 53)
529#define SK_PNMI_ERR053MSG "General: Driver release date not initialized"
530#define SK_PNMI_ERR054 (SK_ERRBASE_PNMI + 54)
531#define SK_PNMI_ERR054MSG "General: Driver release date string too long"
532#define SK_PNMI_ERR055 (SK_ERRBASE_PNMI + 55)
533#define SK_PNMI_ERR055MSG "General: Driver file name not initialized"
534#define SK_PNMI_ERR056 (SK_ERRBASE_PNMI + 56)
535#define SK_PNMI_ERR056MSG "General: Driver file name string too long"
536
537/*
538 * Management counter macros called by the driver
539 */
540#define SK_PNMI_SET_DRIVER_DESCR(pAC,v) ((pAC)->Pnmi.pDriverDescription = \
541 (char *)(v))
542
543#define SK_PNMI_SET_DRIVER_VER(pAC,v) ((pAC)->Pnmi.pDriverVersion = \
544 (char *)(v))
545
546#define SK_PNMI_SET_DRIVER_RELDATE(pAC,v) ((pAC)->Pnmi.pDriverReleaseDate = \
547 (char *)(v))
548
549#define SK_PNMI_SET_DRIVER_FILENAME(pAC,v) ((pAC)->Pnmi.pDriverFileName = \
550 (char *)(v))
551
552#define SK_PNMI_CNT_TX_QUEUE_LEN(pAC,v,p) \
553 { \
554 (pAC)->Pnmi.Port[p].TxSwQueueLen = (SK_U64)(v); \
555 if ((pAC)->Pnmi.Port[p].TxSwQueueLen > (pAC)->Pnmi.Port[p].TxSwQueueMax) { \
556 (pAC)->Pnmi.Port[p].TxSwQueueMax = (pAC)->Pnmi.Port[p].TxSwQueueLen; \
557 } \
558 }
559#define SK_PNMI_CNT_TX_RETRY(pAC,p) (((pAC)->Pnmi.Port[p].TxRetryCts)++)
560#define SK_PNMI_CNT_RX_INTR(pAC,p) (((pAC)->Pnmi.Port[p].RxIntrCts)++)
561#define SK_PNMI_CNT_TX_INTR(pAC,p) (((pAC)->Pnmi.Port[p].TxIntrCts)++)
562#define SK_PNMI_CNT_NO_RX_BUF(pAC,p) (((pAC)->Pnmi.Port[p].RxNoBufCts)++)
563#define SK_PNMI_CNT_NO_TX_BUF(pAC,p) (((pAC)->Pnmi.Port[p].TxNoBufCts)++)
564#define SK_PNMI_CNT_USED_TX_DESCR(pAC,v,p) \
565 ((pAC)->Pnmi.Port[p].TxUsedDescrNo=(SK_U64)(v));
566#define SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,v,p) \
567 { \
568 ((pAC)->Pnmi.Port[p].RxDeliveredCts)++; \
569 (pAC)->Pnmi.Port[p].RxOctetsDeliveredCts += (SK_U64)(v); \
570 }
571#define SK_PNMI_CNT_ERR_RECOVERY(pAC,p) (((pAC)->Pnmi.Port[p].ErrRecoveryCts)++);
572
573#define SK_PNMI_CNT_SYNC_OCTETS(pAC,p,v) \
574 { \
575 if ((p) < SK_MAX_MACS) { \
576 ((pAC)->Pnmi.Port[p].StatSyncCts)++; \
577 (pAC)->Pnmi.Port[p].StatSyncOctetsCts += (SK_U64)(v); \
578 } \
579 }
580
581#define SK_PNMI_CNT_RX_LONGFRAMES(pAC,p) \
582 { \
583 if ((p) < SK_MAX_MACS) { \
584 ((pAC)->Pnmi.Port[p].StatRxLongFrameCts++); \
585 } \
586 }
587
588#define SK_PNMI_CNT_RX_FRAMETOOLONG(pAC,p) \
589 { \
590 if ((p) < SK_MAX_MACS) { \
591 ((pAC)->Pnmi.Port[p].StatRxFrameTooLongCts++); \
592 } \
593 }
594
595#define SK_PNMI_CNT_RX_PMACC_ERR(pAC,p) \
596 { \
597 if ((p) < SK_MAX_MACS) { \
598 ((pAC)->Pnmi.Port[p].StatRxPMaccErr++); \
599 } \
600 }
601
602/*
603 * Conversion Macros
604 */
605#define SK_PNMI_PORT_INST2LOG(i) ((unsigned int)(i) - 1)
606#define SK_PNMI_PORT_LOG2INST(l) ((unsigned int)(l) + 1)
607#define SK_PNMI_PORT_PHYS2LOG(p) ((unsigned int)(p) + 1)
608#define SK_PNMI_PORT_LOG2PHYS(pAC,l) ((unsigned int)(l) - 1)
609#define SK_PNMI_PORT_PHYS2INST(pAC,p) \
610 (pAC->Pnmi.DualNetActiveFlag ? 2 : ((unsigned int)(p) + 2))
611#define SK_PNMI_PORT_INST2PHYS(pAC,i) ((unsigned int)(i) - 2)
612
613/*
614 * Structure definition for SkPnmiGetStruct and SkPnmiSetStruct
615 */
616#define SK_PNMI_VPD_KEY_SIZE 5
617#define SK_PNMI_VPD_BUFSIZE (VPD_SIZE)
618#define SK_PNMI_VPD_ENTRIES (VPD_SIZE / 4)
619#define SK_PNMI_VPD_DATALEN 128 /* Number of data bytes */
620
621#define SK_PNMI_MULTICAST_LISTLEN 64
622#define SK_PNMI_SENSOR_ENTRIES (SK_MAX_SENSORS)
623#define SK_PNMI_CHECKSUM_ENTRIES 3
624#define SK_PNMI_MAC_ENTRIES (SK_MAX_MACS + 1)
625#define SK_PNMI_MONITOR_ENTRIES 20
626#define SK_PNMI_TRAP_ENTRIES 10
627#define SK_PNMI_TRAPLEN 128
628#define SK_PNMI_STRINGLEN1 80
629#define SK_PNMI_STRINGLEN2 25
630#define SK_PNMI_TRAP_QUEUE_LEN 512
631
632typedef struct s_PnmiVpd {
633 char VpdKey[SK_PNMI_VPD_KEY_SIZE];
634 char VpdValue[SK_PNMI_VPD_DATALEN];
635 SK_U8 VpdAccess;
636 SK_U8 VpdAction;
637} SK_PNMI_VPD;
638
639typedef struct s_PnmiSensor {
640 SK_U8 SensorIndex;
641 char SensorDescr[SK_PNMI_STRINGLEN2];
642 SK_U8 SensorType;
643 SK_U32 SensorValue;
644 SK_U32 SensorWarningThresholdLow;
645 SK_U32 SensorWarningThresholdHigh;
646 SK_U32 SensorErrorThresholdLow;
647 SK_U32 SensorErrorThresholdHigh;
648 SK_U8 SensorStatus;
649 SK_U64 SensorWarningCts;
650 SK_U64 SensorErrorCts;
651 SK_U64 SensorWarningTimestamp;
652 SK_U64 SensorErrorTimestamp;
653} SK_PNMI_SENSOR;
654
655typedef struct s_PnmiChecksum {
656 SK_U64 ChecksumRxOkCts;
657 SK_U64 ChecksumRxUnableCts;
658 SK_U64 ChecksumRxErrCts;
659 SK_U64 ChecksumTxOkCts;
660 SK_U64 ChecksumTxUnableCts;
661} SK_PNMI_CHECKSUM;
662
663typedef struct s_PnmiStat {
664 SK_U64 StatTxOkCts;
665 SK_U64 StatTxOctetsOkCts;
666 SK_U64 StatTxBroadcastOkCts;
667 SK_U64 StatTxMulticastOkCts;
668 SK_U64 StatTxUnicastOkCts;
669 SK_U64 StatTxLongFramesCts;
670 SK_U64 StatTxBurstCts;
671 SK_U64 StatTxPauseMacCtrlCts;
672 SK_U64 StatTxMacCtrlCts;
673 SK_U64 StatTxSingleCollisionCts;
674 SK_U64 StatTxMultipleCollisionCts;
675 SK_U64 StatTxExcessiveCollisionCts;
676 SK_U64 StatTxLateCollisionCts;
677 SK_U64 StatTxDeferralCts;
678 SK_U64 StatTxExcessiveDeferralCts;
679 SK_U64 StatTxFifoUnderrunCts;
680 SK_U64 StatTxCarrierCts;
681 SK_U64 Dummy1; /* StatTxUtilization */
682 SK_U64 StatTx64Cts;
683 SK_U64 StatTx127Cts;
684 SK_U64 StatTx255Cts;
685 SK_U64 StatTx511Cts;
686 SK_U64 StatTx1023Cts;
687 SK_U64 StatTxMaxCts;
688 SK_U64 StatTxSyncCts;
689 SK_U64 StatTxSyncOctetsCts;
690 SK_U64 StatRxOkCts;
691 SK_U64 StatRxOctetsOkCts;
692 SK_U64 StatRxBroadcastOkCts;
693 SK_U64 StatRxMulticastOkCts;
694 SK_U64 StatRxUnicastOkCts;
695 SK_U64 StatRxLongFramesCts;
696 SK_U64 StatRxPauseMacCtrlCts;
697 SK_U64 StatRxMacCtrlCts;
698 SK_U64 StatRxPauseMacCtrlErrorCts;
699 SK_U64 StatRxMacCtrlUnknownCts;
700 SK_U64 StatRxBurstCts;
701 SK_U64 StatRxMissedCts;
702 SK_U64 StatRxFramingCts;
703 SK_U64 StatRxFifoOverflowCts;
704 SK_U64 StatRxJabberCts;
705 SK_U64 StatRxCarrierCts;
706 SK_U64 StatRxIRLengthCts;
707 SK_U64 StatRxSymbolCts;
708 SK_U64 StatRxShortsCts;
709 SK_U64 StatRxRuntCts;
710 SK_U64 StatRxCextCts;
711 SK_U64 StatRxTooLongCts;
712 SK_U64 StatRxFcsCts;
713 SK_U64 Dummy2; /* StatRxUtilization */
714 SK_U64 StatRx64Cts;
715 SK_U64 StatRx127Cts;
716 SK_U64 StatRx255Cts;
717 SK_U64 StatRx511Cts;
718 SK_U64 StatRx1023Cts;
719 SK_U64 StatRxMaxCts;
720} SK_PNMI_STAT;
721
722typedef struct s_PnmiConf {
723 char ConfMacCurrentAddr[6];
724 char ConfMacFactoryAddr[6];
725 SK_U8 ConfPMD;
726 SK_U8 ConfConnector;
727 SK_U32 ConfPhyType;
728 SK_U32 ConfPhyMode;
729 SK_U8 ConfLinkCapability;
730 SK_U8 ConfLinkMode;
731 SK_U8 ConfLinkModeStatus;
732 SK_U8 ConfLinkStatus;
733 SK_U8 ConfFlowCtrlCapability;
734 SK_U8 ConfFlowCtrlMode;
735 SK_U8 ConfFlowCtrlStatus;
736 SK_U8 ConfPhyOperationCapability;
737 SK_U8 ConfPhyOperationMode;
738 SK_U8 ConfPhyOperationStatus;
739 SK_U8 ConfSpeedCapability;
740 SK_U8 ConfSpeedMode;
741 SK_U8 ConfSpeedStatus;
742} SK_PNMI_CONF;
743
744typedef struct s_PnmiRlmt {
745 SK_U32 RlmtIndex;
746 SK_U32 RlmtStatus;
747 SK_U64 RlmtTxHelloCts;
748 SK_U64 RlmtRxHelloCts;
749 SK_U64 RlmtTxSpHelloReqCts;
750 SK_U64 RlmtRxSpHelloCts;
751} SK_PNMI_RLMT;
752
753typedef struct s_PnmiRlmtMonitor {
754 SK_U32 RlmtMonitorIndex;
755 char RlmtMonitorAddr[6];
756 SK_U64 RlmtMonitorErrorCts;
757 SK_U64 RlmtMonitorTimestamp;
758 SK_U8 RlmtMonitorAdmin;
759} SK_PNMI_RLMT_MONITOR;
760
761typedef struct s_PnmiRequestStatus {
762 SK_U32 ErrorStatus;
763 SK_U32 ErrorOffset;
764} SK_PNMI_REQUEST_STATUS;
765
766typedef struct s_PnmiStrucData {
767 SK_U32 MgmtDBVersion;
768 SK_PNMI_REQUEST_STATUS ReturnStatus;
769 SK_U32 VpdFreeBytes;
770 char VpdEntriesList[SK_PNMI_VPD_ENTRIES * SK_PNMI_VPD_KEY_SIZE];
771 SK_U32 VpdEntriesNumber;
772 SK_PNMI_VPD Vpd[SK_PNMI_VPD_ENTRIES];
773 SK_U32 PortNumber;
774 SK_U32 DeviceType;
775 char DriverDescr[SK_PNMI_STRINGLEN1];
776 char DriverVersion[SK_PNMI_STRINGLEN2];
777 char DriverReleaseDate[SK_PNMI_STRINGLEN1];
778 char DriverFileName[SK_PNMI_STRINGLEN1];
779 char HwDescr[SK_PNMI_STRINGLEN1];
780 char HwVersion[SK_PNMI_STRINGLEN2];
781 SK_U16 Chipset;
782 SK_U32 ChipId;
783 SK_U8 VauxAvail;
784 SK_U32 RamSize;
785 SK_U32 MtuSize;
786 SK_U32 Action;
787 SK_U32 TestResult;
788 SK_U8 BusType;
789 SK_U8 BusSpeed;
790 SK_U8 BusWidth;
791 SK_U8 SensorNumber;
792 SK_PNMI_SENSOR Sensor[SK_PNMI_SENSOR_ENTRIES];
793 SK_U8 ChecksumNumber;
794 SK_PNMI_CHECKSUM Checksum[SK_PNMI_CHECKSUM_ENTRIES];
795 SK_PNMI_STAT Stat[SK_PNMI_MAC_ENTRIES];
796 SK_PNMI_CONF Conf[SK_PNMI_MAC_ENTRIES];
797 SK_U8 RlmtMode;
798 SK_U32 RlmtPortNumber;
799 SK_U8 RlmtPortActive;
800 SK_U8 RlmtPortPreferred;
801 SK_U64 RlmtChangeCts;
802 SK_U64 RlmtChangeTime;
803 SK_U64 RlmtChangeEstimate;
804 SK_U64 RlmtChangeThreshold;
805 SK_PNMI_RLMT Rlmt[SK_MAX_MACS];
806 SK_U32 RlmtMonitorNumber;
807 SK_PNMI_RLMT_MONITOR RlmtMonitor[SK_PNMI_MONITOR_ENTRIES];
808 SK_U32 TrapNumber;
809 SK_U8 Trap[SK_PNMI_TRAP_QUEUE_LEN];
810 SK_U64 TxSwQueueLen;
811 SK_U64 TxSwQueueMax;
812 SK_U64 TxRetryCts;
813 SK_U64 RxIntrCts;
814 SK_U64 TxIntrCts;
815 SK_U64 RxNoBufCts;
816 SK_U64 TxNoBufCts;
817 SK_U64 TxUsedDescrNo;
818 SK_U64 RxDeliveredCts;
819 SK_U64 RxOctetsDeliveredCts;
820 SK_U64 RxHwErrorsCts;
821 SK_U64 TxHwErrorsCts;
822 SK_U64 InErrorsCts;
823 SK_U64 OutErrorsCts;
824 SK_U64 ErrRecoveryCts;
825 SK_U64 SysUpTime;
826} SK_PNMI_STRUCT_DATA;
827
828#define SK_PNMI_STRUCT_SIZE (sizeof(SK_PNMI_STRUCT_DATA))
829#define SK_PNMI_MIN_STRUCT_SIZE ((unsigned int)(SK_UPTR)\
830 &(((SK_PNMI_STRUCT_DATA *)0)->VpdFreeBytes))
831 /*
832 * ReturnStatus field
833 * must be located
834 * before VpdFreeBytes
835 */
836
837/*
838 * Various definitions
839 */
840#define SK_PNMI_MAX_PROTOS 3
841
842#define SK_PNMI_CNT_NO 66 /* Must have the value of the enum
843 * SK_PNMI_MAX_IDX. Define SK_PNMI_CHECK
844 * for check while init phase 1
845 */
846
847/*
848 * Estimate data structure
849 */
850typedef struct s_PnmiEstimate {
851 unsigned int EstValueIndex;
852 SK_U64 EstValue[7];
853 SK_U64 Estimate;
854 SK_TIMER EstTimer;
855} SK_PNMI_ESTIMATE;
856
857
858/*
859 * VCT timer data structure
860 */
861typedef struct s_VctTimer {
862 SK_TIMER VctTimer;
863} SK_PNMI_VCT_TIMER;
864
865
866/*
867 * PNMI specific adapter context structure
868 */
869typedef struct s_PnmiPort {
870 SK_U64 StatSyncCts;
871 SK_U64 StatSyncOctetsCts;
872 SK_U64 StatRxLongFrameCts;
873 SK_U64 StatRxFrameTooLongCts;
874 SK_U64 StatRxPMaccErr;
875 SK_U64 TxSwQueueLen;
876 SK_U64 TxSwQueueMax;
877 SK_U64 TxRetryCts;
878 SK_U64 RxIntrCts;
879 SK_U64 TxIntrCts;
880 SK_U64 RxNoBufCts;
881 SK_U64 TxNoBufCts;
882 SK_U64 TxUsedDescrNo;
883 SK_U64 RxDeliveredCts;
884 SK_U64 RxOctetsDeliveredCts;
885 SK_U64 RxHwErrorsCts;
886 SK_U64 TxHwErrorsCts;
887 SK_U64 InErrorsCts;
888 SK_U64 OutErrorsCts;
889 SK_U64 ErrRecoveryCts;
890 SK_U64 RxShortZeroMark;
891 SK_U64 CounterOffset[SK_PNMI_CNT_NO];
892 SK_U32 CounterHigh[SK_PNMI_CNT_NO];
893 SK_BOOL ActiveFlag;
894 SK_U8 Align[3];
895} SK_PNMI_PORT;
896
897
898typedef struct s_PnmiData {
899 SK_PNMI_PORT Port [SK_MAX_MACS];
900 SK_PNMI_PORT BufPort [SK_MAX_MACS]; /* 2002-09-13 pweber */
901 SK_U64 VirtualCounterOffset[SK_PNMI_CNT_NO];
902 SK_U32 TestResult;
903 char HwVersion[10];
904 SK_U16 Align01;
905
906 char *pDriverDescription;
907 char *pDriverVersion;
908 char *pDriverReleaseDate;
909 char *pDriverFileName;
910
911 int MacUpdatedFlag;
912 int RlmtUpdatedFlag;
913 int SirqUpdatedFlag;
914
915 SK_U64 RlmtChangeCts;
916 SK_U64 RlmtChangeTime;
917 SK_PNMI_ESTIMATE RlmtChangeEstimate;
918 SK_U64 RlmtChangeThreshold;
919
920 SK_U64 StartUpTime;
921 SK_U32 DeviceType;
922 char PciBusSpeed;
923 char PciBusWidth;
924 char Chipset;
925 char PMD;
926 char Connector;
927 SK_BOOL DualNetActiveFlag;
928 SK_U16 Align02;
929
930 char TrapBuf[SK_PNMI_TRAP_QUEUE_LEN];
931 unsigned int TrapBufFree;
932 unsigned int TrapQueueBeg;
933 unsigned int TrapQueueEnd;
934 unsigned int TrapBufPad;
935 unsigned int TrapUnique;
936 SK_U8 VctStatus[SK_MAX_MACS];
937 SK_PNMI_VCT VctBackup[SK_MAX_MACS];
938 SK_PNMI_VCT_TIMER VctTimeout[SK_MAX_MACS];
939#ifdef SK_DIAG_SUPPORT
940 SK_U32 DiagAttached;
941#endif /* SK_DIAG_SUPPORT */
942} SK_PNMI;
943
944
945/*
946 * Function prototypes
947 */
948extern int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int Level);
949extern int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf,
950 unsigned int* pLen, SK_U32 Instance, SK_U32 NetIndex);
951extern int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id,
952 void* pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
953extern int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf,
954 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
955extern int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf,
956 unsigned int *pLen, SK_U32 NetIndex);
957extern int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf,
958 unsigned int *pLen, SK_U32 NetIndex);
959extern int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf,
960 unsigned int *pLen, SK_U32 NetIndex);
961extern int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event,
962 SK_EVPARA Param);
963extern int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf,
964 unsigned int * pLen, SK_U32 NetIndex);
965
966#endif
diff --git a/drivers/net/sk98lin/h/skgesirq.h b/drivers/net/sk98lin/h/skgesirq.h
new file mode 100644
index 000000000000..b486bd9b6628
--- /dev/null
+++ b/drivers/net/sk98lin/h/skgesirq.h
@@ -0,0 +1,111 @@
1/******************************************************************************
2 *
3 * Name: skgesirq.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.30 $
6 * Date: $Date: 2003/07/04 12:34:13 $
7 * Purpose: SK specific Gigabit Ethernet special IRQ functions
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef _INC_SKGESIRQ_H_
26#define _INC_SKGESIRQ_H_
27
28/* Define return codes of SkGePortCheckUp and CheckShort */
29#define SK_HW_PS_NONE 0 /* No action needed */
30#define SK_HW_PS_RESTART 1 /* Restart needed */
31#define SK_HW_PS_LINK 2 /* Link Up actions needed */
32
33/*
34 * Define the Event the special IRQ/INI module can handle
35 */
36#define SK_HWEV_WATIM 1 /* Timeout for WA Errata #2 XMAC */
37#define SK_HWEV_PORT_START 2 /* Port Start Event by RLMT */
38#define SK_HWEV_PORT_STOP 3 /* Port Stop Event by RLMT */
39#define SK_HWEV_CLEAR_STAT 4 /* Clear Statistics by PNMI */
40#define SK_HWEV_UPDATE_STAT 5 /* Update Statistics by PNMI */
41#define SK_HWEV_SET_LMODE 6 /* Set Link Mode by PNMI */
42#define SK_HWEV_SET_FLOWMODE 7 /* Set Flow Control Mode by PNMI */
43#define SK_HWEV_SET_ROLE 8 /* Set Master/Slave (Role) by PNMI */
44#define SK_HWEV_SET_SPEED 9 /* Set Link Speed by PNMI */
45#define SK_HWEV_HALFDUP_CHK 10 /* Half Duplex Hangup Workaround */
46
47#define SK_WA_ACT_TIME (5000000UL) /* 5 sec */
48#define SK_WA_INA_TIME (100000UL) /* 100 msec */
49
50#define SK_HALFDUP_CHK_TIME (10000UL) /* 10 msec */
51
52/*
53 * Define the error numbers and messages
54 */
55#define SKERR_SIRQ_E001 (SK_ERRBASE_SIRQ+0)
56#define SKERR_SIRQ_E001MSG "Unknown event"
57#define SKERR_SIRQ_E002 (SKERR_SIRQ_E001+1)
58#define SKERR_SIRQ_E002MSG "Packet timeout RX1"
59#define SKERR_SIRQ_E003 (SKERR_SIRQ_E002+1)
60#define SKERR_SIRQ_E003MSG "Packet timeout RX2"
61#define SKERR_SIRQ_E004 (SKERR_SIRQ_E003+1)
62#define SKERR_SIRQ_E004MSG "MAC 1 not correctly initialized"
63#define SKERR_SIRQ_E005 (SKERR_SIRQ_E004+1)
64#define SKERR_SIRQ_E005MSG "MAC 2 not correctly initialized"
65#define SKERR_SIRQ_E006 (SKERR_SIRQ_E005+1)
66#define SKERR_SIRQ_E006MSG "CHECK failure R1"
67#define SKERR_SIRQ_E007 (SKERR_SIRQ_E006+1)
68#define SKERR_SIRQ_E007MSG "CHECK failure R2"
69#define SKERR_SIRQ_E008 (SKERR_SIRQ_E007+1)
70#define SKERR_SIRQ_E008MSG "CHECK failure XS1"
71#define SKERR_SIRQ_E009 (SKERR_SIRQ_E008+1)
72#define SKERR_SIRQ_E009MSG "CHECK failure XA1"
73#define SKERR_SIRQ_E010 (SKERR_SIRQ_E009+1)
74#define SKERR_SIRQ_E010MSG "CHECK failure XS2"
75#define SKERR_SIRQ_E011 (SKERR_SIRQ_E010+1)
76#define SKERR_SIRQ_E011MSG "CHECK failure XA2"
77#define SKERR_SIRQ_E012 (SKERR_SIRQ_E011+1)
78#define SKERR_SIRQ_E012MSG "unexpected IRQ Master error"
79#define SKERR_SIRQ_E013 (SKERR_SIRQ_E012+1)
80#define SKERR_SIRQ_E013MSG "unexpected IRQ Status error"
81#define SKERR_SIRQ_E014 (SKERR_SIRQ_E013+1)
82#define SKERR_SIRQ_E014MSG "Parity error on RAM (read)"
83#define SKERR_SIRQ_E015 (SKERR_SIRQ_E014+1)
84#define SKERR_SIRQ_E015MSG "Parity error on RAM (write)"
85#define SKERR_SIRQ_E016 (SKERR_SIRQ_E015+1)
86#define SKERR_SIRQ_E016MSG "Parity error MAC 1"
87#define SKERR_SIRQ_E017 (SKERR_SIRQ_E016+1)
88#define SKERR_SIRQ_E017MSG "Parity error MAC 2"
89#define SKERR_SIRQ_E018 (SKERR_SIRQ_E017+1)
90#define SKERR_SIRQ_E018MSG "Parity error RX 1"
91#define SKERR_SIRQ_E019 (SKERR_SIRQ_E018+1)
92#define SKERR_SIRQ_E019MSG "Parity error RX 2"
93#define SKERR_SIRQ_E020 (SKERR_SIRQ_E019+1)
94#define SKERR_SIRQ_E020MSG "MAC transmit FIFO underrun"
95#define SKERR_SIRQ_E021 (SKERR_SIRQ_E020+1)
96#define SKERR_SIRQ_E021MSG "Spurious TWSI interrupt"
97#define SKERR_SIRQ_E022 (SKERR_SIRQ_E021+1)
98#define SKERR_SIRQ_E022MSG "Cable pair swap error"
99#define SKERR_SIRQ_E023 (SKERR_SIRQ_E022+1)
100#define SKERR_SIRQ_E023MSG "Auto-negotiation error"
101#define SKERR_SIRQ_E024 (SKERR_SIRQ_E023+1)
102#define SKERR_SIRQ_E024MSG "FIFO overflow error"
103#define SKERR_SIRQ_E025 (SKERR_SIRQ_E024+1)
104#define SKERR_SIRQ_E025MSG "2 Pair Downshift detected"
105
106extern void SkGeSirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus);
107extern int SkGeSirqEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
108extern void SkHWLinkUp(SK_AC *pAC, SK_IOC IoC, int Port);
109extern void SkHWLinkDown(SK_AC *pAC, SK_IOC IoC, int Port);
110
111#endif /* _INC_SKGESIRQ_H_ */
diff --git a/drivers/net/sk98lin/h/ski2c.h b/drivers/net/sk98lin/h/ski2c.h
new file mode 100644
index 000000000000..598bb42ccc3d
--- /dev/null
+++ b/drivers/net/sk98lin/h/ski2c.h
@@ -0,0 +1,177 @@
1/******************************************************************************
2 *
3 * Name: ski2c.h
4 * Project: Gigabit Ethernet Adapters, TWSI-Module
5 * Version: $Revision: 1.35 $
6 * Date: $Date: 2003/10/20 09:06:30 $
7 * Purpose: Defines to access Voltage and Temperature Sensor
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * SKI2C.H contains all I2C specific defines
27 */
28
29#ifndef _SKI2C_H_
30#define _SKI2C_H_
31
32typedef struct s_Sensor SK_SENSOR;
33
34#include "h/skgei2c.h"
35
36/*
37 * Define the I2C events.
38 */
39#define SK_I2CEV_IRQ 1 /* IRQ happened Event */
40#define SK_I2CEV_TIM 2 /* Timeout event */
41#define SK_I2CEV_CLEAR 3 /* Clear MIB Values */
42
43/*
44 * Define READ and WRITE Constants.
45 */
46#define I2C_READ 0
47#define I2C_WRITE 1
48#define I2C_BURST 1
49#define I2C_SINGLE 0
50
51#define SKERR_I2C_E001 (SK_ERRBASE_I2C+0)
52#define SKERR_I2C_E001MSG "Sensor index unknown"
53#define SKERR_I2C_E002 (SKERR_I2C_E001+1)
54#define SKERR_I2C_E002MSG "TWSI: transfer does not complete"
55#define SKERR_I2C_E003 (SKERR_I2C_E002+1)
56#define SKERR_I2C_E003MSG "LM80: NAK on device send"
57#define SKERR_I2C_E004 (SKERR_I2C_E003+1)
58#define SKERR_I2C_E004MSG "LM80: NAK on register send"
59#define SKERR_I2C_E005 (SKERR_I2C_E004+1)
60#define SKERR_I2C_E005MSG "LM80: NAK on device (2) send"
61#define SKERR_I2C_E006 (SKERR_I2C_E005+1)
62#define SKERR_I2C_E006MSG "Unknown event"
63#define SKERR_I2C_E007 (SKERR_I2C_E006+1)
64#define SKERR_I2C_E007MSG "LM80 read out of state"
65#define SKERR_I2C_E008 (SKERR_I2C_E007+1)
66#define SKERR_I2C_E008MSG "Unexpected sensor read completed"
67#define SKERR_I2C_E009 (SKERR_I2C_E008+1)
68#define SKERR_I2C_E009MSG "WARNING: temperature sensor out of range"
69#define SKERR_I2C_E010 (SKERR_I2C_E009+1)
70#define SKERR_I2C_E010MSG "WARNING: voltage sensor out of range"
71#define SKERR_I2C_E011 (SKERR_I2C_E010+1)
72#define SKERR_I2C_E011MSG "ERROR: temperature sensor out of range"
73#define SKERR_I2C_E012 (SKERR_I2C_E011+1)
74#define SKERR_I2C_E012MSG "ERROR: voltage sensor out of range"
75#define SKERR_I2C_E013 (SKERR_I2C_E012+1)
76#define SKERR_I2C_E013MSG "ERROR: couldn't init sensor"
77#define SKERR_I2C_E014 (SKERR_I2C_E013+1)
78#define SKERR_I2C_E014MSG "WARNING: fan sensor out of range"
79#define SKERR_I2C_E015 (SKERR_I2C_E014+1)
80#define SKERR_I2C_E015MSG "ERROR: fan sensor out of range"
81#define SKERR_I2C_E016 (SKERR_I2C_E015+1)
82#define SKERR_I2C_E016MSG "TWSI: active transfer does not complete"
83
84/*
85 * Define Timeout values
86 */
87#define SK_I2C_TIM_LONG 2000000L /* 2 seconds */
88#define SK_I2C_TIM_SHORT 100000L /* 100 milliseconds */
89#define SK_I2C_TIM_WATCH 1000000L /* 1 second */
90
91/*
92 * Define trap and error log hold times
93 */
94#ifndef SK_SEN_ERR_TR_HOLD
95#define SK_SEN_ERR_TR_HOLD (4*SK_TICKS_PER_SEC)
96#endif
97#ifndef SK_SEN_ERR_LOG_HOLD
98#define SK_SEN_ERR_LOG_HOLD (60*SK_TICKS_PER_SEC)
99#endif
100#ifndef SK_SEN_WARN_TR_HOLD
101#define SK_SEN_WARN_TR_HOLD (15*SK_TICKS_PER_SEC)
102#endif
103#ifndef SK_SEN_WARN_LOG_HOLD
104#define SK_SEN_WARN_LOG_HOLD (15*60*SK_TICKS_PER_SEC)
105#endif
106
107/*
108 * Defines for SenType
109 */
110#define SK_SEN_UNKNOWN 0
111#define SK_SEN_TEMP 1
112#define SK_SEN_VOLT 2
113#define SK_SEN_FAN 3
114
115/*
116 * Define for the SenErrorFlag
117 */
118#define SK_SEN_ERR_NOT_PRESENT 0 /* Error Flag: Sensor not present */
119#define SK_SEN_ERR_OK 1 /* Error Flag: O.K. */
120#define SK_SEN_ERR_WARN 2 /* Error Flag: Warning */
121#define SK_SEN_ERR_ERR 3 /* Error Flag: Error */
122#define SK_SEN_ERR_FAULTY 4 /* Error Flag: Faulty */
123
124/*
125 * Define the Sensor struct
126 */
127struct s_Sensor {
128 char *SenDesc; /* Description */
129 int SenType; /* Voltage or Temperature */
130 SK_I32 SenValue; /* Current value of the sensor */
131 SK_I32 SenThreErrHigh; /* High error Threshhold of this sensor */
132 SK_I32 SenThreWarnHigh; /* High warning Threshhold of this sensor */
133 SK_I32 SenThreErrLow; /* Lower error Threshold of the sensor */
134 SK_I32 SenThreWarnLow; /* Lower warning Threshold of the sensor */
135 int SenErrFlag; /* Sensor indicated an error */
136 SK_BOOL SenInit; /* Is sensor initialized ? */
137 SK_U64 SenErrCts; /* Error trap counter */
138 SK_U64 SenWarnCts; /* Warning trap counter */
139 SK_U64 SenBegErrTS; /* Begin error timestamp */
140 SK_U64 SenBegWarnTS; /* Begin warning timestamp */
141 SK_U64 SenLastErrTrapTS; /* Last error trap timestamp */
142 SK_U64 SenLastErrLogTS; /* Last error log timestamp */
143 SK_U64 SenLastWarnTrapTS; /* Last warning trap timestamp */
144 SK_U64 SenLastWarnLogTS; /* Last warning log timestamp */
145 int SenState; /* Sensor State (see HW specific include) */
146 int (*SenRead)(SK_AC *pAC, SK_IOC IoC, struct s_Sensor *pSen);
147 /* Sensors read function */
148 SK_U16 SenReg; /* Register Address for this sensor */
149 SK_U8 SenDev; /* Device Selection for this sensor */
150};
151
152typedef struct s_I2c {
153 SK_SENSOR SenTable[SK_MAX_SENSORS]; /* Sensor Table */
154 int CurrSens; /* Which sensor is currently queried */
155 int MaxSens; /* Max. number of sensors */
156 int TimerMode; /* Use the timer also to watch the state machine */
157 int InitLevel; /* Initialized Level */
158#ifndef SK_DIAG
159 int DummyReads; /* Number of non-checked dummy reads */
160 SK_TIMER SenTimer; /* Sensors timer */
161#endif /* !SK_DIAG */
162} SK_I2C;
163
164extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level);
165extern int SkI2cWrite(SK_AC *pAC, SK_IOC IoC, SK_U32 Data, int Dev, int Size,
166 int Reg, int Burst);
167extern int SkI2cReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen);
168#ifdef SK_DIAG
169extern SK_U32 SkI2cRead(SK_AC *pAC, SK_IOC IoC, int Dev, int Size, int Reg,
170 int Burst);
171#else /* !SK_DIAG */
172extern int SkI2cEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
173extern void SkI2cWaitIrq(SK_AC *pAC, SK_IOC IoC);
174extern void SkI2cIsr(SK_AC *pAC, SK_IOC IoC);
175#endif /* !SK_DIAG */
176#endif /* n_SKI2C_H */
177
diff --git a/drivers/net/sk98lin/h/skqueue.h b/drivers/net/sk98lin/h/skqueue.h
new file mode 100644
index 000000000000..2ec40d4fdf60
--- /dev/null
+++ b/drivers/net/sk98lin/h/skqueue.h
@@ -0,0 +1,94 @@
1/******************************************************************************
2 *
3 * Name: skqueue.h
4 * Project: Gigabit Ethernet Adapters, Event Scheduler Module
5 * Version: $Revision: 1.16 $
6 * Date: $Date: 2003/09/16 12:50:32 $
7 * Purpose: Defines for the Event queue
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * SKQUEUE.H contains all defines and types for the event queue
27 */
28
29#ifndef _SKQUEUE_H_
30#define _SKQUEUE_H_
31
32
33/*
34 * define the event classes to be served
35 */
36#define SKGE_DRV 1 /* Driver Event Class */
37#define SKGE_RLMT 2 /* RLMT Event Class */
38#define SKGE_I2C 3 /* I2C Event Class */
39#define SKGE_PNMI 4 /* PNMI Event Class */
40#define SKGE_CSUM 5 /* Checksum Event Class */
41#define SKGE_HWAC 6 /* Hardware Access Event Class */
42
43#define SKGE_SWT 9 /* Software Timer Event Class */
44#define SKGE_LACP 10 /* LACP Aggregation Event Class */
45#define SKGE_RSF 11 /* RSF Aggregation Event Class */
46#define SKGE_MARKER 12 /* MARKER Aggregation Event Class */
47#define SKGE_FD 13 /* FD Distributor Event Class */
48
49/*
50 * define event queue as circular buffer
51 */
52#define SK_MAX_EVENT 64
53
54/*
55 * Parameter union for the Para stuff
56 */
57typedef union u_EvPara {
58 void *pParaPtr; /* Parameter Pointer */
59 SK_U64 Para64; /* Parameter 64bit version */
60 SK_U32 Para32[2]; /* Parameter Array of 32bit parameters */
61} SK_EVPARA;
62
63/*
64 * Event Queue
65 * skqueue.c
66 * events are class/value pairs
67 * class is addressee, e.g. RLMT, PNMI etc.
68 * value is command, e.g. line state change, ring op change etc.
69 */
70typedef struct s_EventElem {
71 SK_U32 Class; /* Event class */
72 SK_U32 Event; /* Event value */
73 SK_EVPARA Para; /* Event parameter */
74} SK_EVENTELEM;
75
76typedef struct s_Queue {
77 SK_EVENTELEM EvQueue[SK_MAX_EVENT];
78 SK_EVENTELEM *EvPut;
79 SK_EVENTELEM *EvGet;
80} SK_QUEUE;
81
82extern void SkEventInit(SK_AC *pAC, SK_IOC Ioc, int Level);
83extern void SkEventQueue(SK_AC *pAC, SK_U32 Class, SK_U32 Event,
84 SK_EVPARA Para);
85extern int SkEventDispatcher(SK_AC *pAC, SK_IOC Ioc);
86
87
88/* Define Error Numbers and messages */
89#define SKERR_Q_E001 (SK_ERRBASE_QUEUE+0)
90#define SKERR_Q_E001MSG "Event queue overflow"
91#define SKERR_Q_E002 (SKERR_Q_E001+1)
92#define SKERR_Q_E002MSG "Undefined event class"
93#endif /* _SKQUEUE_H_ */
94
diff --git a/drivers/net/sk98lin/h/skrlmt.h b/drivers/net/sk98lin/h/skrlmt.h
new file mode 100644
index 000000000000..ca75dfdcf2d6
--- /dev/null
+++ b/drivers/net/sk98lin/h/skrlmt.h
@@ -0,0 +1,438 @@
1/******************************************************************************
2 *
3 * Name: skrlmt.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.37 $
6 * Date: $Date: 2003/04/15 09:43:43 $
7 * Purpose: Header file for Redundant Link ManagemenT.
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * This is the header file for Redundant Link ManagemenT.
30 *
31 * Include File Hierarchy:
32 *
33 * "skdrv1st.h"
34 * ...
35 * "sktypes.h"
36 * "skqueue.h"
37 * "skaddr.h"
38 * "skrlmt.h"
39 * ...
40 * "skdrv2nd.h"
41 *
42 ******************************************************************************/
43
44#ifndef __INC_SKRLMT_H
45#define __INC_SKRLMT_H
46
47#ifdef __cplusplus
48extern "C" {
49#endif /* cplusplus */
50
51/* defines ********************************************************************/
52
53#define SK_RLMT_NET_DOWN_TEMP 1 /* NET_DOWN due to last port down. */
54#define SK_RLMT_NET_DOWN_FINAL 2 /* NET_DOWN due to RLMT_STOP. */
55
56/* ----- Default queue sizes - must be multiples of 8 KB ----- */
57
58/* Less than 8 KB free in RX queue => pause frames. */
59#define SK_RLMT_STANDBY_QRXSIZE 128 /* Size of rx standby queue in KB. */
60#define SK_RLMT_STANDBY_QXASIZE 32 /* Size of async standby queue in KB. */
61#define SK_RLMT_STANDBY_QXSSIZE 0 /* Size of sync standby queue in KB. */
62
63#define SK_RLMT_MAX_TX_BUF_SIZE 60 /* Maximum RLMT transmit size. */
64
65/* ----- PORT states ----- */
66
67#define SK_RLMT_PS_INIT 0 /* Port state: Init. */
68#define SK_RLMT_PS_LINK_DOWN 1 /* Port state: Link down. */
69#define SK_RLMT_PS_DOWN 2 /* Port state: Port down. */
70#define SK_RLMT_PS_GOING_UP 3 /* Port state: Going up. */
71#define SK_RLMT_PS_UP 4 /* Port state: Up. */
72
73/* ----- RLMT states ----- */
74
75#define SK_RLMT_RS_INIT 0 /* RLMT state: Init. */
76#define SK_RLMT_RS_NET_DOWN 1 /* RLMT state: Net down. */
77#define SK_RLMT_RS_NET_UP 2 /* RLMT state: Net up. */
78
79/* ----- PORT events ----- */
80
81#define SK_RLMT_LINK_UP 1001 /* Link came up. */
82#define SK_RLMT_LINK_DOWN 1002 /* Link went down. */
83#define SK_RLMT_PORT_ADDR 1003 /* Port address changed. */
84
85/* ----- RLMT events ----- */
86
87#define SK_RLMT_START 2001 /* Start RLMT. */
88#define SK_RLMT_STOP 2002 /* Stop RLMT. */
89#define SK_RLMT_PACKET_RECEIVED 2003 /* Packet was received for RLMT. */
90#define SK_RLMT_STATS_CLEAR 2004 /* Clear statistics. */
91#define SK_RLMT_STATS_UPDATE 2005 /* Update statistics. */
92#define SK_RLMT_PREFPORT_CHANGE 2006 /* Change preferred port. */
93#define SK_RLMT_MODE_CHANGE 2007 /* New RlmtMode. */
94#define SK_RLMT_SET_NETS 2008 /* Number of Nets (1 or 2). */
95
96/* ----- RLMT mode bits ----- */
97
98/*
99 * CAUTION: These defines are private to RLMT.
100 * Please use the RLMT mode defines below.
101 */
102
103#define SK_RLMT_CHECK_LINK 1 /* Check Link. */
104#define SK_RLMT_CHECK_LOC_LINK 2 /* Check other link on same adapter. */
105#define SK_RLMT_CHECK_SEG 4 /* Check segmentation. */
106
107#ifndef RLMT_CHECK_REMOTE
108#define SK_RLMT_CHECK_OTHERS SK_RLMT_CHECK_LOC_LINK
109#else /* RLMT_CHECK_REMOTE */
110#define SK_RLMT_CHECK_REM_LINK 8 /* Check link(s) on other adapter(s). */
111#define SK_RLMT_MAX_REMOTE_PORTS_CHECKED 3
112#define SK_RLMT_CHECK_OTHERS \
113 (SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_REM_LINK)
114#endif /* RLMT_CHECK_REMOTE */
115
116#ifndef SK_RLMT_ENABLE_TRANSPARENT
117#define SK_RLMT_TRANSPARENT 0 /* RLMT transparent - inactive. */
118#else /* SK_RLMT_ENABLE_TRANSPARENT */
119#define SK_RLMT_TRANSPARENT 128 /* RLMT transparent. */
120#endif /* SK_RLMT_ENABLE_TRANSPARENT */
121
122/* ----- RLMT modes ----- */
123
124/* Check Link State. */
125#define SK_RLMT_MODE_CLS (SK_RLMT_CHECK_LINK)
126
127/* Check Local Ports: check other links on the same adapter. */
128#define SK_RLMT_MODE_CLP (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK)
129
130/* Check Local Ports and Segmentation Status. */
131#define SK_RLMT_MODE_CLPSS \
132 (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_SEG)
133
134#ifdef RLMT_CHECK_REMOTE
135/* Check Local and Remote Ports: check links (local or remote). */
136 Name of define TBD!
137#define SK_RLMT_MODE_CRP \
138 (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_REM_LINK)
139
140/* Check Local and Remote Ports and Segmentation Status. */
141 Name of define TBD!
142#define SK_RLMT_MODE_CRPSS \
143 (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | \
144 SK_RLMT_CHECK_REM_LINK | SK_RLMT_CHECK_SEG)
145#endif /* RLMT_CHECK_REMOTE */
146
147/* ----- RLMT lookahead result bits ----- */
148
149#define SK_RLMT_RX_RLMT 1 /* Give packet to RLMT. */
150#define SK_RLMT_RX_PROTOCOL 2 /* Give packet to protocol. */
151
152/* Macros */
153
154#if 0
155SK_AC *pAC /* adapter context */
156SK_U32 PortNum /* receiving port */
157unsigned PktLen /* received packet's length */
158SK_BOOL IsBc /* Flag: packet is broadcast */
159unsigned *pOffset /* offs. of bytes to present to SK_RLMT_LOOKAHEAD */
160unsigned *pNumBytes /* #Bytes to present to SK_RLMT_LOOKAHEAD */
161#endif /* 0 */
162
163#define SK_RLMT_PRE_LOOKAHEAD(pAC,PortNum,PktLen,IsBc,pOffset,pNumBytes) { \
164 SK_AC *_pAC; \
165 SK_U32 _PortNum; \
166 _pAC = (pAC); \
167 _PortNum = (SK_U32)(PortNum); \
168 /* _pAC->Rlmt.Port[_PortNum].PacketsRx++; */ \
169 _pAC->Rlmt.Port[_PortNum].PacketsPerTimeSlot++; \
170 if (_pAC->Rlmt.RlmtOff) { \
171 *(pNumBytes) = 0; \
172 } \
173 else {\
174 if ((_pAC->Rlmt.Port[_PortNum].Net->RlmtMode & SK_RLMT_TRANSPARENT) != 0) { \
175 *(pNumBytes) = 0; \
176 } \
177 else if (IsBc) { \
178 if (_pAC->Rlmt.Port[_PortNum].Net->RlmtMode != SK_RLMT_MODE_CLS) { \
179 *(pNumBytes) = 6; \
180 *(pOffset) = 6; \
181 } \
182 else { \
183 *(pNumBytes) = 0; \
184 } \
185 } \
186 else { \
187 if ((PktLen) > SK_RLMT_MAX_TX_BUF_SIZE) { \
188 /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
189 *(pNumBytes) = 0; \
190 } \
191 else { \
192 *(pNumBytes) = 6; \
193 *(pOffset) = 0; \
194 } \
195 } \
196 } \
197}
198
199#if 0
200SK_AC *pAC /* adapter context */
201SK_U32 PortNum /* receiving port */
202SK_U8 *pLaPacket, /* received packet's data (points to pOffset) */
203SK_BOOL IsBc /* Flag: packet is broadcast */
204SK_BOOL IsMc /* Flag: packet is multicast */
205unsigned *pForRlmt /* Result: bits SK_RLMT_RX_RLMT, SK_RLMT_RX_PROTOCOL */
206SK_RLMT_LOOKAHEAD() expects *pNumBytes from
207packet offset *pOffset (s.a.) at *pLaPacket.
208
209If you use SK_RLMT_LOOKAHEAD in a path where you already know if the packet is
210BC, MC, or UC, you should use constants for IsBc and IsMc, so that your compiler
211can trash unneeded parts of the if construction.
212#endif /* 0 */
213
214#define SK_RLMT_LOOKAHEAD(pAC,PortNum,pLaPacket,IsBc,IsMc,pForRlmt) { \
215 SK_AC *_pAC; \
216 SK_U32 _PortNum; \
217 SK_U8 *_pLaPacket; \
218 _pAC = (pAC); \
219 _PortNum = (SK_U32)(PortNum); \
220 _pLaPacket = (SK_U8 *)(pLaPacket); \
221 if (IsBc) {\
222 if (!SK_ADDR_EQUAL(_pLaPacket, _pAC->Addr.Net[_pAC->Rlmt.Port[ \
223 _PortNum].Net->NetNumber].CurrentMacAddress.a)) { \
224 _pAC->Rlmt.Port[_PortNum].BcTimeStamp = SkOsGetTime(_pAC); \
225 _pAC->Rlmt.CheckSwitch = SK_TRUE; \
226 } \
227 /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
228 *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
229 } \
230 else if (IsMc) { \
231 if (SK_ADDR_EQUAL(_pLaPacket, BridgeMcAddr.a)) { \
232 _pAC->Rlmt.Port[_PortNum].BpduPacketsPerTimeSlot++; \
233 if (_pAC->Rlmt.Port[_PortNum].Net->RlmtMode & SK_RLMT_CHECK_SEG) { \
234 *(pForRlmt) = SK_RLMT_RX_RLMT | SK_RLMT_RX_PROTOCOL; \
235 } \
236 else { \
237 *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
238 } \
239 } \
240 else if (SK_ADDR_EQUAL(_pLaPacket, SkRlmtMcAddr.a)) { \
241 *(pForRlmt) = SK_RLMT_RX_RLMT; \
242 } \
243 else { \
244 /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
245 *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
246 } \
247 } \
248 else { \
249 if (SK_ADDR_EQUAL( \
250 _pLaPacket, \
251 _pAC->Addr.Port[_PortNum].CurrentMacAddress.a)) { \
252 *(pForRlmt) = SK_RLMT_RX_RLMT; \
253 } \
254 else { \
255 /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
256 *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
257 } \
258 } \
259}
260
261#ifdef SK_RLMT_FAST_LOOKAHEAD
262Error: SK_RLMT_FAST_LOOKAHEAD no longer used. Use new macros for lookahead.
263#endif /* SK_RLMT_FAST_LOOKAHEAD */
264#ifdef SK_RLMT_SLOW_LOOKAHEAD
265Error: SK_RLMT_SLOW_LOOKAHEAD no longer used. Use new macros for lookahead.
266#endif /* SK_RLMT_SLOW_LOOKAHEAD */
267
268/* typedefs *******************************************************************/
269
270#ifdef SK_RLMT_MBUF_PRIVATE
271typedef struct s_RlmtMbuf {
272 some content
273} SK_RLMT_MBUF;
274#endif /* SK_RLMT_MBUF_PRIVATE */
275
276
277#ifdef SK_LA_INFO
278typedef struct s_Rlmt_PacketInfo {
279 unsigned PacketLength; /* Length of packet. */
280 unsigned PacketType; /* Directed/Multicast/Broadcast. */
281} SK_RLMT_PINFO;
282#endif /* SK_LA_INFO */
283
284
285typedef struct s_RootId {
286 SK_U8 Id[8]; /* Root Bridge Id. */
287} SK_RLMT_ROOT_ID;
288
289
290typedef struct s_port {
291 SK_MAC_ADDR CheckAddr;
292 SK_BOOL SuspectTx;
293} SK_PORT_CHECK;
294
295
296typedef struct s_RlmtNet SK_RLMT_NET;
297
298
299typedef struct s_RlmtPort {
300
301/* ----- Public part (read-only) ----- */
302
303 SK_U8 PortState; /* Current state of this port. */
304
305 /* For PNMI */
306 SK_BOOL LinkDown;
307 SK_BOOL PortDown;
308 SK_U8 Align01;
309
310 SK_U32 PortNumber; /* Number of port on adapter. */
311 SK_RLMT_NET * Net; /* Net port belongs to. */
312
313 SK_U64 TxHelloCts;
314 SK_U64 RxHelloCts;
315 SK_U64 TxSpHelloReqCts;
316 SK_U64 RxSpHelloCts;
317
318/* ----- Private part ----- */
319
320/* SK_U64 PacketsRx; */ /* Total packets received. */
321 SK_U32 PacketsPerTimeSlot; /* Packets rxed between TOs. */
322/* SK_U32 DataPacketsPerTimeSlot; */ /* Data packets ... */
323 SK_U32 BpduPacketsPerTimeSlot; /* BPDU packets rxed in TS. */
324 SK_U64 BcTimeStamp; /* Time of last BC receive. */
325 SK_U64 GuTimeStamp; /* Time of entering GOING_UP. */
326
327 SK_TIMER UpTimer; /* Timer struct Link/Port up. */
328 SK_TIMER DownRxTimer; /* Timer struct down rx. */
329 SK_TIMER DownTxTimer; /* Timer struct down tx. */
330
331 SK_U32 CheckingState; /* Checking State. */
332
333 SK_ADDR_PORT * AddrPort;
334
335 SK_U8 Random[4]; /* Random value. */
336 unsigned PortsChecked; /* #ports checked. */
337 unsigned PortsSuspect; /* #ports checked that are s. */
338 SK_PORT_CHECK PortCheck[1];
339/* SK_PORT_CHECK PortCheck[SK_MAX_MACS - 1]; */
340
341 SK_BOOL PortStarted; /* Port is started. */
342 SK_BOOL PortNoRx; /* NoRx for >= 1 time slot. */
343 SK_BOOL RootIdSet;
344 SK_RLMT_ROOT_ID Root; /* Root Bridge Id. */
345} SK_RLMT_PORT;
346
347
348struct s_RlmtNet {
349
350/* ----- Public part (read-only) ----- */
351
352 SK_U32 NetNumber; /* Number of net. */
353
354 SK_RLMT_PORT * Port[SK_MAX_MACS]; /* Ports that belong to this net. */
355 SK_U32 NumPorts; /* Number of ports. */
356 SK_U32 PrefPort; /* Preferred port. */
357
358 /* For PNMI */
359
360 SK_U32 ChgBcPrio; /* Change Priority of last broadcast received */
361 SK_U32 RlmtMode; /* Check ... */
362 SK_U32 ActivePort; /* Active port. */
363 SK_U32 Preference; /* 0xFFFFFFFF: Automatic. */
364
365 SK_U8 RlmtState; /* Current RLMT state. */
366
367/* ----- Private part ----- */
368 SK_BOOL RootIdSet;
369 SK_U16 Align01;
370
371 int LinksUp; /* #Links up. */
372 int PortsUp; /* #Ports up. */
373 SK_U32 TimeoutValue; /* RLMT timeout value. */
374
375 SK_U32 CheckingState; /* Checking State. */
376 SK_RLMT_ROOT_ID Root; /* Root Bridge Id. */
377
378 SK_TIMER LocTimer; /* Timer struct. */
379 SK_TIMER SegTimer; /* Timer struct. */
380};
381
382
383typedef struct s_Rlmt {
384
385/* ----- Public part (read-only) ----- */
386
387 SK_U32 NumNets; /* Number of nets. */
388 SK_U32 NetsStarted; /* Number of nets started. */
389 SK_RLMT_NET Net[SK_MAX_NETS]; /* Array of available nets. */
390 SK_RLMT_PORT Port[SK_MAX_MACS]; /* Array of available ports. */
391
392/* ----- Private part ----- */
393 SK_BOOL CheckSwitch;
394 SK_BOOL RlmtOff; /* set to zero if the Mac addresses
395 are equal or the second one
396 is zero */
397 SK_U16 Align01;
398
399} SK_RLMT;
400
401
402extern SK_MAC_ADDR BridgeMcAddr;
403extern SK_MAC_ADDR SkRlmtMcAddr;
404
405/* function prototypes ********************************************************/
406
407
408#ifndef SK_KR_PROTO
409
410/* Functions provided by SkRlmt */
411
412/* ANSI/C++ compliant function prototypes */
413
414extern void SkRlmtInit(
415 SK_AC *pAC,
416 SK_IOC IoC,
417 int Level);
418
419extern int SkRlmtEvent(
420 SK_AC *pAC,
421 SK_IOC IoC,
422 SK_U32 Event,
423 SK_EVPARA Para);
424
425#else /* defined(SK_KR_PROTO) */
426
427/* Non-ANSI/C++ compliant function prototypes */
428
429#error KR-style function prototypes are not yet provided.
430
431#endif /* defined(SK_KR_PROTO)) */
432
433
434#ifdef __cplusplus
435}
436#endif /* __cplusplus */
437
438#endif /* __INC_SKRLMT_H */
diff --git a/drivers/net/sk98lin/h/sktimer.h b/drivers/net/sk98lin/h/sktimer.h
new file mode 100644
index 000000000000..04e6d7c1ec33
--- /dev/null
+++ b/drivers/net/sk98lin/h/sktimer.h
@@ -0,0 +1,63 @@
1/******************************************************************************
2 *
3 * Name: sktimer.h
4 * Project: Gigabit Ethernet Adapters, Event Scheduler Module
5 * Version: $Revision: 1.11 $
6 * Date: $Date: 2003/09/16 12:58:18 $
7 * Purpose: Defines for the timer functions
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * SKTIMER.H contains all defines and types for the timer functions
27 */
28
29#ifndef _SKTIMER_H_
30#define _SKTIMER_H_
31
32#include "h/skqueue.h"
33
34/*
35 * SK timer
36 * - needed wherever a timer is used. Put this in your data structure
37 * wherever you want.
38 */
39typedef struct s_Timer SK_TIMER;
40
41struct s_Timer {
42 SK_TIMER *TmNext; /* linked list */
43 SK_U32 TmClass; /* Timer Event class */
44 SK_U32 TmEvent; /* Timer Event value */
45 SK_EVPARA TmPara; /* Timer Event parameter */
46 SK_U32 TmDelta; /* delta time */
47 int TmActive; /* flag: active/inactive */
48};
49
50/*
51 * Timer control struct.
52 * - use in Adapters context name pAC->Tim
53 */
54typedef struct s_TimCtrl {
55 SK_TIMER *StQueue; /* Head of Timer queue */
56} SK_TIMCTRL;
57
58extern void SkTimerInit(SK_AC *pAC, SK_IOC Ioc, int Level);
59extern void SkTimerStop(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer);
60extern void SkTimerStart(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer,
61 SK_U32 Time, SK_U32 Class, SK_U32 Event, SK_EVPARA Para);
62extern void SkTimerDone(SK_AC *pAC, SK_IOC Ioc);
63#endif /* _SKTIMER_H_ */
diff --git a/drivers/net/sk98lin/h/sktypes.h b/drivers/net/sk98lin/h/sktypes.h
new file mode 100644
index 000000000000..40edc96e1055
--- /dev/null
+++ b/drivers/net/sk98lin/h/sktypes.h
@@ -0,0 +1,69 @@
1/******************************************************************************
2 *
3 * Name: sktypes.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.2 $
6 * Date: $Date: 2003/10/07 08:16:51 $
7 * Purpose: Define data types for Linux
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * In this file, all data types that are needed by the common modules
30 * are mapped to Linux data types.
31 *
32 *
33 * Include File Hierarchy:
34 *
35 *
36 ******************************************************************************/
37
38#ifndef __INC_SKTYPES_H
39#define __INC_SKTYPES_H
40
41
42/* defines *******************************************************************/
43
44/*
45 * Data types with a specific size. 'I' = signed, 'U' = unsigned.
46 */
47#define SK_I8 s8
48#define SK_U8 u8
49#define SK_I16 s16
50#define SK_U16 u16
51#define SK_I32 s32
52#define SK_U32 u32
53#define SK_I64 s64
54#define SK_U64 u64
55
56#define SK_UPTR ulong /* casting pointer <-> integral */
57
58/*
59* Boolean type.
60*/
61#define SK_BOOL SK_U8
62#define SK_FALSE 0
63#define SK_TRUE (!SK_FALSE)
64
65/* typedefs *******************************************************************/
66
67/* function prototypes ********************************************************/
68
69#endif /* __INC_SKTYPES_H */
diff --git a/drivers/net/sk98lin/h/skversion.h b/drivers/net/sk98lin/h/skversion.h
new file mode 100644
index 000000000000..a1a7294828e5
--- /dev/null
+++ b/drivers/net/sk98lin/h/skversion.h
@@ -0,0 +1,38 @@
1/******************************************************************************
2 *
3 * Name: version.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.5 $
6 * Date: $Date: 2003/10/07 08:16:51 $
7 * Purpose: SK specific Error log support
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifdef lint
26static const char SysKonnectFileId[] = "@(#) (C) SysKonnect GmbH.";
27static const char SysKonnectBuildNumber[] =
28 "@(#)SK-BUILD: 6.23 PL: 01";
29#endif /* !defined(lint) */
30
31#define BOOT_STRING "sk98lin: Network Device Driver v6.23\n" \
32 "(C)Copyright 1999-2004 Marvell(R)."
33
34#define VER_STRING "6.23"
35#define DRIVER_FILE_NAME "sk98lin"
36#define DRIVER_REL_DATE "Feb-13-2004"
37
38
diff --git a/drivers/net/sk98lin/h/skvpd.h b/drivers/net/sk98lin/h/skvpd.h
new file mode 100644
index 000000000000..bdc1a5eaaae9
--- /dev/null
+++ b/drivers/net/sk98lin/h/skvpd.h
@@ -0,0 +1,271 @@
1/******************************************************************************
2 *
3 * Name: skvpd.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.15 $
6 * Date: $Date: 2003/01/13 10:39:38 $
7 * Purpose: Defines and Macros for VPD handling
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2003 SysKonnect GmbH.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * The information in this file is provided "AS IS" without warranty.
21 *
22 ******************************************************************************/
23
24/*
25 * skvpd.h contains Diagnostic specific defines for VPD handling
26 */
27
28#ifndef __INC_SKVPD_H_
29#define __INC_SKVPD_H_
30
31/*
32 * Define Resource Type Identifiers and VPD keywords
33 */
34#define RES_ID 0x82 /* Resource Type ID String (Product Name) */
35#define RES_VPD_R 0x90 /* start of VPD read only area */
36#define RES_VPD_W 0x91 /* start of VPD read/write area */
37#define RES_END 0x78 /* Resource Type End Tag */
38
39#ifndef VPD_NAME
40#define VPD_NAME "Name" /* Product Name, VPD name of RES_ID */
41#endif /* VPD_NAME */
42#define VPD_PN "PN" /* Adapter Part Number */
43#define VPD_EC "EC" /* Adapter Engineering Level */
44#define VPD_MN "MN" /* Manufacture ID */
45#define VPD_SN "SN" /* Serial Number */
46#define VPD_CP "CP" /* Extended Capability */
47#define VPD_RV "RV" /* Checksum and Reserved */
48#define VPD_YA "YA" /* Asset Tag Identifier */
49#define VPD_VL "VL" /* First Error Log Message (SK specific) */
50#define VPD_VF "VF" /* Second Error Log Message (SK specific) */
51#define VPD_RW "RW" /* Remaining Read / Write Area */
52
53/* 'type' values for vpd_setup_para() */
54#define VPD_RO_KEY 1 /* RO keys are "PN", "EC", "MN", "SN", "RV" */
55#define VPD_RW_KEY 2 /* RW keys are "Yx", "Vx", and "RW" */
56
57/* 'op' values for vpd_setup_para() */
58#define ADD_KEY 1 /* add the key at the pos "RV" or "RW" */
59#define OWR_KEY 2 /* overwrite key if already exists */
60
61/*
62 * Define READ and WRITE Constants.
63 */
64
65#define VPD_DEV_ID_GENESIS 0x4300
66
67#define VPD_SIZE_YUKON 256
68#define VPD_SIZE_GENESIS 512
69#define VPD_SIZE 512
70#define VPD_READ 0x0000
71#define VPD_WRITE 0x8000
72
73#define VPD_STOP(pAC,IoC) VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG,VPD_WRITE)
74
75#define VPD_GET_RES_LEN(p) ((unsigned int) \
76 (* (SK_U8 *)&(p)[1]) |\
77 ((* (SK_U8 *)&(p)[2]) << 8))
78#define VPD_GET_VPD_LEN(p) ((unsigned int)(* (SK_U8 *)&(p)[2]))
79#define VPD_GET_VAL(p) ((char *)&(p)[3])
80
81#define VPD_MAX_LEN 50
82
83/* VPD status */
84 /* bit 7..1 reserved */
85#define VPD_VALID (1<<0) /* VPD data buffer, vpd_free_ro, */
86 /* and vpd_free_rw valid */
87
88/*
89 * VPD structs
90 */
91typedef struct s_vpd_status {
92 unsigned short Align01; /* Alignment */
93 unsigned short vpd_status; /* VPD status, description see above */
94 int vpd_free_ro; /* unused bytes in read only area */
95 int vpd_free_rw; /* bytes available in read/write area */
96} SK_VPD_STATUS;
97
98typedef struct s_vpd {
99 SK_VPD_STATUS v; /* VPD status structure */
100 char vpd_buf[VPD_SIZE]; /* VPD buffer */
101 int rom_size; /* VPD ROM Size from PCI_OUR_REG_2 */
102 int vpd_size; /* saved VPD-size */
103} SK_VPD;
104
105typedef struct s_vpd_para {
106 unsigned int p_len; /* parameter length */
107 char *p_val; /* points to the value */
108} SK_VPD_PARA;
109
110/*
111 * structure of Large Resource Type Identifiers
112 */
113
114/* was removed because of alignment problems */
115
116/*
117 * structure of VPD keywords
118 */
119typedef struct s_vpd_key {
120 char p_key[2]; /* 2 bytes ID string */
121 unsigned char p_len; /* 1 byte length */
122 char p_val; /* start of the value string */
123} SK_VPD_KEY;
124
125
126/*
127 * System specific VPD macros
128 */
129#ifndef SKDIAG
130#ifndef VPD_DO_IO
131#define VPD_OUT8(pAC,IoC,Addr,Val) (void)SkPciWriteCfgByte(pAC,Addr,Val)
132#define VPD_OUT16(pAC,IoC,Addr,Val) (void)SkPciWriteCfgWord(pAC,Addr,Val)
133#define VPD_OUT32(pAC,IoC,Addr,Val) (void)SkPciWriteCfgDWord(pAC,Addr,Val)
134#define VPD_IN8(pAC,IoC,Addr,pVal) (void)SkPciReadCfgByte(pAC,Addr,pVal)
135#define VPD_IN16(pAC,IoC,Addr,pVal) (void)SkPciReadCfgWord(pAC,Addr,pVal)
136#define VPD_IN32(pAC,IoC,Addr,pVal) (void)SkPciReadCfgDWord(pAC,Addr,pVal)
137#else /* VPD_DO_IO */
138#define VPD_OUT8(pAC,IoC,Addr,Val) SK_OUT8(IoC,PCI_C(Addr),Val)
139#define VPD_OUT16(pAC,IoC,Addr,Val) SK_OUT16(IoC,PCI_C(Addr),Val)
140#define VPD_OUT32(pAC,IoC,Addr,Val) SK_OUT32(IoC,PCI_C(Addr),Val)
141#define VPD_IN8(pAC,IoC,Addr,pVal) SK_IN8(IoC,PCI_C(Addr),pVal)
142#define VPD_IN16(pAC,IoC,Addr,pVal) SK_IN16(IoC,PCI_C(Addr),pVal)
143#define VPD_IN32(pAC,IoC,Addr,pVal) SK_IN32(IoC,PCI_C(Addr),pVal)
144#endif /* VPD_DO_IO */
145#else /* SKDIAG */
146#define VPD_OUT8(pAC,Ioc,Addr,Val) { \
147 if ((pAC)->DgT.DgUseCfgCycle) \
148 SkPciWriteCfgByte(pAC,Addr,Val); \
149 else \
150 SK_OUT8(pAC,PCI_C(Addr),Val); \
151 }
152#define VPD_OUT16(pAC,Ioc,Addr,Val) { \
153 if ((pAC)->DgT.DgUseCfgCycle) \
154 SkPciWriteCfgWord(pAC,Addr,Val); \
155 else \
156 SK_OUT16(pAC,PCI_C(Addr),Val); \
157 }
158#define VPD_OUT32(pAC,Ioc,Addr,Val) { \
159 if ((pAC)->DgT.DgUseCfgCycle) \
160 SkPciWriteCfgDWord(pAC,Addr,Val); \
161 else \
162 SK_OUT32(pAC,PCI_C(Addr),Val); \
163 }
164#define VPD_IN8(pAC,Ioc,Addr,pVal) { \
165 if ((pAC)->DgT.DgUseCfgCycle) \
166 SkPciReadCfgByte(pAC,Addr,pVal); \
167 else \
168 SK_IN8(pAC,PCI_C(Addr),pVal); \
169 }
170#define VPD_IN16(pAC,Ioc,Addr,pVal) { \
171 if ((pAC)->DgT.DgUseCfgCycle) \
172 SkPciReadCfgWord(pAC,Addr,pVal); \
173 else \
174 SK_IN16(pAC,PCI_C(Addr),pVal); \
175 }
176#define VPD_IN32(pAC,Ioc,Addr,pVal) { \
177 if ((pAC)->DgT.DgUseCfgCycle) \
178 SkPciReadCfgDWord(pAC,Addr,pVal); \
179 else \
180 SK_IN32(pAC,PCI_C(Addr),pVal); \
181 }
182#endif /* nSKDIAG */
183
184/* function prototypes ********************************************************/
185
186#ifndef SK_KR_PROTO
187#ifdef SKDIAG
188extern SK_U32 VpdReadDWord(
189 SK_AC *pAC,
190 SK_IOC IoC,
191 int addr);
192#endif /* SKDIAG */
193
194extern int VpdSetupPara(
195 SK_AC *pAC,
196 const char *key,
197 const char *buf,
198 int len,
199 int type,
200 int op);
201
202extern SK_VPD_STATUS *VpdStat(
203 SK_AC *pAC,
204 SK_IOC IoC);
205
206extern int VpdKeys(
207 SK_AC *pAC,
208 SK_IOC IoC,
209 char *buf,
210 int *len,
211 int *elements);
212
213extern int VpdRead(
214 SK_AC *pAC,
215 SK_IOC IoC,
216 const char *key,
217 char *buf,
218 int *len);
219
220extern SK_BOOL VpdMayWrite(
221 char *key);
222
223extern int VpdWrite(
224 SK_AC *pAC,
225 SK_IOC IoC,
226 const char *key,
227 const char *buf);
228
229extern int VpdDelete(
230 SK_AC *pAC,
231 SK_IOC IoC,
232 char *key);
233
234extern int VpdUpdate(
235 SK_AC *pAC,
236 SK_IOC IoC);
237
238extern void VpdErrLog(
239 SK_AC *pAC,
240 SK_IOC IoC,
241 char *msg);
242
243#ifdef SKDIAG
244extern int VpdReadBlock(
245 SK_AC *pAC,
246 SK_IOC IoC,
247 char *buf,
248 int addr,
249 int len);
250
251extern int VpdWriteBlock(
252 SK_AC *pAC,
253 SK_IOC IoC,
254 char *buf,
255 int addr,
256 int len);
257#endif /* SKDIAG */
258#else /* SK_KR_PROTO */
259extern SK_U32 VpdReadDWord();
260extern int VpdSetupPara();
261extern SK_VPD_STATUS *VpdStat();
262extern int VpdKeys();
263extern int VpdRead();
264extern SK_BOOL VpdMayWrite();
265extern int VpdWrite();
266extern int VpdDelete();
267extern int VpdUpdate();
268extern void VpdErrLog();
269#endif /* SK_KR_PROTO */
270
271#endif /* __INC_SKVPD_H_ */
diff --git a/drivers/net/sk98lin/h/xmac_ii.h b/drivers/net/sk98lin/h/xmac_ii.h
new file mode 100644
index 000000000000..2b19f8ad0318
--- /dev/null
+++ b/drivers/net/sk98lin/h/xmac_ii.h
@@ -0,0 +1,1579 @@
1/******************************************************************************
2 *
3 * Name: xmac_ii.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.52 $
6 * Date: $Date: 2003/10/02 16:35:50 $
7 * Purpose: Defines and Macros for Gigabit Ethernet Controller
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef __INC_XMAC_H
26#define __INC_XMAC_H
27
28#ifdef __cplusplus
29extern "C" {
30#endif /* __cplusplus */
31
32/* defines ********************************************************************/
33
34/*
35 * XMAC II registers
36 *
37 * The XMAC registers are 16 or 32 bits wide.
38 * The XMACs host processor interface is set to 16 bit mode,
39 * therefore ALL registers will be addressed with 16 bit accesses.
40 *
41 * The following macros are provided to access the XMAC registers
42 * XM_IN16(), XM_OUT16, XM_IN32(), XM_OUT32(), XM_INADR(), XM_OUTADR(),
43 * XM_INHASH(), and XM_OUTHASH().
44 * The macros are defined in SkGeHw.h.
45 *
46 * Note: NA reg = Network Address e.g DA, SA etc.
47 *
48 */
49#define XM_MMU_CMD 0x0000 /* 16 bit r/w MMU Command Register */
50 /* 0x0004: reserved */
51#define XM_POFF 0x0008 /* 32 bit r/w Packet Offset Register */
52#define XM_BURST 0x000c /* 32 bit r/w Burst Register for half duplex*/
53#define XM_1L_VLAN_TAG 0x0010 /* 16 bit r/w One Level VLAN Tag ID */
54#define XM_2L_VLAN_TAG 0x0014 /* 16 bit r/w Two Level VLAN Tag ID */
55 /* 0x0018 - 0x001e: reserved */
56#define XM_TX_CMD 0x0020 /* 16 bit r/w Transmit Command Register */
57#define XM_TX_RT_LIM 0x0024 /* 16 bit r/w Transmit Retry Limit Register */
58#define XM_TX_STIME 0x0028 /* 16 bit r/w Transmit Slottime Register */
59#define XM_TX_IPG 0x002c /* 16 bit r/w Transmit Inter Packet Gap */
60#define XM_RX_CMD 0x0030 /* 16 bit r/w Receive Command Register */
61#define XM_PHY_ADDR 0x0034 /* 16 bit r/w PHY Address Register */
62#define XM_PHY_DATA 0x0038 /* 16 bit r/w PHY Data Register */
63 /* 0x003c: reserved */
64#define XM_GP_PORT 0x0040 /* 32 bit r/w General Purpose Port Register */
65#define XM_IMSK 0x0044 /* 16 bit r/w Interrupt Mask Register */
66#define XM_ISRC 0x0048 /* 16 bit r/o Interrupt Status Register */
67#define XM_HW_CFG 0x004c /* 16 bit r/w Hardware Config Register */
68 /* 0x0050 - 0x005e: reserved */
69#define XM_TX_LO_WM 0x0060 /* 16 bit r/w Tx FIFO Low Water Mark */
70#define XM_TX_HI_WM 0x0062 /* 16 bit r/w Tx FIFO High Water Mark */
71#define XM_TX_THR 0x0064 /* 16 bit r/w Tx Request Threshold */
72#define XM_HT_THR 0x0066 /* 16 bit r/w Host Request Threshold */
73#define XM_PAUSE_DA 0x0068 /* NA reg r/w Pause Destination Address */
74 /* 0x006e: reserved */
75#define XM_CTL_PARA 0x0070 /* 32 bit r/w Control Parameter Register */
76#define XM_MAC_OPCODE 0x0074 /* 16 bit r/w Opcode for MAC control frames */
77#define XM_MAC_PTIME 0x0076 /* 16 bit r/w Pause time for MAC ctrl frames*/
78#define XM_TX_STAT 0x0078 /* 32 bit r/o Tx Status LIFO Register */
79
80 /* 0x0080 - 0x00fc: 16 NA reg r/w Exact Match Address Registers */
81 /* use the XM_EXM() macro to address */
82#define XM_EXM_START 0x0080 /* r/w Start Address of the EXM Regs */
83
84 /*
85 * XM_EXM(Reg)
86 *
87 * returns the XMAC address offset of specified Exact Match Addr Reg
88 *
89 * para: Reg EXM register to addr (0 .. 15)
90 *
91 * usage: XM_INADDR(IoC, MAC_1, XM_EXM(i), &val[i]);
92 */
93#define XM_EXM(Reg) (XM_EXM_START + ((Reg) << 3))
94
95#define XM_SRC_CHK 0x0100 /* NA reg r/w Source Check Address Register */
96#define XM_SA 0x0108 /* NA reg r/w Station Address Register */
97#define XM_HSM 0x0110 /* 64 bit r/w Hash Match Address Registers */
98#define XM_RX_LO_WM 0x0118 /* 16 bit r/w Receive Low Water Mark */
99#define XM_RX_HI_WM 0x011a /* 16 bit r/w Receive High Water Mark */
100#define XM_RX_THR 0x011c /* 32 bit r/w Receive Request Threshold */
101#define XM_DEV_ID 0x0120 /* 32 bit r/o Device ID Register */
102#define XM_MODE 0x0124 /* 32 bit r/w Mode Register */
103#define XM_LSA 0x0128 /* NA reg r/o Last Source Register */
104 /* 0x012e: reserved */
105#define XM_TS_READ 0x0130 /* 32 bit r/o Time Stamp Read Register */
106#define XM_TS_LOAD 0x0134 /* 32 bit r/o Time Stamp Load Value */
107 /* 0x0138 - 0x01fe: reserved */
108#define XM_STAT_CMD 0x0200 /* 16 bit r/w Statistics Command Register */
109#define XM_RX_CNT_EV 0x0204 /* 32 bit r/o Rx Counter Event Register */
110#define XM_TX_CNT_EV 0x0208 /* 32 bit r/o Tx Counter Event Register */
111#define XM_RX_EV_MSK 0x020c /* 32 bit r/w Rx Counter Event Mask */
112#define XM_TX_EV_MSK 0x0210 /* 32 bit r/w Tx Counter Event Mask */
113 /* 0x0204 - 0x027e: reserved */
114#define XM_TXF_OK 0x0280 /* 32 bit r/o Frames Transmitted OK Conuter */
115#define XM_TXO_OK_HI 0x0284 /* 32 bit r/o Octets Transmitted OK High Cnt*/
116#define XM_TXO_OK_LO 0x0288 /* 32 bit r/o Octets Transmitted OK Low Cnt */
117#define XM_TXF_BC_OK 0x028c /* 32 bit r/o Broadcast Frames Xmitted OK */
118#define XM_TXF_MC_OK 0x0290 /* 32 bit r/o Multicast Frames Xmitted OK */
119#define XM_TXF_UC_OK 0x0294 /* 32 bit r/o Unicast Frames Xmitted OK */
120#define XM_TXF_LONG 0x0298 /* 32 bit r/o Tx Long Frame Counter */
121#define XM_TXE_BURST 0x029c /* 32 bit r/o Tx Burst Event Counter */
122#define XM_TXF_MPAUSE 0x02a0 /* 32 bit r/o Tx Pause MAC Ctrl Frame Cnt */
123#define XM_TXF_MCTRL 0x02a4 /* 32 bit r/o Tx MAC Ctrl Frame Counter */
124#define XM_TXF_SNG_COL 0x02a8 /* 32 bit r/o Tx Single Collision Counter */
125#define XM_TXF_MUL_COL 0x02ac /* 32 bit r/o Tx Multiple Collision Counter */
126#define XM_TXF_ABO_COL 0x02b0 /* 32 bit r/o Tx aborted due to Exces. Col. */
127#define XM_TXF_LAT_COL 0x02b4 /* 32 bit r/o Tx Late Collision Counter */
128#define XM_TXF_DEF 0x02b8 /* 32 bit r/o Tx Deferred Frame Counter */
129#define XM_TXF_EX_DEF 0x02bc /* 32 bit r/o Tx Excessive Deferall Counter */
130#define XM_TXE_FIFO_UR 0x02c0 /* 32 bit r/o Tx FIFO Underrun Event Cnt */
131#define XM_TXE_CS_ERR 0x02c4 /* 32 bit r/o Tx Carrier Sense Error Cnt */
132#define XM_TXP_UTIL 0x02c8 /* 32 bit r/o Tx Utilization in % */
133 /* 0x02cc - 0x02ce: reserved */
134#define XM_TXF_64B 0x02d0 /* 32 bit r/o 64 Byte Tx Frame Counter */
135#define XM_TXF_127B 0x02d4 /* 32 bit r/o 65-127 Byte Tx Frame Counter */
136#define XM_TXF_255B 0x02d8 /* 32 bit r/o 128-255 Byte Tx Frame Counter */
137#define XM_TXF_511B 0x02dc /* 32 bit r/o 256-511 Byte Tx Frame Counter */
138#define XM_TXF_1023B 0x02e0 /* 32 bit r/o 512-1023 Byte Tx Frame Counter*/
139#define XM_TXF_MAX_SZ 0x02e4 /* 32 bit r/o 1024-MaxSize Byte Tx Frame Cnt*/
140 /* 0x02e8 - 0x02fe: reserved */
141#define XM_RXF_OK 0x0300 /* 32 bit r/o Frames Received OK */
142#define XM_RXO_OK_HI 0x0304 /* 32 bit r/o Octets Received OK High Cnt */
143#define XM_RXO_OK_LO 0x0308 /* 32 bit r/o Octets Received OK Low Counter*/
144#define XM_RXF_BC_OK 0x030c /* 32 bit r/o Broadcast Frames Received OK */
145#define XM_RXF_MC_OK 0x0310 /* 32 bit r/o Multicast Frames Received OK */
146#define XM_RXF_UC_OK 0x0314 /* 32 bit r/o Unicast Frames Received OK */
147#define XM_RXF_MPAUSE 0x0318 /* 32 bit r/o Rx Pause MAC Ctrl Frame Cnt */
148#define XM_RXF_MCTRL 0x031c /* 32 bit r/o Rx MAC Ctrl Frame Counter */
149#define XM_RXF_INV_MP 0x0320 /* 32 bit r/o Rx invalid Pause Frame Cnt */
150#define XM_RXF_INV_MOC 0x0324 /* 32 bit r/o Rx Frames with inv. MAC Opcode*/
151#define XM_RXE_BURST 0x0328 /* 32 bit r/o Rx Burst Event Counter */
152#define XM_RXE_FMISS 0x032c /* 32 bit r/o Rx Missed Frames Event Cnt */
153#define XM_RXF_FRA_ERR 0x0330 /* 32 bit r/o Rx Framing Error Counter */
154#define XM_RXE_FIFO_OV 0x0334 /* 32 bit r/o Rx FIFO overflow Event Cnt */
155#define XM_RXF_JAB_PKT 0x0338 /* 32 bit r/o Rx Jabber Packet Frame Cnt */
156#define XM_RXE_CAR_ERR 0x033c /* 32 bit r/o Rx Carrier Event Error Cnt */
157#define XM_RXF_LEN_ERR 0x0340 /* 32 bit r/o Rx in Range Length Error */
158#define XM_RXE_SYM_ERR 0x0344 /* 32 bit r/o Rx Symbol Error Counter */
159#define XM_RXE_SHT_ERR 0x0348 /* 32 bit r/o Rx Short Event Error Cnt */
160#define XM_RXE_RUNT 0x034c /* 32 bit r/o Rx Runt Event Counter */
161#define XM_RXF_LNG_ERR 0x0350 /* 32 bit r/o Rx Frame too Long Error Cnt */
162#define XM_RXF_FCS_ERR 0x0354 /* 32 bit r/o Rx Frame Check Seq. Error Cnt */
163 /* 0x0358 - 0x035a: reserved */
164#define XM_RXF_CEX_ERR 0x035c /* 32 bit r/o Rx Carrier Ext Error Frame Cnt*/
165#define XM_RXP_UTIL 0x0360 /* 32 bit r/o Rx Utilization in % */
166 /* 0x0364 - 0x0366: reserved */
167#define XM_RXF_64B 0x0368 /* 32 bit r/o 64 Byte Rx Frame Counter */
168#define XM_RXF_127B 0x036c /* 32 bit r/o 65-127 Byte Rx Frame Counter */
169#define XM_RXF_255B 0x0370 /* 32 bit r/o 128-255 Byte Rx Frame Counter */
170#define XM_RXF_511B 0x0374 /* 32 bit r/o 256-511 Byte Rx Frame Counter */
171#define XM_RXF_1023B 0x0378 /* 32 bit r/o 512-1023 Byte Rx Frame Counter*/
172#define XM_RXF_MAX_SZ 0x037c /* 32 bit r/o 1024-MaxSize Byte Rx Frame Cnt*/
173 /* 0x02e8 - 0x02fe: reserved */
174
175
176/*----------------------------------------------------------------------------*/
177/*
178 * XMAC Bit Definitions
179 *
180 * If the bit access behaviour differs from the register access behaviour
181 * (r/w, r/o) this is documented after the bit number.
182 * The following bit access behaviours are used:
183 * (sc) self clearing
184 * (ro) read only
185 */
186
187/* XM_MMU_CMD 16 bit r/w MMU Command Register */
188 /* Bit 15..13: reserved */
189#define XM_MMU_PHY_RDY (1<<12) /* Bit 12: PHY Read Ready */
190#define XM_MMU_PHY_BUSY (1<<11) /* Bit 11: PHY Busy */
191#define XM_MMU_IGN_PF (1<<10) /* Bit 10: Ignore Pause Frame */
192#define XM_MMU_MAC_LB (1<<9) /* Bit 9: Enable MAC Loopback */
193 /* Bit 8: reserved */
194#define XM_MMU_FRC_COL (1<<7) /* Bit 7: Force Collision */
195#define XM_MMU_SIM_COL (1<<6) /* Bit 6: Simulate Collision */
196#define XM_MMU_NO_PRE (1<<5) /* Bit 5: No MDIO Preamble */
197#define XM_MMU_GMII_FD (1<<4) /* Bit 4: GMII uses Full Duplex */
198#define XM_MMU_RAT_CTRL (1<<3) /* Bit 3: Enable Rate Control */
199#define XM_MMU_GMII_LOOP (1<<2) /* Bit 2: PHY is in Loopback Mode */
200#define XM_MMU_ENA_RX (1<<1) /* Bit 1: Enable Receiver */
201#define XM_MMU_ENA_TX (1<<0) /* Bit 0: Enable Transmitter */
202
203
204/* XM_TX_CMD 16 bit r/w Transmit Command Register */
205 /* Bit 15..7: reserved */
206#define XM_TX_BK2BK (1<<6) /* Bit 6: Ignor Carrier Sense (Tx Bk2Bk)*/
207#define XM_TX_ENC_BYP (1<<5) /* Bit 5: Set Encoder in Bypass Mode */
208#define XM_TX_SAM_LINE (1<<4) /* Bit 4: (sc) Start utilization calculation */
209#define XM_TX_NO_GIG_MD (1<<3) /* Bit 3: Disable Carrier Extension */
210#define XM_TX_NO_PRE (1<<2) /* Bit 2: Disable Preamble Generation */
211#define XM_TX_NO_CRC (1<<1) /* Bit 1: Disable CRC Generation */
212#define XM_TX_AUTO_PAD (1<<0) /* Bit 0: Enable Automatic Padding */
213
214
215/* XM_TX_RT_LIM 16 bit r/w Transmit Retry Limit Register */
216 /* Bit 15..5: reserved */
217#define XM_RT_LIM_MSK 0x1f /* Bit 4..0: Tx Retry Limit */
218
219
220/* XM_TX_STIME 16 bit r/w Transmit Slottime Register */
221 /* Bit 15..7: reserved */
222#define XM_STIME_MSK 0x7f /* Bit 6..0: Tx Slottime bits */
223
224
225/* XM_TX_IPG 16 bit r/w Transmit Inter Packet Gap */
226 /* Bit 15..8: reserved */
227#define XM_IPG_MSK 0xff /* Bit 7..0: IPG value bits */
228
229
230/* XM_RX_CMD 16 bit r/w Receive Command Register */
231 /* Bit 15..9: reserved */
232#define XM_RX_LENERR_OK (1<<8) /* Bit 8 don't set Rx Err bit for */
233 /* inrange error packets */
234#define XM_RX_BIG_PK_OK (1<<7) /* Bit 7 don't set Rx Err bit for */
235 /* jumbo packets */
236#define XM_RX_IPG_CAP (1<<6) /* Bit 6 repl. type field with IPG */
237#define XM_RX_TP_MD (1<<5) /* Bit 5: Enable transparent Mode */
238#define XM_RX_STRIP_FCS (1<<4) /* Bit 4: Enable FCS Stripping */
239#define XM_RX_SELF_RX (1<<3) /* Bit 3: Enable Rx of own packets */
240#define XM_RX_SAM_LINE (1<<2) /* Bit 2: (sc) Start utilization calculation */
241#define XM_RX_STRIP_PAD (1<<1) /* Bit 1: Strip pad bytes of Rx frames */
242#define XM_RX_DIS_CEXT (1<<0) /* Bit 0: Disable carrier ext. check */
243
244
245/* XM_PHY_ADDR 16 bit r/w PHY Address Register */
246 /* Bit 15..5: reserved */
247#define XM_PHY_ADDR_SZ 0x1f /* Bit 4..0: PHY Address bits */
248
249
250/* XM_GP_PORT 32 bit r/w General Purpose Port Register */
251 /* Bit 31..7: reserved */
252#define XM_GP_ANIP (1L<<6) /* Bit 6: (ro) Auto-Neg. in progress */
253#define XM_GP_FRC_INT (1L<<5) /* Bit 5: (sc) Force Interrupt */
254 /* Bit 4: reserved */
255#define XM_GP_RES_MAC (1L<<3) /* Bit 3: (sc) Reset MAC and FIFOs */
256#define XM_GP_RES_STAT (1L<<2) /* Bit 2: (sc) Reset the statistics module */
257 /* Bit 1: reserved */
258#define XM_GP_INP_ASS (1L<<0) /* Bit 0: (ro) GP Input Pin asserted */
259
260
261/* XM_IMSK 16 bit r/w Interrupt Mask Register */
262/* XM_ISRC 16 bit r/o Interrupt Status Register */
263 /* Bit 15: reserved */
264#define XM_IS_LNK_AE (1<<14) /* Bit 14: Link Asynchronous Event */
265#define XM_IS_TX_ABORT (1<<13) /* Bit 13: Transmit Abort, late Col. etc */
266#define XM_IS_FRC_INT (1<<12) /* Bit 12: Force INT bit set in GP */
267#define XM_IS_INP_ASS (1<<11) /* Bit 11: Input Asserted, GP bit 0 set */
268#define XM_IS_LIPA_RC (1<<10) /* Bit 10: Link Partner requests config */
269#define XM_IS_RX_PAGE (1<<9) /* Bit 9: Page Received */
270#define XM_IS_TX_PAGE (1<<8) /* Bit 8: Next Page Loaded for Transmit */
271#define XM_IS_AND (1<<7) /* Bit 7: Auto-Negotiation Done */
272#define XM_IS_TSC_OV (1<<6) /* Bit 6: Time Stamp Counter Overflow */
273#define XM_IS_RXC_OV (1<<5) /* Bit 5: Rx Counter Event Overflow */
274#define XM_IS_TXC_OV (1<<4) /* Bit 4: Tx Counter Event Overflow */
275#define XM_IS_RXF_OV (1<<3) /* Bit 3: Receive FIFO Overflow */
276#define XM_IS_TXF_UR (1<<2) /* Bit 2: Transmit FIFO Underrun */
277#define XM_IS_TX_COMP (1<<1) /* Bit 1: Frame Tx Complete */
278#define XM_IS_RX_COMP (1<<0) /* Bit 0: Frame Rx Complete */
279
280#define XM_DEF_MSK (~(XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE |\
281 XM_IS_AND | XM_IS_RXC_OV | XM_IS_TXC_OV | XM_IS_TXF_UR))
282
283
284/* XM_HW_CFG 16 bit r/w Hardware Config Register */
285 /* Bit 15.. 4: reserved */
286#define XM_HW_GEN_EOP (1<<3) /* Bit 3: generate End of Packet pulse */
287#define XM_HW_COM4SIG (1<<2) /* Bit 2: use Comma Detect for Sig. Det.*/
288 /* Bit 1: reserved */
289#define XM_HW_GMII_MD (1<<0) /* Bit 0: GMII Interface selected */
290
291
292/* XM_TX_LO_WM 16 bit r/w Tx FIFO Low Water Mark */
293/* XM_TX_HI_WM 16 bit r/w Tx FIFO High Water Mark */
294 /* Bit 15..10 reserved */
295#define XM_TX_WM_MSK 0x01ff /* Bit 9.. 0 Tx FIFO Watermark bits */
296
297/* XM_TX_THR 16 bit r/w Tx Request Threshold */
298/* XM_HT_THR 16 bit r/w Host Request Threshold */
299/* XM_RX_THR 16 bit r/w Rx Request Threshold */
300 /* Bit 15..11 reserved */
301#define XM_THR_MSK 0x03ff /* Bit 10.. 0 Rx/Tx Request Threshold bits */
302
303
304/* XM_TX_STAT 32 bit r/o Tx Status LIFO Register */
305#define XM_ST_VALID (1UL<<31) /* Bit 31: Status Valid */
306#define XM_ST_BYTE_CNT (0x3fffL<<17) /* Bit 30..17: Tx frame Length */
307#define XM_ST_RETRY_CNT (0x1fL<<12) /* Bit 16..12: Retry Count */
308#define XM_ST_EX_COL (1L<<11) /* Bit 11: Excessive Collisions */
309#define XM_ST_EX_DEF (1L<<10) /* Bit 10: Excessive Deferral */
310#define XM_ST_BURST (1L<<9) /* Bit 9: p. xmitted in burst md*/
311#define XM_ST_DEFER (1L<<8) /* Bit 8: packet was defered */
312#define XM_ST_BC (1L<<7) /* Bit 7: Broadcast packet */
313#define XM_ST_MC (1L<<6) /* Bit 6: Multicast packet */
314#define XM_ST_UC (1L<<5) /* Bit 5: Unicast packet */
315#define XM_ST_TX_UR (1L<<4) /* Bit 4: FIFO Underrun occured */
316#define XM_ST_CS_ERR (1L<<3) /* Bit 3: Carrier Sense Error */
317#define XM_ST_LAT_COL (1L<<2) /* Bit 2: Late Collision Error */
318#define XM_ST_MUL_COL (1L<<1) /* Bit 1: Multiple Collisions */
319#define XM_ST_SGN_COL (1L<<0) /* Bit 0: Single Collision */
320
321/* XM_RX_LO_WM 16 bit r/w Receive Low Water Mark */
322/* XM_RX_HI_WM 16 bit r/w Receive High Water Mark */
323 /* Bit 15..11: reserved */
324#define XM_RX_WM_MSK 0x03ff /* Bit 11.. 0: Rx FIFO Watermark bits */
325
326
327/* XM_DEV_ID 32 bit r/o Device ID Register */
328#define XM_DEV_OUI (0x00ffffffUL<<8) /* Bit 31..8: Device OUI */
329#define XM_DEV_REV (0x07L << 5) /* Bit 7..5: Chip Rev Num */
330
331
332/* XM_MODE 32 bit r/w Mode Register */
333 /* Bit 31..27: reserved */
334#define XM_MD_ENA_REJ (1L<<26) /* Bit 26: Enable Frame Reject */
335#define XM_MD_SPOE_E (1L<<25) /* Bit 25: Send Pause on Edge */
336 /* extern generated */
337#define XM_MD_TX_REP (1L<<24) /* Bit 24: Transmit Repeater Mode */
338#define XM_MD_SPOFF_I (1L<<23) /* Bit 23: Send Pause on FIFO full */
339 /* intern generated */
340#define XM_MD_LE_STW (1L<<22) /* Bit 22: Rx Stat Word in Little Endian */
341#define XM_MD_TX_CONT (1L<<21) /* Bit 21: Send Continuous */
342#define XM_MD_TX_PAUSE (1L<<20) /* Bit 20: (sc) Send Pause Frame */
343#define XM_MD_ATS (1L<<19) /* Bit 19: Append Time Stamp */
344#define XM_MD_SPOL_I (1L<<18) /* Bit 18: Send Pause on Low */
345 /* intern generated */
346#define XM_MD_SPOH_I (1L<<17) /* Bit 17: Send Pause on High */
347 /* intern generated */
348#define XM_MD_CAP (1L<<16) /* Bit 16: Check Address Pair */
349#define XM_MD_ENA_HASH (1L<<15) /* Bit 15: Enable Hashing */
350#define XM_MD_CSA (1L<<14) /* Bit 14: Check Station Address */
351#define XM_MD_CAA (1L<<13) /* Bit 13: Check Address Array */
352#define XM_MD_RX_MCTRL (1L<<12) /* Bit 12: Rx MAC Control Frame */
353#define XM_MD_RX_RUNT (1L<<11) /* Bit 11: Rx Runt Frames */
354#define XM_MD_RX_IRLE (1L<<10) /* Bit 10: Rx in Range Len Err Frame */
355#define XM_MD_RX_LONG (1L<<9) /* Bit 9: Rx Long Frame */
356#define XM_MD_RX_CRCE (1L<<8) /* Bit 8: Rx CRC Error Frame */
357#define XM_MD_RX_ERR (1L<<7) /* Bit 7: Rx Error Frame */
358#define XM_MD_DIS_UC (1L<<6) /* Bit 6: Disable Rx Unicast */
359#define XM_MD_DIS_MC (1L<<5) /* Bit 5: Disable Rx Multicast */
360#define XM_MD_DIS_BC (1L<<4) /* Bit 4: Disable Rx Broadcast */
361#define XM_MD_ENA_PROM (1L<<3) /* Bit 3: Enable Promiscuous */
362#define XM_MD_ENA_BE (1L<<2) /* Bit 2: Enable Big Endian */
363#define XM_MD_FTF (1L<<1) /* Bit 1: (sc) Flush Tx FIFO */
364#define XM_MD_FRF (1L<<0) /* Bit 0: (sc) Flush Rx FIFO */
365
366#define XM_PAUSE_MODE (XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I)
367#define XM_DEF_MODE (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\
368 XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA | XM_MD_CAA)
369
370/* XM_STAT_CMD 16 bit r/w Statistics Command Register */
371 /* Bit 16..6: reserved */
372#define XM_SC_SNP_RXC (1<<5) /* Bit 5: (sc) Snap Rx Counters */
373#define XM_SC_SNP_TXC (1<<4) /* Bit 4: (sc) Snap Tx Counters */
374#define XM_SC_CP_RXC (1<<3) /* Bit 3: Copy Rx Counters Continuously */
375#define XM_SC_CP_TXC (1<<2) /* Bit 2: Copy Tx Counters Continuously */
376#define XM_SC_CLR_RXC (1<<1) /* Bit 1: (sc) Clear Rx Counters */
377#define XM_SC_CLR_TXC (1<<0) /* Bit 0: (sc) Clear Tx Counters */
378
379
380/* XM_RX_CNT_EV 32 bit r/o Rx Counter Event Register */
381/* XM_RX_EV_MSK 32 bit r/w Rx Counter Event Mask */
382#define XMR_MAX_SZ_OV (1UL<<31) /* Bit 31: 1024-MaxSize Rx Cnt Ov*/
383#define XMR_1023B_OV (1L<<30) /* Bit 30: 512-1023Byte Rx Cnt Ov*/
384#define XMR_511B_OV (1L<<29) /* Bit 29: 256-511 Byte Rx Cnt Ov*/
385#define XMR_255B_OV (1L<<28) /* Bit 28: 128-255 Byte Rx Cnt Ov*/
386#define XMR_127B_OV (1L<<27) /* Bit 27: 65-127 Byte Rx Cnt Ov */
387#define XMR_64B_OV (1L<<26) /* Bit 26: 64 Byte Rx Cnt Ov */
388#define XMR_UTIL_OV (1L<<25) /* Bit 25: Rx Util Cnt Overflow */
389#define XMR_UTIL_UR (1L<<24) /* Bit 24: Rx Util Cnt Underrun */
390#define XMR_CEX_ERR_OV (1L<<23) /* Bit 23: CEXT Err Cnt Ov */
391 /* Bit 22: reserved */
392#define XMR_FCS_ERR_OV (1L<<21) /* Bit 21: Rx FCS Error Cnt Ov */
393#define XMR_LNG_ERR_OV (1L<<20) /* Bit 20: Rx too Long Err Cnt Ov*/
394#define XMR_RUNT_OV (1L<<19) /* Bit 19: Runt Event Cnt Ov */
395#define XMR_SHT_ERR_OV (1L<<18) /* Bit 18: Rx Short Ev Err Cnt Ov*/
396#define XMR_SYM_ERR_OV (1L<<17) /* Bit 17: Rx Sym Err Cnt Ov */
397 /* Bit 16: reserved */
398#define XMR_CAR_ERR_OV (1L<<15) /* Bit 15: Rx Carr Ev Err Cnt Ov */
399#define XMR_JAB_PKT_OV (1L<<14) /* Bit 14: Rx Jabb Packet Cnt Ov */
400#define XMR_FIFO_OV (1L<<13) /* Bit 13: Rx FIFO Ov Ev Cnt Ov */
401#define XMR_FRA_ERR_OV (1L<<12) /* Bit 12: Rx Framing Err Cnt Ov */
402#define XMR_FMISS_OV (1L<<11) /* Bit 11: Rx Missed Ev Cnt Ov */
403#define XMR_BURST (1L<<10) /* Bit 10: Rx Burst Event Cnt Ov */
404#define XMR_INV_MOC (1L<<9) /* Bit 9: Rx with inv. MAC OC Ov*/
405#define XMR_INV_MP (1L<<8) /* Bit 8: Rx inv Pause Frame Ov */
406#define XMR_MCTRL_OV (1L<<7) /* Bit 7: Rx MAC Ctrl-F Cnt Ov */
407#define XMR_MPAUSE_OV (1L<<6) /* Bit 6: Rx Pause MAC Ctrl-F Ov*/
408#define XMR_UC_OK_OV (1L<<5) /* Bit 5: Rx Unicast Frame CntOv*/
409#define XMR_MC_OK_OV (1L<<4) /* Bit 4: Rx Multicast Cnt Ov */
410#define XMR_BC_OK_OV (1L<<3) /* Bit 3: Rx Broadcast Cnt Ov */
411#define XMR_OK_LO_OV (1L<<2) /* Bit 2: Octets Rx OK Low CntOv*/
412#define XMR_OK_HI_OV (1L<<1) /* Bit 1: Octets Rx OK Hi Cnt Ov*/
413#define XMR_OK_OV (1L<<0) /* Bit 0: Frames Received Ok Ov */
414
415#define XMR_DEF_MSK (XMR_OK_LO_OV | XMR_OK_HI_OV)
416
417/* XM_TX_CNT_EV 32 bit r/o Tx Counter Event Register */
418/* XM_TX_EV_MSK 32 bit r/w Tx Counter Event Mask */
419 /* Bit 31..26: reserved */
420#define XMT_MAX_SZ_OV (1L<<25) /* Bit 25: 1024-MaxSize Tx Cnt Ov*/
421#define XMT_1023B_OV (1L<<24) /* Bit 24: 512-1023Byte Tx Cnt Ov*/
422#define XMT_511B_OV (1L<<23) /* Bit 23: 256-511 Byte Tx Cnt Ov*/
423#define XMT_255B_OV (1L<<22) /* Bit 22: 128-255 Byte Tx Cnt Ov*/
424#define XMT_127B_OV (1L<<21) /* Bit 21: 65-127 Byte Tx Cnt Ov */
425#define XMT_64B_OV (1L<<20) /* Bit 20: 64 Byte Tx Cnt Ov */
426#define XMT_UTIL_OV (1L<<19) /* Bit 19: Tx Util Cnt Overflow */
427#define XMT_UTIL_UR (1L<<18) /* Bit 18: Tx Util Cnt Underrun */
428#define XMT_CS_ERR_OV (1L<<17) /* Bit 17: Tx Carr Sen Err Cnt Ov*/
429#define XMT_FIFO_UR_OV (1L<<16) /* Bit 16: Tx FIFO Ur Ev Cnt Ov */
430#define XMT_EX_DEF_OV (1L<<15) /* Bit 15: Tx Ex Deferall Cnt Ov */
431#define XMT_DEF (1L<<14) /* Bit 14: Tx Deferred Cnt Ov */
432#define XMT_LAT_COL_OV (1L<<13) /* Bit 13: Tx Late Col Cnt Ov */
433#define XMT_ABO_COL_OV (1L<<12) /* Bit 12: Tx abo dueto Ex Col Ov*/
434#define XMT_MUL_COL_OV (1L<<11) /* Bit 11: Tx Mult Col Cnt Ov */
435#define XMT_SNG_COL (1L<<10) /* Bit 10: Tx Single Col Cnt Ov */
436#define XMT_MCTRL_OV (1L<<9) /* Bit 9: Tx MAC Ctrl Counter Ov*/
437#define XMT_MPAUSE (1L<<8) /* Bit 8: Tx Pause MAC Ctrl-F Ov*/
438#define XMT_BURST (1L<<7) /* Bit 7: Tx Burst Event Cnt Ov */
439#define XMT_LONG (1L<<6) /* Bit 6: Tx Long Frame Cnt Ov */
440#define XMT_UC_OK_OV (1L<<5) /* Bit 5: Tx Unicast Cnt Ov */
441#define XMT_MC_OK_OV (1L<<4) /* Bit 4: Tx Multicast Cnt Ov */
442#define XMT_BC_OK_OV (1L<<3) /* Bit 3: Tx Broadcast Cnt Ov */
443#define XMT_OK_LO_OV (1L<<2) /* Bit 2: Octets Tx OK Low CntOv*/
444#define XMT_OK_HI_OV (1L<<1) /* Bit 1: Octets Tx OK Hi Cnt Ov*/
445#define XMT_OK_OV (1L<<0) /* Bit 0: Frames Tx Ok Ov */
446
447#define XMT_DEF_MSK (XMT_OK_LO_OV | XMT_OK_HI_OV)
448
449/*
450 * Receive Frame Status Encoding
451 */
452#define XMR_FS_LEN (0x3fffUL<<18) /* Bit 31..18: Rx Frame Length */
453#define XMR_FS_2L_VLAN (1L<<17) /* Bit 17: tagged wh 2Lev VLAN ID*/
454#define XMR_FS_1L_VLAN (1L<<16) /* Bit 16: tagged wh 1Lev VLAN ID*/
455#define XMR_FS_BC (1L<<15) /* Bit 15: Broadcast Frame */
456#define XMR_FS_MC (1L<<14) /* Bit 14: Multicast Frame */
457#define XMR_FS_UC (1L<<13) /* Bit 13: Unicast Frame */
458 /* Bit 12: reserved */
459#define XMR_FS_BURST (1L<<11) /* Bit 11: Burst Mode */
460#define XMR_FS_CEX_ERR (1L<<10) /* Bit 10: Carrier Ext. Error */
461#define XMR_FS_802_3 (1L<<9) /* Bit 9: 802.3 Frame */
462#define XMR_FS_COL_ERR (1L<<8) /* Bit 8: Collision Error */
463#define XMR_FS_CAR_ERR (1L<<7) /* Bit 7: Carrier Event Error */
464#define XMR_FS_LEN_ERR (1L<<6) /* Bit 6: In-Range Length Error */
465#define XMR_FS_FRA_ERR (1L<<5) /* Bit 5: Framing Error */
466#define XMR_FS_RUNT (1L<<4) /* Bit 4: Runt Frame */
467#define XMR_FS_LNG_ERR (1L<<3) /* Bit 3: Giant (Jumbo) Frame */
468#define XMR_FS_FCS_ERR (1L<<2) /* Bit 2: Frame Check Sequ Err */
469#define XMR_FS_ERR (1L<<1) /* Bit 1: Frame Error */
470#define XMR_FS_MCTRL (1L<<0) /* Bit 0: MAC Control Packet */
471
472/*
473 * XMR_FS_ERR will be set if
474 * XMR_FS_FCS_ERR, XMR_FS_LNG_ERR, XMR_FS_RUNT,
475 * XMR_FS_FRA_ERR, XMR_FS_LEN_ERR, or XMR_FS_CEX_ERR
476 * is set. XMR_FS_LNG_ERR and XMR_FS_LEN_ERR will issue
477 * XMR_FS_ERR unless the corresponding bit in the Receive Command
478 * Register is set.
479 */
480#define XMR_FS_ANY_ERR XMR_FS_ERR
481
482/*----------------------------------------------------------------------------*/
483/*
484 * XMAC-PHY Registers, indirect addressed over the XMAC
485 */
486#define PHY_XMAC_CTRL 0x00 /* 16 bit r/w PHY Control Register */
487#define PHY_XMAC_STAT 0x01 /* 16 bit r/w PHY Status Register */
488#define PHY_XMAC_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
489#define PHY_XMAC_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
490#define PHY_XMAC_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
491#define PHY_XMAC_AUNE_LP 0x05 /* 16 bit r/o Link Partner Abi Reg */
492#define PHY_XMAC_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
493#define PHY_XMAC_NEPG 0x07 /* 16 bit r/w Next Page Register */
494#define PHY_XMAC_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */
495 /* 0x09 - 0x0e: reserved */
496#define PHY_XMAC_EXT_STAT 0x0f /* 16 bit r/o Ext Status Register */
497#define PHY_XMAC_RES_ABI 0x10 /* 16 bit r/o PHY Resolved Ability */
498
499/*----------------------------------------------------------------------------*/
500/*
501 * Broadcom-PHY Registers, indirect addressed over XMAC
502 */
503#define PHY_BCOM_CTRL 0x00 /* 16 bit r/w PHY Control Register */
504#define PHY_BCOM_STAT 0x01 /* 16 bit r/o PHY Status Register */
505#define PHY_BCOM_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
506#define PHY_BCOM_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
507#define PHY_BCOM_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
508#define PHY_BCOM_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */
509#define PHY_BCOM_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
510#define PHY_BCOM_NEPG 0x07 /* 16 bit r/w Next Page Register */
511#define PHY_BCOM_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */
512 /* Broadcom-specific registers */
513#define PHY_BCOM_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Ctrl Reg */
514#define PHY_BCOM_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */
515 /* 0x0b - 0x0e: reserved */
516#define PHY_BCOM_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */
517#define PHY_BCOM_P_EXT_CTRL 0x10 /* 16 bit r/w PHY Extended Ctrl Reg */
518#define PHY_BCOM_P_EXT_STAT 0x11 /* 16 bit r/o PHY Extended Stat Reg */
519#define PHY_BCOM_RE_CTR 0x12 /* 16 bit r/w Receive Error Counter */
520#define PHY_BCOM_FC_CTR 0x13 /* 16 bit r/w False Carrier Sense Cnt */
521#define PHY_BCOM_RNO_CTR 0x14 /* 16 bit r/w Receiver NOT_OK Cnt */
522 /* 0x15 - 0x17: reserved */
523#define PHY_BCOM_AUX_CTRL 0x18 /* 16 bit r/w Auxiliary Control Reg */
524#define PHY_BCOM_AUX_STAT 0x19 /* 16 bit r/o Auxiliary Stat Summary */
525#define PHY_BCOM_INT_STAT 0x1a /* 16 bit r/o Interrupt Status Reg */
526#define PHY_BCOM_INT_MASK 0x1b /* 16 bit r/w Interrupt Mask Reg */
527 /* 0x1c: reserved */
528 /* 0x1d - 0x1f: test registers */
529
530/*----------------------------------------------------------------------------*/
531/*
532 * Marvel-PHY Registers, indirect addressed over GMAC
533 */
534#define PHY_MARV_CTRL 0x00 /* 16 bit r/w PHY Control Register */
535#define PHY_MARV_STAT 0x01 /* 16 bit r/o PHY Status Register */
536#define PHY_MARV_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
537#define PHY_MARV_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
538#define PHY_MARV_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
539#define PHY_MARV_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */
540#define PHY_MARV_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
541#define PHY_MARV_NEPG 0x07 /* 16 bit r/w Next Page Register */
542#define PHY_MARV_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */
543 /* Marvel-specific registers */
544#define PHY_MARV_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Ctrl Reg */
545#define PHY_MARV_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */
546 /* 0x0b - 0x0e: reserved */
547#define PHY_MARV_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */
548#define PHY_MARV_PHY_CTRL 0x10 /* 16 bit r/w PHY Specific Ctrl Reg */
549#define PHY_MARV_PHY_STAT 0x11 /* 16 bit r/o PHY Specific Stat Reg */
550#define PHY_MARV_INT_MASK 0x12 /* 16 bit r/w Interrupt Mask Reg */
551#define PHY_MARV_INT_STAT 0x13 /* 16 bit r/o Interrupt Status Reg */
552#define PHY_MARV_EXT_CTRL 0x14 /* 16 bit r/w Ext. PHY Specific Ctrl */
553#define PHY_MARV_RXE_CNT 0x15 /* 16 bit r/w Receive Error Counter */
554#define PHY_MARV_EXT_ADR 0x16 /* 16 bit r/w Ext. Ad. for Cable Diag. */
555 /* 0x17: reserved */
556#define PHY_MARV_LED_CTRL 0x18 /* 16 bit r/w LED Control Reg */
557#define PHY_MARV_LED_OVER 0x19 /* 16 bit r/w Manual LED Override Reg */
558#define PHY_MARV_EXT_CTRL_2 0x1a /* 16 bit r/w Ext. PHY Specific Ctrl 2 */
559#define PHY_MARV_EXT_P_STAT 0x1b /* 16 bit r/w Ext. PHY Spec. Stat Reg */
560#define PHY_MARV_CABLE_DIAG 0x1c /* 16 bit r/o Cable Diagnostic Reg */
561 /* 0x1d - 0x1f: reserved */
562
563/*----------------------------------------------------------------------------*/
564/*
565 * Level One-PHY Registers, indirect addressed over XMAC
566 */
567#define PHY_LONE_CTRL 0x00 /* 16 bit r/w PHY Control Register */
568#define PHY_LONE_STAT 0x01 /* 16 bit r/o PHY Status Register */
569#define PHY_LONE_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
570#define PHY_LONE_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
571#define PHY_LONE_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
572#define PHY_LONE_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */
573#define PHY_LONE_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
574#define PHY_LONE_NEPG 0x07 /* 16 bit r/w Next Page Register */
575#define PHY_LONE_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */
576 /* Level One-specific registers */
577#define PHY_LONE_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Control Reg*/
578#define PHY_LONE_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */
579 /* 0x0b -0x0e: reserved */
580#define PHY_LONE_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */
581#define PHY_LONE_PORT_CFG 0x10 /* 16 bit r/w Port Configuration Reg*/
582#define PHY_LONE_Q_STAT 0x11 /* 16 bit r/o Quick Status Reg */
583#define PHY_LONE_INT_ENAB 0x12 /* 16 bit r/w Interrupt Enable Reg */
584#define PHY_LONE_INT_STAT 0x13 /* 16 bit r/o Interrupt Status Reg */
585#define PHY_LONE_LED_CFG 0x14 /* 16 bit r/w LED Configuration Reg */
586#define PHY_LONE_PORT_CTRL 0x15 /* 16 bit r/w Port Control Reg */
587#define PHY_LONE_CIM 0x16 /* 16 bit r/o CIM Reg */
588 /* 0x17 -0x1c: reserved */
589
590/*----------------------------------------------------------------------------*/
591/*
592 * National-PHY Registers, indirect addressed over XMAC
593 */
594#define PHY_NAT_CTRL 0x00 /* 16 bit r/w PHY Control Register */
595#define PHY_NAT_STAT 0x01 /* 16 bit r/w PHY Status Register */
596#define PHY_NAT_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
597#define PHY_NAT_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
598#define PHY_NAT_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
599#define PHY_NAT_AUNE_LP 0x05 /* 16 bit r/o Link Partner Ability Reg */
600#define PHY_NAT_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
601#define PHY_NAT_NEPG 0x07 /* 16 bit r/w Next Page Register */
602#define PHY_NAT_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner Reg */
603 /* National-specific registers */
604#define PHY_NAT_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Control Reg */
605#define PHY_NAT_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */
606 /* 0x0b -0x0e: reserved */
607#define PHY_NAT_EXT_STAT 0x0f /* 16 bit r/o Extended Status Register */
608#define PHY_NAT_EXT_CTRL1 0x10 /* 16 bit r/o Extended Control Reg1 */
609#define PHY_NAT_Q_STAT1 0x11 /* 16 bit r/o Quick Status Reg1 */
610#define PHY_NAT_10B_OP 0x12 /* 16 bit r/o 10Base-T Operations Reg */
611#define PHY_NAT_EXT_CTRL2 0x13 /* 16 bit r/o Extended Control Reg1 */
612#define PHY_NAT_Q_STAT2 0x14 /* 16 bit r/o Quick Status Reg2 */
613 /* 0x15 -0x18: reserved */
614#define PHY_NAT_PHY_ADDR 0x19 /* 16 bit r/o PHY Address Register */
615
616
617/*----------------------------------------------------------------------------*/
618
619/*
620 * PHY bit definitions
621 * Bits defined as PHY_X_..., PHY_B_..., PHY_L_... or PHY_N_... are
622 * XMAC/Broadcom/LevelOne/National/Marvell-specific.
623 * All other are general.
624 */
625
626/***** PHY_XMAC_CTRL 16 bit r/w PHY Control Register *****/
627/***** PHY_BCOM_CTRL 16 bit r/w PHY Control Register *****/
628/***** PHY_MARV_CTRL 16 bit r/w PHY Status Register *****/
629/***** PHY_LONE_CTRL 16 bit r/w PHY Control Register *****/
630#define PHY_CT_RESET (1<<15) /* Bit 15: (sc) clear all PHY related regs */
631#define PHY_CT_LOOP (1<<14) /* Bit 14: enable Loopback over PHY */
632#define PHY_CT_SPS_LSB (1<<13) /* Bit 13: (BC,L1) Speed select, lower bit */
633#define PHY_CT_ANE (1<<12) /* Bit 12: Auto-Negotiation Enabled */
634#define PHY_CT_PDOWN (1<<11) /* Bit 11: (BC,L1) Power Down Mode */
635#define PHY_CT_ISOL (1<<10) /* Bit 10: (BC,L1) Isolate Mode */
636#define PHY_CT_RE_CFG (1<<9) /* Bit 9: (sc) Restart Auto-Negotiation */
637#define PHY_CT_DUP_MD (1<<8) /* Bit 8: Duplex Mode */
638#define PHY_CT_COL_TST (1<<7) /* Bit 7: (BC,L1) Collision Test enabled */
639#define PHY_CT_SPS_MSB (1<<6) /* Bit 6: (BC,L1) Speed select, upper bit */
640 /* Bit 5..0: reserved */
641
642#define PHY_CT_SP1000 PHY_CT_SPS_MSB /* enable speed of 1000 Mbps */
643#define PHY_CT_SP100 PHY_CT_SPS_LSB /* enable speed of 100 Mbps */
644#define PHY_CT_SP10 (0) /* enable speed of 10 Mbps */
645
646
647/***** PHY_XMAC_STAT 16 bit r/w PHY Status Register *****/
648/***** PHY_BCOM_STAT 16 bit r/w PHY Status Register *****/
649/***** PHY_MARV_STAT 16 bit r/w PHY Status Register *****/
650/***** PHY_LONE_STAT 16 bit r/w PHY Status Register *****/
651 /* Bit 15..9: reserved */
652 /* (BC/L1) 100/10 Mbps cap bits ignored*/
653#define PHY_ST_EXT_ST (1<<8) /* Bit 8: Extended Status Present */
654 /* Bit 7: reserved */
655#define PHY_ST_PRE_SUP (1<<6) /* Bit 6: (BC/L1) preamble suppression */
656#define PHY_ST_AN_OVER (1<<5) /* Bit 5: Auto-Negotiation Over */
657#define PHY_ST_REM_FLT (1<<4) /* Bit 4: Remote Fault Condition Occured */
658#define PHY_ST_AN_CAP (1<<3) /* Bit 3: Auto-Negotiation Capability */
659#define PHY_ST_LSYNC (1<<2) /* Bit 2: Link Synchronized */
660#define PHY_ST_JAB_DET (1<<1) /* Bit 1: (BC/L1) Jabber Detected */
661#define PHY_ST_EXT_REG (1<<0) /* Bit 0: Extended Register available */
662
663
664/***** PHY_XMAC_ID1 16 bit r/o PHY ID1 Register */
665/***** PHY_BCOM_ID1 16 bit r/o PHY ID1 Register */
666/***** PHY_MARV_ID1 16 bit r/o PHY ID1 Register */
667/***** PHY_LONE_ID1 16 bit r/o PHY ID1 Register */
668#define PHY_I1_OUI_MSK (0x3f<<10) /* Bit 15..10: Organization Unique ID */
669#define PHY_I1_MOD_NUM (0x3f<<4) /* Bit 9.. 4: Model Number */
670#define PHY_I1_REV_MSK 0x0f /* Bit 3.. 0: Revision Number */
671
672/* different Broadcom PHY Ids */
673#define PHY_BCOM_ID1_A1 0x6041
674#define PHY_BCOM_ID1_B2 0x6043
675#define PHY_BCOM_ID1_C0 0x6044
676#define PHY_BCOM_ID1_C5 0x6047
677
678
679/***** PHY_XMAC_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
680/***** PHY_XMAC_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
681#define PHY_AN_NXT_PG (1<<15) /* Bit 15: Request Next Page */
682#define PHY_X_AN_ACK (1<<14) /* Bit 14: (ro) Acknowledge Received */
683#define PHY_X_AN_RFB (3<<12) /* Bit 13..12: Remote Fault Bits */
684 /* Bit 11.. 9: reserved */
685#define PHY_X_AN_PAUSE (3<<7) /* Bit 8.. 7: Pause Bits */
686#define PHY_X_AN_HD (1<<6) /* Bit 6: Half Duplex */
687#define PHY_X_AN_FD (1<<5) /* Bit 5: Full Duplex */
688 /* Bit 4.. 0: reserved */
689
690/***** PHY_BCOM_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
691/***** PHY_BCOM_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
692/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */
693 /* Bit 14: reserved */
694#define PHY_B_AN_RF (1<<13) /* Bit 13: Remote Fault */
695 /* Bit 12: reserved */
696#define PHY_B_AN_ASP (1<<11) /* Bit 11: Asymmetric Pause */
697#define PHY_B_AN_PC (1<<10) /* Bit 10: Pause Capable */
698 /* Bit 9..5: 100/10 BT cap bits ingnored */
699#define PHY_B_AN_SEL 0x1f /* Bit 4..0: Selector Field, 00001=Ethernet*/
700
701/***** PHY_LONE_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
702/***** PHY_LONE_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
703/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */
704 /* Bit 14: reserved */
705#define PHY_L_AN_RF (1<<13) /* Bit 13: Remote Fault */
706 /* Bit 12: reserved */
707#define PHY_L_AN_ASP (1<<11) /* Bit 11: Asymmetric Pause */
708#define PHY_L_AN_PC (1<<10) /* Bit 10: Pause Capable */
709 /* Bit 9..5: 100/10 BT cap bits ingnored */
710#define PHY_L_AN_SEL 0x1f /* Bit 4..0: Selector Field, 00001=Ethernet*/
711
712/***** PHY_NAT_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
713/***** PHY_NAT_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
714/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */
715 /* Bit 14: reserved */
716#define PHY_N_AN_RF (1<<13) /* Bit 13: Remote Fault */
717 /* Bit 12: reserved */
718#define PHY_N_AN_100F (1<<11) /* Bit 11: 100Base-T2 FD Support */
719#define PHY_N_AN_100H (1<<10) /* Bit 10: 100Base-T2 HD Support */
720 /* Bit 9..5: 100/10 BT cap bits ingnored */
721#define PHY_N_AN_SEL 0x1f /* Bit 4..0: Selector Field, 00001=Ethernet*/
722
723/* field type definition for PHY_x_AN_SEL */
724#define PHY_SEL_TYPE 0x01 /* 00001 = Ethernet */
725
726/***** PHY_XMAC_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/
727 /* Bit 15..4: reserved */
728#define PHY_ANE_LP_NP (1<<3) /* Bit 3: Link Partner can Next Page */
729#define PHY_ANE_LOC_NP (1<<2) /* Bit 2: Local PHY can Next Page */
730#define PHY_ANE_RX_PG (1<<1) /* Bit 1: Page Received */
731 /* Bit 0: reserved */
732
733/***** PHY_BCOM_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/
734/***** PHY_LONE_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/
735/***** PHY_MARV_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/
736 /* Bit 15..5: reserved */
737#define PHY_ANE_PAR_DF (1<<4) /* Bit 4: Parallel Detection Fault */
738/* PHY_ANE_LP_NP (see XMAC) Bit 3: Link Partner can Next Page */
739/* PHY_ANE_LOC_NP (see XMAC) Bit 2: Local PHY can Next Page */
740/* PHY_ANE_RX_PG (see XMAC) Bit 1: Page Received */
741#define PHY_ANE_LP_CAP (1<<0) /* Bit 0: Link Partner Auto-Neg. Cap. */
742
743/***** PHY_XMAC_NEPG 16 bit r/w Next Page Register *****/
744/***** PHY_BCOM_NEPG 16 bit r/w Next Page Register *****/
745/***** PHY_LONE_NEPG 16 bit r/w Next Page Register *****/
746/***** PHY_XMAC_NEPG_LP 16 bit r/o Next Page Link Partner *****/
747/***** PHY_BCOM_NEPG_LP 16 bit r/o Next Page Link Partner *****/
748/***** PHY_LONE_NEPG_LP 16 bit r/o Next Page Link Partner *****/
749#define PHY_NP_MORE (1<<15) /* Bit 15: More, Next Pages to follow */
750#define PHY_NP_ACK1 (1<<14) /* Bit 14: (ro) Ack1, for receiving a message */
751#define PHY_NP_MSG_VAL (1<<13) /* Bit 13: Message Page valid */
752#define PHY_NP_ACK2 (1<<12) /* Bit 12: Ack2, comply with msg content */
753#define PHY_NP_TOG (1<<11) /* Bit 11: Toggle Bit, ensure sync */
754#define PHY_NP_MSG 0x07ff /* Bit 10..0: Message from/to Link Partner */
755
756/*
757 * XMAC-Specific
758 */
759/***** PHY_XMAC_EXT_STAT 16 bit r/w Extended Status Register *****/
760#define PHY_X_EX_FD (1<<15) /* Bit 15: Device Supports Full Duplex */
761#define PHY_X_EX_HD (1<<14) /* Bit 14: Device Supports Half Duplex */
762 /* Bit 13..0: reserved */
763
764/***** PHY_XMAC_RES_ABI 16 bit r/o PHY Resolved Ability *****/
765 /* Bit 15..9: reserved */
766#define PHY_X_RS_PAUSE (3<<7) /* Bit 8..7: selected Pause Mode */
767#define PHY_X_RS_HD (1<<6) /* Bit 6: Half Duplex Mode selected */
768#define PHY_X_RS_FD (1<<5) /* Bit 5: Full Duplex Mode selected */
769#define PHY_X_RS_ABLMIS (1<<4) /* Bit 4: duplex or pause cap mismatch */
770#define PHY_X_RS_PAUMIS (1<<3) /* Bit 3: pause capability mismatch */
771 /* Bit 2..0: reserved */
772/*
773 * Remote Fault Bits (PHY_X_AN_RFB) encoding
774 */
775#define X_RFB_OK (0<<12) /* Bit 13..12 No errors, Link OK */
776#define X_RFB_LF (1<<12) /* Bit 13..12 Link Failure */
777#define X_RFB_OFF (2<<12) /* Bit 13..12 Offline */
778#define X_RFB_AN_ERR (3<<12) /* Bit 13..12 Auto-Negotiation Error */
779
780/*
781 * Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding
782 */
783#define PHY_X_P_NO_PAUSE (0<<7) /* Bit 8..7: no Pause Mode */
784#define PHY_X_P_SYM_MD (1<<7) /* Bit 8..7: symmetric Pause Mode */
785#define PHY_X_P_ASYM_MD (2<<7) /* Bit 8..7: asymmetric Pause Mode */
786#define PHY_X_P_BOTH_MD (3<<7) /* Bit 8..7: both Pause Mode */
787
788
789/*
790 * Broadcom-Specific
791 */
792/***** PHY_BCOM_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
793#define PHY_B_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */
794#define PHY_B_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */
795#define PHY_B_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */
796#define PHY_B_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */
797#define PHY_B_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */
798#define PHY_B_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */
799 /* Bit 7..0: reserved */
800
801/***** PHY_BCOM_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
802/***** PHY_MARV_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
803#define PHY_B_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */
804#define PHY_B_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */
805#define PHY_B_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */
806#define PHY_B_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status */
807#define PHY_B_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */
808#define PHY_B_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */
809 /* Bit 9..8: reserved */
810#define PHY_B_1000S_IEC 0xff /* Bit 7..0: Idle Error Count */
811
812/***** PHY_BCOM_EXT_STAT 16 bit r/o Extended Status Register *****/
813#define PHY_B_ES_X_FD_CAP (1<<15) /* Bit 15: 1000Base-X FD capable */
814#define PHY_B_ES_X_HD_CAP (1<<14) /* Bit 14: 1000Base-X HD capable */
815#define PHY_B_ES_T_FD_CAP (1<<13) /* Bit 13: 1000Base-T FD capable */
816#define PHY_B_ES_T_HD_CAP (1<<12) /* Bit 12: 1000Base-T HD capable */
817 /* Bit 11..0: reserved */
818
819/***** PHY_BCOM_P_EXT_CTRL 16 bit r/w PHY Extended Control Reg *****/
820#define PHY_B_PEC_MAC_PHY (1<<15) /* Bit 15: 10BIT/GMI-Interface */
821#define PHY_B_PEC_DIS_CROSS (1<<14) /* Bit 14: Disable MDI Crossover */
822#define PHY_B_PEC_TX_DIS (1<<13) /* Bit 13: Tx output Disabled */
823#define PHY_B_PEC_INT_DIS (1<<12) /* Bit 12: Interrupts Disabled */
824#define PHY_B_PEC_F_INT (1<<11) /* Bit 11: Force Interrupt */
825#define PHY_B_PEC_BY_45 (1<<10) /* Bit 10: Bypass 4B5B-Decoder */
826#define PHY_B_PEC_BY_SCR (1<<9) /* Bit 9: Bypass Scrambler */
827#define PHY_B_PEC_BY_MLT3 (1<<8) /* Bit 8: Bypass MLT3 Encoder */
828#define PHY_B_PEC_BY_RXA (1<<7) /* Bit 7: Bypass Rx Alignm. */
829#define PHY_B_PEC_RES_SCR (1<<6) /* Bit 6: Reset Scrambler */
830#define PHY_B_PEC_EN_LTR (1<<5) /* Bit 5: Ena LED Traffic Mode */
831#define PHY_B_PEC_LED_ON (1<<4) /* Bit 4: Force LED's on */
832#define PHY_B_PEC_LED_OFF (1<<3) /* Bit 3: Force LED's off */
833#define PHY_B_PEC_EX_IPG (1<<2) /* Bit 2: Extend Tx IPG Mode */
834#define PHY_B_PEC_3_LED (1<<1) /* Bit 1: Three Link LED mode */
835#define PHY_B_PEC_HIGH_LA (1<<0) /* Bit 0: GMII FIFO Elasticy */
836
837/***** PHY_BCOM_P_EXT_STAT 16 bit r/o PHY Extended Status Reg *****/
838 /* Bit 15..14: reserved */
839#define PHY_B_PES_CROSS_STAT (1<<13) /* Bit 13: MDI Crossover Status */
840#define PHY_B_PES_INT_STAT (1<<12) /* Bit 12: Interrupt Status */
841#define PHY_B_PES_RRS (1<<11) /* Bit 11: Remote Receiver Stat. */
842#define PHY_B_PES_LRS (1<<10) /* Bit 10: Local Receiver Stat. */
843#define PHY_B_PES_LOCKED (1<<9) /* Bit 9: Locked */
844#define PHY_B_PES_LS (1<<8) /* Bit 8: Link Status */
845#define PHY_B_PES_RF (1<<7) /* Bit 7: Remote Fault */
846#define PHY_B_PES_CE_ER (1<<6) /* Bit 6: Carrier Ext Error */
847#define PHY_B_PES_BAD_SSD (1<<5) /* Bit 5: Bad SSD */
848#define PHY_B_PES_BAD_ESD (1<<4) /* Bit 4: Bad ESD */
849#define PHY_B_PES_RX_ER (1<<3) /* Bit 3: Receive Error */
850#define PHY_B_PES_TX_ER (1<<2) /* Bit 2: Transmit Error */
851#define PHY_B_PES_LOCK_ER (1<<1) /* Bit 1: Lock Error */
852#define PHY_B_PES_MLT3_ER (1<<0) /* Bit 0: MLT3 code Error */
853
854/***** PHY_BCOM_FC_CTR 16 bit r/w False Carrier Counter *****/
855 /* Bit 15..8: reserved */
856#define PHY_B_FC_CTR 0xff /* Bit 7..0: False Carrier Counter */
857
858/***** PHY_BCOM_RNO_CTR 16 bit r/w Receive NOT_OK Counter *****/
859#define PHY_B_RC_LOC_MSK 0xff00 /* Bit 15..8: Local Rx NOT_OK cnt */
860#define PHY_B_RC_REM_MSK 0x00ff /* Bit 7..0: Remote Rx NOT_OK cnt */
861
862/***** PHY_BCOM_AUX_CTRL 16 bit r/w Auxiliary Control Reg *****/
863#define PHY_B_AC_L_SQE (1<<15) /* Bit 15: Low Squelch */
864#define PHY_B_AC_LONG_PACK (1<<14) /* Bit 14: Rx Long Packets */
865#define PHY_B_AC_ER_CTRL (3<<12) /* Bit 13..12: Edgerate Control */
866 /* Bit 11: reserved */
867#define PHY_B_AC_TX_TST (1<<10) /* Bit 10: Tx test bit, always 1 */
868 /* Bit 9.. 8: reserved */
869#define PHY_B_AC_DIS_PRF (1<<7) /* Bit 7: dis part resp filter */
870 /* Bit 6: reserved */
871#define PHY_B_AC_DIS_PM (1<<5) /* Bit 5: dis power management */
872 /* Bit 4: reserved */
873#define PHY_B_AC_DIAG (1<<3) /* Bit 3: Diagnostic Mode */
874 /* Bit 2.. 0: reserved */
875
876/***** PHY_BCOM_AUX_STAT 16 bit r/o Auxiliary Status Reg *****/
877#define PHY_B_AS_AN_C (1<<15) /* Bit 15: AutoNeg complete */
878#define PHY_B_AS_AN_CA (1<<14) /* Bit 14: AN Complete Ack */
879#define PHY_B_AS_ANACK_D (1<<13) /* Bit 13: AN Ack Detect */
880#define PHY_B_AS_ANAB_D (1<<12) /* Bit 12: AN Ability Detect */
881#define PHY_B_AS_NPW (1<<11) /* Bit 11: AN Next Page Wait */
882#define PHY_B_AS_AN_RES_MSK (7<<8) /* Bit 10..8: AN HDC */
883#define PHY_B_AS_PDF (1<<7) /* Bit 7: Parallel Detect. Fault */
884#define PHY_B_AS_RF (1<<6) /* Bit 6: Remote Fault */
885#define PHY_B_AS_ANP_R (1<<5) /* Bit 5: AN Page Received */
886#define PHY_B_AS_LP_ANAB (1<<4) /* Bit 4: LP AN Ability */
887#define PHY_B_AS_LP_NPAB (1<<3) /* Bit 3: LP Next Page Ability */
888#define PHY_B_AS_LS (1<<2) /* Bit 2: Link Status */
889#define PHY_B_AS_PRR (1<<1) /* Bit 1: Pause Resolution-Rx */
890#define PHY_B_AS_PRT (1<<0) /* Bit 0: Pause Resolution-Tx */
891
892#define PHY_B_AS_PAUSE_MSK (PHY_B_AS_PRR | PHY_B_AS_PRT)
893
894/***** PHY_BCOM_INT_STAT 16 bit r/o Interrupt Status Reg *****/
895/***** PHY_BCOM_INT_MASK 16 bit r/w Interrupt Mask Reg *****/
896 /* Bit 15: reserved */
897#define PHY_B_IS_PSE (1<<14) /* Bit 14: Pair Swap Error */
898#define PHY_B_IS_MDXI_SC (1<<13) /* Bit 13: MDIX Status Change */
899#define PHY_B_IS_HCT (1<<12) /* Bit 12: counter above 32k */
900#define PHY_B_IS_LCT (1<<11) /* Bit 11: counter above 128 */
901#define PHY_B_IS_AN_PR (1<<10) /* Bit 10: Page Received */
902#define PHY_B_IS_NO_HDCL (1<<9) /* Bit 9: No HCD Link */
903#define PHY_B_IS_NO_HDC (1<<8) /* Bit 8: No HCD */
904#define PHY_B_IS_NEG_USHDC (1<<7) /* Bit 7: Negotiated Unsup. HCD */
905#define PHY_B_IS_SCR_S_ER (1<<6) /* Bit 6: Scrambler Sync Error */
906#define PHY_B_IS_RRS_CHANGE (1<<5) /* Bit 5: Remote Rx Stat Change */
907#define PHY_B_IS_LRS_CHANGE (1<<4) /* Bit 4: Local Rx Stat Change */
908#define PHY_B_IS_DUP_CHANGE (1<<3) /* Bit 3: Duplex Mode Change */
909#define PHY_B_IS_LSP_CHANGE (1<<2) /* Bit 2: Link Speed Change */
910#define PHY_B_IS_LST_CHANGE (1<<1) /* Bit 1: Link Status Changed */
911#define PHY_B_IS_CRC_ER (1<<0) /* Bit 0: CRC Error */
912
913#define PHY_B_DEF_MSK (~(PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE))
914
915/* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */
916#define PHY_B_P_NO_PAUSE (0<<10) /* Bit 11..10: no Pause Mode */
917#define PHY_B_P_SYM_MD (1<<10) /* Bit 11..10: symmetric Pause Mode */
918#define PHY_B_P_ASYM_MD (2<<10) /* Bit 11..10: asymmetric Pause Mode */
919#define PHY_B_P_BOTH_MD (3<<10) /* Bit 11..10: both Pause Mode */
920
921/*
922 * Resolved Duplex mode and Capabilities (Aux Status Summary Reg)
923 */
924#define PHY_B_RES_1000FD (7<<8) /* Bit 10..8: 1000Base-T Full Dup. */
925#define PHY_B_RES_1000HD (6<<8) /* Bit 10..8: 1000Base-T Half Dup. */
926/* others: 100/10: invalid for us */
927
928/*
929 * Level One-Specific
930 */
931/***** PHY_LONE_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
932#define PHY_L_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */
933#define PHY_L_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */
934#define PHY_L_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */
935#define PHY_L_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */
936#define PHY_L_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */
937#define PHY_L_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */
938 /* Bit 7..0: reserved */
939
940/***** PHY_LONE_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
941#define PHY_L_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */
942#define PHY_L_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */
943#define PHY_L_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */
944#define PHY_L_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status */
945#define PHY_L_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */
946#define PHY_L_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */
947 /* Bit 9..8: reserved */
948#define PHY_B_1000S_IEC 0xff /* Bit 7..0: Idle Error Count */
949
950/***** PHY_LONE_EXT_STAT 16 bit r/o Extended Status Register *****/
951#define PHY_L_ES_X_FD_CAP (1<<15) /* Bit 15: 1000Base-X FD capable */
952#define PHY_L_ES_X_HD_CAP (1<<14) /* Bit 14: 1000Base-X HD capable */
953#define PHY_L_ES_T_FD_CAP (1<<13) /* Bit 13: 1000Base-T FD capable */
954#define PHY_L_ES_T_HD_CAP (1<<12) /* Bit 12: 1000Base-T HD capable */
955 /* Bit 11..0: reserved */
956
957/***** PHY_LONE_PORT_CFG 16 bit r/w Port Configuration Reg *****/
958#define PHY_L_PC_REP_MODE (1<<15) /* Bit 15: Repeater Mode */
959 /* Bit 14: reserved */
960#define PHY_L_PC_TX_DIS (1<<13) /* Bit 13: Tx output Disabled */
961#define PHY_L_PC_BY_SCR (1<<12) /* Bit 12: Bypass Scrambler */
962#define PHY_L_PC_BY_45 (1<<11) /* Bit 11: Bypass 4B5B-Decoder */
963#define PHY_L_PC_JAB_DIS (1<<10) /* Bit 10: Jabber Disabled */
964#define PHY_L_PC_SQE (1<<9) /* Bit 9: Enable Heartbeat */
965#define PHY_L_PC_TP_LOOP (1<<8) /* Bit 8: TP Loopback */
966#define PHY_L_PC_SSS (1<<7) /* Bit 7: Smart Speed Selection */
967#define PHY_L_PC_FIFO_SIZE (1<<6) /* Bit 6: FIFO Size */
968#define PHY_L_PC_PRE_EN (1<<5) /* Bit 5: Preamble Enable */
969#define PHY_L_PC_CIM (1<<4) /* Bit 4: Carrier Integrity Mon */
970#define PHY_L_PC_10_SER (1<<3) /* Bit 3: Use Serial Output */
971#define PHY_L_PC_ANISOL (1<<2) /* Bit 2: Unisolate Port */
972#define PHY_L_PC_TEN_BIT (1<<1) /* Bit 1: 10bit iface mode on */
973#define PHY_L_PC_ALTCLOCK (1<<0) /* Bit 0: (ro) ALTCLOCK Mode on */
974
975/***** PHY_LONE_Q_STAT 16 bit r/o Quick Status Reg *****/
976#define PHY_L_QS_D_RATE (3<<14) /* Bit 15..14: Data Rate */
977#define PHY_L_QS_TX_STAT (1<<13) /* Bit 13: Transmitting */
978#define PHY_L_QS_RX_STAT (1<<12) /* Bit 12: Receiving */
979#define PHY_L_QS_COL_STAT (1<<11) /* Bit 11: Collision */
980#define PHY_L_QS_L_STAT (1<<10) /* Bit 10: Link is up */
981#define PHY_L_QS_DUP_MOD (1<<9) /* Bit 9: Full/Half Duplex */
982#define PHY_L_QS_AN (1<<8) /* Bit 8: AutoNeg is On */
983#define PHY_L_QS_AN_C (1<<7) /* Bit 7: AN is Complete */
984#define PHY_L_QS_LLE (7<<4) /* Bit 6: Line Length Estim. */
985#define PHY_L_QS_PAUSE (1<<3) /* Bit 3: LP advertised Pause */
986#define PHY_L_QS_AS_PAUSE (1<<2) /* Bit 2: LP adv. asym. Pause */
987#define PHY_L_QS_ISOLATE (1<<1) /* Bit 1: CIM Isolated */
988#define PHY_L_QS_EVENT (1<<0) /* Bit 0: Event has occurred */
989
990/***** PHY_LONE_INT_ENAB 16 bit r/w Interrupt Enable Reg *****/
991/***** PHY_LONE_INT_STAT 16 bit r/o Interrupt Status Reg *****/
992 /* Bit 15..14: reserved */
993#define PHY_L_IS_AN_F (1<<13) /* Bit 13: Auto-Negotiation fault */
994 /* Bit 12: not described */
995#define PHY_L_IS_CROSS (1<<11) /* Bit 11: Crossover used */
996#define PHY_L_IS_POL (1<<10) /* Bit 10: Polarity correct. used */
997#define PHY_L_IS_SS (1<<9) /* Bit 9: Smart Speed Downgrade */
998#define PHY_L_IS_CFULL (1<<8) /* Bit 8: Counter Full */
999#define PHY_L_IS_AN_C (1<<7) /* Bit 7: AutoNeg Complete */
1000#define PHY_L_IS_SPEED (1<<6) /* Bit 6: Speed Changed */
1001#define PHY_L_IS_DUP (1<<5) /* Bit 5: Duplex Changed */
1002#define PHY_L_IS_LS (1<<4) /* Bit 4: Link Status Changed */
1003#define PHY_L_IS_ISOL (1<<3) /* Bit 3: Isolate Occured */
1004#define PHY_L_IS_MDINT (1<<2) /* Bit 2: (ro) STAT: MII Int Pending */
1005#define PHY_L_IS_INTEN (1<<1) /* Bit 1: ENAB: Enable IRQs */
1006#define PHY_L_IS_FORCE (1<<0) /* Bit 0: ENAB: Force Interrupt */
1007
1008/* int. mask */
1009#define PHY_L_DEF_MSK (PHY_L_IS_LS | PHY_L_IS_ISOL | PHY_L_IS_INTEN)
1010
1011/***** PHY_LONE_LED_CFG 16 bit r/w LED Configuration Reg *****/
1012#define PHY_L_LC_LEDC (3<<14) /* Bit 15..14: Col/Blink/On/Off */
1013#define PHY_L_LC_LEDR (3<<12) /* Bit 13..12: Rx/Blink/On/Off */
1014#define PHY_L_LC_LEDT (3<<10) /* Bit 11..10: Tx/Blink/On/Off */
1015#define PHY_L_LC_LEDG (3<<8) /* Bit 9..8: Giga/Blink/On/Off */
1016#define PHY_L_LC_LEDS (3<<6) /* Bit 7..6: 10-100/Blink/On/Off */
1017#define PHY_L_LC_LEDL (3<<4) /* Bit 5..4: Link/Blink/On/Off */
1018#define PHY_L_LC_LEDF (3<<2) /* Bit 3..2: Duplex/Blink/On/Off */
1019#define PHY_L_LC_PSTRECH (1<<1) /* Bit 1: Strech LED Pulses */
1020#define PHY_L_LC_FREQ (1<<0) /* Bit 0: 30/100 ms */
1021
1022/***** PHY_LONE_PORT_CTRL 16 bit r/w Port Control Reg *****/
1023#define PHY_L_PC_TX_TCLK (1<<15) /* Bit 15: Enable TX_TCLK */
1024 /* Bit 14: reserved */
1025#define PHY_L_PC_ALT_NP (1<<13) /* Bit 14: Alternate Next Page */
1026#define PHY_L_PC_GMII_ALT (1<<12) /* Bit 13: Alternate GMII driver */
1027 /* Bit 11: reserved */
1028#define PHY_L_PC_TEN_CRS (1<<10) /* Bit 10: Extend CRS*/
1029 /* Bit 9..0: not described */
1030
1031/***** PHY_LONE_CIM 16 bit r/o CIM Reg *****/
1032#define PHY_L_CIM_ISOL (255<<8)/* Bit 15..8: Isolate Count */
1033#define PHY_L_CIM_FALSE_CAR (255<<0)/* Bit 7..0: False Carrier Count */
1034
1035
1036/*
1037 * Pause Bits (PHY_L_AN_ASP and PHY_L_AN_PC) encoding
1038 */
1039#define PHY_L_P_NO_PAUSE (0<<10) /* Bit 11..10: no Pause Mode */
1040#define PHY_L_P_SYM_MD (1<<10) /* Bit 11..10: symmetric Pause Mode */
1041#define PHY_L_P_ASYM_MD (2<<10) /* Bit 11..10: asymmetric Pause Mode */
1042#define PHY_L_P_BOTH_MD (3<<10) /* Bit 11..10: both Pause Mode */
1043
1044
1045/*
1046 * National-Specific
1047 */
1048/***** PHY_NAT_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
1049#define PHY_N_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */
1050#define PHY_N_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */
1051#define PHY_N_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */
1052#define PHY_N_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */
1053#define PHY_N_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */
1054#define PHY_N_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */
1055#define PHY_N_1000C_APC (1<<7) /* Bit 7: Asymmetric Pause Cap. */
1056 /* Bit 6..0: reserved */
1057
1058/***** PHY_NAT_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
1059#define PHY_N_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */
1060#define PHY_N_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */
1061#define PHY_N_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */
1062#define PHY_N_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status*/
1063#define PHY_N_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */
1064#define PHY_N_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */
1065#define PHY_N_1000C_LP_APC (1<<9) /* Bit 9: LP Asym. Pause Cap. */
1066 /* Bit 8: reserved */
1067#define PHY_N_1000S_IEC 0xff /* Bit 7..0: Idle Error Count */
1068
1069/***** PHY_NAT_EXT_STAT 16 bit r/o Extended Status Register *****/
1070#define PHY_N_ES_X_FD_CAP (1<<15) /* Bit 15: 1000Base-X FD capable */
1071#define PHY_N_ES_X_HD_CAP (1<<14) /* Bit 14: 1000Base-X HD capable */
1072#define PHY_N_ES_T_FD_CAP (1<<13) /* Bit 13: 1000Base-T FD capable */
1073#define PHY_N_ES_T_HD_CAP (1<<12) /* Bit 12: 1000Base-T HD capable */
1074 /* Bit 11..0: reserved */
1075
1076/* todo: those are still missing */
1077/***** PHY_NAT_EXT_CTRL1 16 bit r/o Extended Control Reg1 *****/
1078/***** PHY_NAT_Q_STAT1 16 bit r/o Quick Status Reg1 *****/
1079/***** PHY_NAT_10B_OP 16 bit r/o 10Base-T Operations Reg *****/
1080/***** PHY_NAT_EXT_CTRL2 16 bit r/o Extended Control Reg1 *****/
1081/***** PHY_NAT_Q_STAT2 16 bit r/o Quick Status Reg2 *****/
1082/***** PHY_NAT_PHY_ADDR 16 bit r/o PHY Address Register *****/
1083
1084/*
1085 * Marvell-Specific
1086 */
1087/***** PHY_MARV_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
1088/***** PHY_MARV_AUNE_LP 16 bit r/w Link Part Ability Reg *****/
1089#define PHY_M_AN_NXT_PG BIT_15 /* Request Next Page */
1090#define PHY_M_AN_ACK BIT_14 /* (ro) Acknowledge Received */
1091#define PHY_M_AN_RF BIT_13 /* Remote Fault */
1092 /* Bit 12: reserved */
1093#define PHY_M_AN_ASP BIT_11 /* Asymmetric Pause */
1094#define PHY_M_AN_PC BIT_10 /* MAC Pause implemented */
1095#define PHY_M_AN_100_FD BIT_8 /* Advertise 100Base-TX Full Duplex */
1096#define PHY_M_AN_100_HD BIT_7 /* Advertise 100Base-TX Half Duplex */
1097#define PHY_M_AN_10_FD BIT_6 /* Advertise 10Base-TX Full Duplex */
1098#define PHY_M_AN_10_HD BIT_5 /* Advertise 10Base-TX Half Duplex */
1099
1100/* special defines for FIBER (88E1011S only) */
1101#define PHY_M_AN_ASP_X BIT_8 /* Asymmetric Pause */
1102#define PHY_M_AN_PC_X BIT_7 /* MAC Pause implemented */
1103#define PHY_M_AN_1000X_AHD BIT_6 /* Advertise 10000Base-X Half Duplex */
1104#define PHY_M_AN_1000X_AFD BIT_5 /* Advertise 10000Base-X Full Duplex */
1105
1106/* Pause Bits (PHY_M_AN_ASP_X and PHY_M_AN_PC_X) encoding */
1107#define PHY_M_P_NO_PAUSE_X (0<<7) /* Bit 8.. 7: no Pause Mode */
1108#define PHY_M_P_SYM_MD_X (1<<7) /* Bit 8.. 7: symmetric Pause Mode */
1109#define PHY_M_P_ASYM_MD_X (2<<7) /* Bit 8.. 7: asymmetric Pause Mode */
1110#define PHY_M_P_BOTH_MD_X (3<<7) /* Bit 8.. 7: both Pause Mode */
1111
1112/***** PHY_MARV_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
1113#define PHY_M_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */
1114#define PHY_M_1000C_MSE (1<<12) /* Bit 12: Manual Master/Slave Enable */
1115#define PHY_M_1000C_MSC (1<<11) /* Bit 11: M/S Configuration (1=Master) */
1116#define PHY_M_1000C_MPD (1<<10) /* Bit 10: Multi-Port Device */
1117#define PHY_M_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */
1118#define PHY_M_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */
1119 /* Bit 7..0: reserved */
1120
1121/***** PHY_MARV_PHY_CTRL 16 bit r/w PHY Specific Ctrl Reg *****/
1122#define PHY_M_PC_TX_FFD_MSK (3<<14) /* Bit 15..14: Tx FIFO Depth Mask */
1123#define PHY_M_PC_RX_FFD_MSK (3<<12) /* Bit 13..12: Rx FIFO Depth Mask */
1124#define PHY_M_PC_ASS_CRS_TX (1<<11) /* Bit 11: Assert CRS on Transmit */
1125#define PHY_M_PC_FL_GOOD (1<<10) /* Bit 10: Force Link Good */
1126#define PHY_M_PC_EN_DET_MSK (3<<8) /* Bit 9.. 8: Energy Detect Mask */
1127#define PHY_M_PC_ENA_EXT_D (1<<7) /* Bit 7: Enable Ext. Distance (10BT) */
1128#define PHY_M_PC_MDIX_MSK (3<<5) /* Bit 6.. 5: MDI/MDIX Config. Mask */
1129#define PHY_M_PC_DIS_125CLK (1<<4) /* Bit 4: Disable 125 CLK */
1130#define PHY_M_PC_MAC_POW_UP (1<<3) /* Bit 3: MAC Power up */
1131#define PHY_M_PC_SQE_T_ENA (1<<2) /* Bit 2: SQE Test Enabled */
1132#define PHY_M_PC_POL_R_DIS (1<<1) /* Bit 1: Polarity Reversal Disabled */
1133#define PHY_M_PC_DIS_JABBER (1<<0) /* Bit 0: Disable Jabber */
1134
1135#define PHY_M_PC_EN_DET SHIFT8(2) /* Energy Detect (Mode 1) */
1136#define PHY_M_PC_EN_DET_PLUS SHIFT8(3) /* Energy Detect Plus (Mode 2) */
1137
1138#define PHY_M_PC_MDI_XMODE(x) SHIFT5(x)
1139#define PHY_M_PC_MAN_MDI 0 /* 00 = Manual MDI configuration */
1140#define PHY_M_PC_MAN_MDIX 1 /* 01 = Manual MDIX configuration */
1141#define PHY_M_PC_ENA_AUTO 3 /* 11 = Enable Automatic Crossover */
1142
1143/***** PHY_MARV_PHY_STAT 16 bit r/o PHY Specific Status Reg *****/
1144#define PHY_M_PS_SPEED_MSK (3<<14) /* Bit 15..14: Speed Mask */
1145#define PHY_M_PS_SPEED_1000 (1<<15) /* 10 = 1000 Mbps */
1146#define PHY_M_PS_SPEED_100 (1<<14) /* 01 = 100 Mbps */
1147#define PHY_M_PS_SPEED_10 0 /* 00 = 10 Mbps */
1148#define PHY_M_PS_FULL_DUP (1<<13) /* Bit 13: Full Duplex */
1149#define PHY_M_PS_PAGE_REC (1<<12) /* Bit 12: Page Received */
1150#define PHY_M_PS_SPDUP_RES (1<<11) /* Bit 11: Speed & Duplex Resolved */
1151#define PHY_M_PS_LINK_UP (1<<10) /* Bit 10: Link Up */
1152#define PHY_M_PS_CABLE_MSK (3<<7) /* Bit 9.. 7: Cable Length Mask */
1153#define PHY_M_PS_MDI_X_STAT (1<<6) /* Bit 6: MDI Crossover Stat (1=MDIX) */
1154#define PHY_M_PS_DOWNS_STAT (1<<5) /* Bit 5: Downshift Status (1=downsh.) */
1155#define PHY_M_PS_ENDET_STAT (1<<4) /* Bit 4: Energy Detect Status (1=act) */
1156#define PHY_M_PS_TX_P_EN (1<<3) /* Bit 3: Tx Pause Enabled */
1157#define PHY_M_PS_RX_P_EN (1<<2) /* Bit 2: Rx Pause Enabled */
1158#define PHY_M_PS_POL_REV (1<<1) /* Bit 1: Polarity Reversed */
1159#define PHY_M_PC_JABBER (1<<0) /* Bit 0: Jabber */
1160
1161#define PHY_M_PS_PAUSE_MSK (PHY_M_PS_TX_P_EN | PHY_M_PS_RX_P_EN)
1162
1163/***** PHY_MARV_INT_MASK 16 bit r/w Interrupt Mask Reg *****/
1164/***** PHY_MARV_INT_STAT 16 bit r/o Interrupt Status Reg *****/
1165#define PHY_M_IS_AN_ERROR (1<<15) /* Bit 15: Auto-Negotiation Error */
1166#define PHY_M_IS_LSP_CHANGE (1<<14) /* Bit 14: Link Speed Changed */
1167#define PHY_M_IS_DUP_CHANGE (1<<13) /* Bit 13: Duplex Mode Changed */
1168#define PHY_M_IS_AN_PR (1<<12) /* Bit 12: Page Received */
1169#define PHY_M_IS_AN_COMPL (1<<11) /* Bit 11: Auto-Negotiation Completed */
1170#define PHY_M_IS_LST_CHANGE (1<<10) /* Bit 10: Link Status Changed */
1171#define PHY_M_IS_SYMB_ERROR (1<<9) /* Bit 9: Symbol Error */
1172#define PHY_M_IS_FALSE_CARR (1<<8) /* Bit 8: False Carrier */
1173#define PHY_M_IS_FIFO_ERROR (1<<7) /* Bit 7: FIFO Overflow/Underrun Error */
1174#define PHY_M_IS_MDI_CHANGE (1<<6) /* Bit 6: MDI Crossover Changed */
1175#define PHY_M_IS_DOWNSH_DET (1<<5) /* Bit 5: Downshift Detected */
1176#define PHY_M_IS_END_CHANGE (1<<4) /* Bit 4: Energy Detect Changed */
1177 /* Bit 3..2: reserved */
1178#define PHY_M_IS_POL_CHANGE (1<<1) /* Bit 1: Polarity Changed */
1179#define PHY_M_IS_JABBER (1<<0) /* Bit 0: Jabber */
1180
1181#define PHY_M_DEF_MSK (PHY_M_IS_AN_ERROR | PHY_M_IS_AN_PR | \
1182 PHY_M_IS_LST_CHANGE | PHY_M_IS_FIFO_ERROR)
1183
1184/***** PHY_MARV_EXT_CTRL 16 bit r/w Ext. PHY Specific Ctrl *****/
1185#define PHY_M_EC_M_DSC_MSK (3<<10) /* Bit 11..10: Master downshift counter */
1186#define PHY_M_EC_S_DSC_MSK (3<<8) /* Bit 9.. 8: Slave downshift counter */
1187#define PHY_M_EC_MAC_S_MSK (7<<4) /* Bit 6.. 4: Def. MAC interface speed */
1188#define PHY_M_EC_FIB_AN_ENA (1<<3) /* Bit 3: Fiber Auto-Neg. Enable */
1189
1190#define PHY_M_EC_M_DSC(x) SHIFT10(x) /* 00=1x; 01=2x; 10=3x; 11=4x */
1191#define PHY_M_EC_S_DSC(x) SHIFT8(x) /* 00=dis; 01=1x; 10=2x; 11=3x */
1192#define PHY_M_EC_MAC_S(x) SHIFT4(x) /* 01X=0; 110=2.5; 111=25 (MHz) */
1193
1194#define MAC_TX_CLK_0_MHZ 2
1195#define MAC_TX_CLK_2_5_MHZ 6
1196#define MAC_TX_CLK_25_MHZ 7
1197
1198/***** PHY_MARV_LED_CTRL 16 bit r/w LED Control Reg *****/
1199#define PHY_M_LEDC_DIS_LED (1<<15) /* Bit 15: Disable LED */
1200#define PHY_M_LEDC_PULS_MSK (7<<12) /* Bit 14..12: Pulse Stretch Mask */
1201#define PHY_M_LEDC_F_INT (1<<11) /* Bit 11: Force Interrupt */
1202#define PHY_M_LEDC_BL_R_MSK (7<<8) /* Bit 10.. 8: Blink Rate Mask */
1203 /* Bit 7.. 5: reserved */
1204#define PHY_M_LEDC_LINK_MSK (3<<3) /* Bit 4.. 3: Link Control Mask */
1205#define PHY_M_LEDC_DP_CTRL (1<<2) /* Bit 2: Duplex Control */
1206#define PHY_M_LEDC_RX_CTRL (1<<1) /* Bit 1: Rx activity / Link */
1207#define PHY_M_LEDC_TX_CTRL (1<<0) /* Bit 0: Tx activity / Link */
1208
1209#define PHY_M_LED_PULS_DUR(x) SHIFT12(x) /* Pulse Stretch Duration */
1210
1211#define PULS_NO_STR 0 /* no pulse stretching */
1212#define PULS_21MS 1 /* 21 ms to 42 ms */
1213#define PULS_42MS 2 /* 42 ms to 84 ms */
1214#define PULS_84MS 3 /* 84 ms to 170 ms */
1215#define PULS_170MS 4 /* 170 ms to 340 ms */
1216#define PULS_340MS 5 /* 340 ms to 670 ms */
1217#define PULS_670MS 6 /* 670 ms to 1.3 s */
1218#define PULS_1300MS 7 /* 1.3 s to 2.7 s */
1219
1220#define PHY_M_LED_BLINK_RT(x) SHIFT8(x) /* Blink Rate */
1221
1222#define BLINK_42MS 0 /* 42 ms */
1223#define BLINK_84MS 1 /* 84 ms */
1224#define BLINK_170MS 2 /* 170 ms */
1225#define BLINK_340MS 3 /* 340 ms */
1226#define BLINK_670MS 4 /* 670 ms */
1227 /* values 5 - 7: reserved */
1228
1229/***** PHY_MARV_LED_OVER 16 bit r/w Manual LED Override Reg *****/
1230#define PHY_M_LED_MO_DUP(x) SHIFT10(x) /* Bit 11..10: Duplex */
1231#define PHY_M_LED_MO_10(x) SHIFT8(x) /* Bit 9.. 8: Link 10 */
1232#define PHY_M_LED_MO_100(x) SHIFT6(x) /* Bit 7.. 6: Link 100 */
1233#define PHY_M_LED_MO_1000(x) SHIFT4(x) /* Bit 5.. 4: Link 1000 */
1234#define PHY_M_LED_MO_RX(x) SHIFT2(x) /* Bit 3.. 2: Rx */
1235#define PHY_M_LED_MO_TX(x) SHIFT0(x) /* Bit 1.. 0: Tx */
1236
1237#define MO_LED_NORM 0
1238#define MO_LED_BLINK 1
1239#define MO_LED_OFF 2
1240#define MO_LED_ON 3
1241
1242/***** PHY_MARV_EXT_CTRL_2 16 bit r/w Ext. PHY Specific Ctrl 2 *****/
1243 /* Bit 15.. 7: reserved */
1244#define PHY_M_EC2_FI_IMPED (1<<6) /* Bit 6: Fiber Input Impedance */
1245#define PHY_M_EC2_FO_IMPED (1<<5) /* Bit 5: Fiber Output Impedance */
1246#define PHY_M_EC2_FO_M_CLK (1<<4) /* Bit 4: Fiber Mode Clock Enable */
1247#define PHY_M_EC2_FO_BOOST (1<<3) /* Bit 3: Fiber Output Boost */
1248#define PHY_M_EC2_FO_AM_MSK 7 /* Bit 2.. 0: Fiber Output Amplitude */
1249
1250/***** PHY_MARV_EXT_P_STAT 16 bit r/w Ext. PHY Specific Status *****/
1251#define PHY_M_FC_AUTO_SEL (1<<15) /* Bit 15: Fiber/Copper Auto Sel. dis. */
1252#define PHY_M_FC_AN_REG_ACC (1<<14) /* Bit 14: Fiber/Copper Autoneg. reg acc */
1253#define PHY_M_FC_RESULUTION (1<<13) /* Bit 13: Fiber/Copper Resulution */
1254#define PHY_M_SER_IF_AN_BP (1<<12) /* Bit 12: Ser IF autoneg. bypass enable */
1255#define PHY_M_SER_IF_BP_ST (1<<11) /* Bit 11: Ser IF autoneg. bypass status */
1256#define PHY_M_IRQ_POLARITY (1<<10) /* Bit 10: IRQ polarity */
1257 /* Bit 9..4: reserved */
1258#define PHY_M_UNDOC1 (1<< 7) /* undocumented bit !! */
1259#define PHY_M_MODE_MASK (0xf<<0)/* Bit 3..0: copy of HWCFG MODE[3:0] */
1260
1261
1262/***** PHY_MARV_CABLE_DIAG 16 bit r/o Cable Diagnostic Reg *****/
1263#define PHY_M_CABD_ENA_TEST (1<<15) /* Bit 15: Enable Test */
1264#define PHY_M_CABD_STAT_MSK (3<<13) /* Bit 14..13: Status */
1265 /* Bit 12.. 8: reserved */
1266#define PHY_M_CABD_DIST_MSK 0xff /* Bit 7.. 0: Distance */
1267
1268/* values for Cable Diagnostic Status (11=fail; 00=OK; 10=open; 01=short) */
1269#define CABD_STAT_NORMAL 0
1270#define CABD_STAT_SHORT 1
1271#define CABD_STAT_OPEN 2
1272#define CABD_STAT_FAIL 3
1273
1274
1275/*
1276 * GMAC registers
1277 *
1278 * The GMAC registers are 16 or 32 bits wide.
1279 * The GMACs host processor interface is 16 bits wide,
1280 * therefore ALL registers will be addressed with 16 bit accesses.
1281 *
1282 * The following macros are provided to access the GMAC registers
1283 * GM_IN16(), GM_OUT16, GM_IN32(), GM_OUT32(), GM_INADR(), GM_OUTADR(),
1284 * GM_INHASH(), and GM_OUTHASH().
1285 * The macros are defined in SkGeHw.h.
1286 *
1287 * Note: NA reg = Network Address e.g DA, SA etc.
1288 *
1289 */
1290
1291/* Port Registers */
1292#define GM_GP_STAT 0x0000 /* 16 bit r/o General Purpose Status */
1293#define GM_GP_CTRL 0x0004 /* 16 bit r/w General Purpose Control */
1294#define GM_TX_CTRL 0x0008 /* 16 bit r/w Transmit Control Reg. */
1295#define GM_RX_CTRL 0x000c /* 16 bit r/w Receive Control Reg. */
1296#define GM_TX_FLOW_CTRL 0x0010 /* 16 bit r/w Transmit Flow-Control */
1297#define GM_TX_PARAM 0x0014 /* 16 bit r/w Transmit Parameter Reg. */
1298#define GM_SERIAL_MODE 0x0018 /* 16 bit r/w Serial Mode Register */
1299
1300/* Source Address Registers */
1301#define GM_SRC_ADDR_1L 0x001c /* 16 bit r/w Source Address 1 (low) */
1302#define GM_SRC_ADDR_1M 0x0020 /* 16 bit r/w Source Address 1 (middle) */
1303#define GM_SRC_ADDR_1H 0x0024 /* 16 bit r/w Source Address 1 (high) */
1304#define GM_SRC_ADDR_2L 0x0028 /* 16 bit r/w Source Address 2 (low) */
1305#define GM_SRC_ADDR_2M 0x002c /* 16 bit r/w Source Address 2 (middle) */
1306#define GM_SRC_ADDR_2H 0x0030 /* 16 bit r/w Source Address 2 (high) */
1307
1308/* Multicast Address Hash Registers */
1309#define GM_MC_ADDR_H1 0x0034 /* 16 bit r/w Multicast Address Hash 1 */
1310#define GM_MC_ADDR_H2 0x0038 /* 16 bit r/w Multicast Address Hash 2 */
1311#define GM_MC_ADDR_H3 0x003c /* 16 bit r/w Multicast Address Hash 3 */
1312#define GM_MC_ADDR_H4 0x0040 /* 16 bit r/w Multicast Address Hash 4 */
1313
1314/* Interrupt Source Registers */
1315#define GM_TX_IRQ_SRC 0x0044 /* 16 bit r/o Tx Overflow IRQ Source */
1316#define GM_RX_IRQ_SRC 0x0048 /* 16 bit r/o Rx Overflow IRQ Source */
1317#define GM_TR_IRQ_SRC 0x004c /* 16 bit r/o Tx/Rx Over. IRQ Source */
1318
1319/* Interrupt Mask Registers */
1320#define GM_TX_IRQ_MSK 0x0050 /* 16 bit r/w Tx Overflow IRQ Mask */
1321#define GM_RX_IRQ_MSK 0x0054 /* 16 bit r/w Rx Overflow IRQ Mask */
1322#define GM_TR_IRQ_MSK 0x0058 /* 16 bit r/w Tx/Rx Over. IRQ Mask */
1323
1324/* Serial Management Interface (SMI) Registers */
1325#define GM_SMI_CTRL 0x0080 /* 16 bit r/w SMI Control Register */
1326#define GM_SMI_DATA 0x0084 /* 16 bit r/w SMI Data Register */
1327#define GM_PHY_ADDR 0x0088 /* 16 bit r/w GPHY Address Register */
1328
1329/* MIB Counters */
1330#define GM_MIB_CNT_BASE 0x0100 /* Base Address of MIB Counters */
1331#define GM_MIB_CNT_SIZE 44 /* Number of MIB Counters */
1332
1333/*
1334 * MIB Counters base address definitions (low word) -
1335 * use offset 4 for access to high word (32 bit r/o)
1336 */
1337#define GM_RXF_UC_OK \
1338 (GM_MIB_CNT_BASE + 0) /* Unicast Frames Received OK */
1339#define GM_RXF_BC_OK \
1340 (GM_MIB_CNT_BASE + 8) /* Broadcast Frames Received OK */
1341#define GM_RXF_MPAUSE \
1342 (GM_MIB_CNT_BASE + 16) /* Pause MAC Ctrl Frames Received */
1343#define GM_RXF_MC_OK \
1344 (GM_MIB_CNT_BASE + 24) /* Multicast Frames Received OK */
1345#define GM_RXF_FCS_ERR \
1346 (GM_MIB_CNT_BASE + 32) /* Rx Frame Check Seq. Error */
1347 /* GM_MIB_CNT_BASE + 40: reserved */
1348#define GM_RXO_OK_LO \
1349 (GM_MIB_CNT_BASE + 48) /* Octets Received OK Low */
1350#define GM_RXO_OK_HI \
1351 (GM_MIB_CNT_BASE + 56) /* Octets Received OK High */
1352#define GM_RXO_ERR_LO \
1353 (GM_MIB_CNT_BASE + 64) /* Octets Received Invalid Low */
1354#define GM_RXO_ERR_HI \
1355 (GM_MIB_CNT_BASE + 72) /* Octets Received Invalid High */
1356#define GM_RXF_SHT \
1357 (GM_MIB_CNT_BASE + 80) /* Frames <64 Byte Received OK */
1358#define GM_RXE_FRAG \
1359 (GM_MIB_CNT_BASE + 88) /* Frames <64 Byte Received with FCS Err */
1360#define GM_RXF_64B \
1361 (GM_MIB_CNT_BASE + 96) /* 64 Byte Rx Frame */
1362#define GM_RXF_127B \
1363 (GM_MIB_CNT_BASE + 104) /* 65-127 Byte Rx Frame */
1364#define GM_RXF_255B \
1365 (GM_MIB_CNT_BASE + 112) /* 128-255 Byte Rx Frame */
1366#define GM_RXF_511B \
1367 (GM_MIB_CNT_BASE + 120) /* 256-511 Byte Rx Frame */
1368#define GM_RXF_1023B \
1369 (GM_MIB_CNT_BASE + 128) /* 512-1023 Byte Rx Frame */
1370#define GM_RXF_1518B \
1371 (GM_MIB_CNT_BASE + 136) /* 1024-1518 Byte Rx Frame */
1372#define GM_RXF_MAX_SZ \
1373 (GM_MIB_CNT_BASE + 144) /* 1519-MaxSize Byte Rx Frame */
1374#define GM_RXF_LNG_ERR \
1375 (GM_MIB_CNT_BASE + 152) /* Rx Frame too Long Error */
1376#define GM_RXF_JAB_PKT \
1377 (GM_MIB_CNT_BASE + 160) /* Rx Jabber Packet Frame */
1378 /* GM_MIB_CNT_BASE + 168: reserved */
1379#define GM_RXE_FIFO_OV \
1380 (GM_MIB_CNT_BASE + 176) /* Rx FIFO overflow Event */
1381 /* GM_MIB_CNT_BASE + 184: reserved */
1382#define GM_TXF_UC_OK \
1383 (GM_MIB_CNT_BASE + 192) /* Unicast Frames Xmitted OK */
1384#define GM_TXF_BC_OK \
1385 (GM_MIB_CNT_BASE + 200) /* Broadcast Frames Xmitted OK */
1386#define GM_TXF_MPAUSE \
1387 (GM_MIB_CNT_BASE + 208) /* Pause MAC Ctrl Frames Xmitted */
1388#define GM_TXF_MC_OK \
1389 (GM_MIB_CNT_BASE + 216) /* Multicast Frames Xmitted OK */
1390#define GM_TXO_OK_LO \
1391 (GM_MIB_CNT_BASE + 224) /* Octets Transmitted OK Low */
1392#define GM_TXO_OK_HI \
1393 (GM_MIB_CNT_BASE + 232) /* Octets Transmitted OK High */
1394#define GM_TXF_64B \
1395 (GM_MIB_CNT_BASE + 240) /* 64 Byte Tx Frame */
1396#define GM_TXF_127B \
1397 (GM_MIB_CNT_BASE + 248) /* 65-127 Byte Tx Frame */
1398#define GM_TXF_255B \
1399 (GM_MIB_CNT_BASE + 256) /* 128-255 Byte Tx Frame */
1400#define GM_TXF_511B \
1401 (GM_MIB_CNT_BASE + 264) /* 256-511 Byte Tx Frame */
1402#define GM_TXF_1023B \
1403 (GM_MIB_CNT_BASE + 272) /* 512-1023 Byte Tx Frame */
1404#define GM_TXF_1518B \
1405 (GM_MIB_CNT_BASE + 280) /* 1024-1518 Byte Tx Frame */
1406#define GM_TXF_MAX_SZ \
1407 (GM_MIB_CNT_BASE + 288) /* 1519-MaxSize Byte Tx Frame */
1408 /* GM_MIB_CNT_BASE + 296: reserved */
1409#define GM_TXF_COL \
1410 (GM_MIB_CNT_BASE + 304) /* Tx Collision */
1411#define GM_TXF_LAT_COL \
1412 (GM_MIB_CNT_BASE + 312) /* Tx Late Collision */
1413#define GM_TXF_ABO_COL \
1414 (GM_MIB_CNT_BASE + 320) /* Tx aborted due to Exces. Col. */
1415#define GM_TXF_MUL_COL \
1416 (GM_MIB_CNT_BASE + 328) /* Tx Multiple Collision */
1417#define GM_TXF_SNG_COL \
1418 (GM_MIB_CNT_BASE + 336) /* Tx Single Collision */
1419#define GM_TXE_FIFO_UR \
1420 (GM_MIB_CNT_BASE + 344) /* Tx FIFO Underrun Event */
1421
1422/*----------------------------------------------------------------------------*/
1423/*
1424 * GMAC Bit Definitions
1425 *
1426 * If the bit access behaviour differs from the register access behaviour
1427 * (r/w, r/o) this is documented after the bit number.
1428 * The following bit access behaviours are used:
1429 * (sc) self clearing
1430 * (r/o) read only
1431 */
1432
1433/* GM_GP_STAT 16 bit r/o General Purpose Status Register */
1434#define GM_GPSR_SPEED (1<<15) /* Bit 15: Port Speed (1 = 100 Mbps) */
1435#define GM_GPSR_DUPLEX (1<<14) /* Bit 14: Duplex Mode (1 = Full) */
1436#define GM_GPSR_FC_TX_DIS (1<<13) /* Bit 13: Tx Flow-Control Mode Disabled */
1437#define GM_GPSR_LINK_UP (1<<12) /* Bit 12: Link Up Status */
1438#define GM_GPSR_PAUSE (1<<11) /* Bit 11: Pause State */
1439#define GM_GPSR_TX_ACTIVE (1<<10) /* Bit 10: Tx in Progress */
1440#define GM_GPSR_EXC_COL (1<<9) /* Bit 9: Excessive Collisions Occured */
1441#define GM_GPSR_LAT_COL (1<<8) /* Bit 8: Late Collisions Occured */
1442 /* Bit 7..6: reserved */
1443#define GM_GPSR_PHY_ST_CH (1<<5) /* Bit 5: PHY Status Change */
1444#define GM_GPSR_GIG_SPEED (1<<4) /* Bit 4: Gigabit Speed (1 = 1000 Mbps) */
1445#define GM_GPSR_PART_MODE (1<<3) /* Bit 3: Partition mode */
1446#define GM_GPSR_FC_RX_DIS (1<<2) /* Bit 2: Rx Flow-Control Mode Disabled */
1447#define GM_GPSR_PROM_EN (1<<1) /* Bit 1: Promiscuous Mode Enabled */
1448 /* Bit 0: reserved */
1449
1450/* GM_GP_CTRL 16 bit r/w General Purpose Control Register */
1451 /* Bit 15: reserved */
1452#define GM_GPCR_PROM_ENA (1<<14) /* Bit 14: Enable Promiscuous Mode */
1453#define GM_GPCR_FC_TX_DIS (1<<13) /* Bit 13: Disable Tx Flow-Control Mode */
1454#define GM_GPCR_TX_ENA (1<<12) /* Bit 12: Enable Transmit */
1455#define GM_GPCR_RX_ENA (1<<11) /* Bit 11: Enable Receive */
1456#define GM_GPCR_BURST_ENA (1<<10) /* Bit 10: Enable Burst Mode */
1457#define GM_GPCR_LOOP_ENA (1<<9) /* Bit 9: Enable MAC Loopback Mode */
1458#define GM_GPCR_PART_ENA (1<<8) /* Bit 8: Enable Partition Mode */
1459#define GM_GPCR_GIGS_ENA (1<<7) /* Bit 7: Gigabit Speed (1000 Mbps) */
1460#define GM_GPCR_FL_PASS (1<<6) /* Bit 6: Force Link Pass */
1461#define GM_GPCR_DUP_FULL (1<<5) /* Bit 5: Full Duplex Mode */
1462#define GM_GPCR_FC_RX_DIS (1<<4) /* Bit 4: Disable Rx Flow-Control Mode */
1463#define GM_GPCR_SPEED_100 (1<<3) /* Bit 3: Port Speed 100 Mbps */
1464#define GM_GPCR_AU_DUP_DIS (1<<2) /* Bit 2: Disable Auto-Update Duplex */
1465#define GM_GPCR_AU_FCT_DIS (1<<1) /* Bit 1: Disable Auto-Update Flow-C. */
1466#define GM_GPCR_AU_SPD_DIS (1<<0) /* Bit 0: Disable Auto-Update Speed */
1467
1468#define GM_GPCR_SPEED_1000 (GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100)
1469#define GM_GPCR_AU_ALL_DIS (GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS |\
1470 GM_GPCR_AU_SPD_DIS)
1471
1472/* GM_TX_CTRL 16 bit r/w Transmit Control Register */
1473#define GM_TXCR_FORCE_JAM (1<<15) /* Bit 15: Force Jam / Flow-Control */
1474#define GM_TXCR_CRC_DIS (1<<14) /* Bit 14: Disable insertion of CRC */
1475#define GM_TXCR_PAD_DIS (1<<13) /* Bit 13: Disable padding of packets */
1476#define GM_TXCR_COL_THR_MSK (1<<10) /* Bit 12..10: Collision Threshold */
1477
1478#define TX_COL_THR(x) (SHIFT10(x) & GM_TXCR_COL_THR_MSK)
1479
1480#define TX_COL_DEF 0x04
1481
1482/* GM_RX_CTRL 16 bit r/w Receive Control Register */
1483#define GM_RXCR_UCF_ENA (1<<15) /* Bit 15: Enable Unicast filtering */
1484#define GM_RXCR_MCF_ENA (1<<14) /* Bit 14: Enable Multicast filtering */
1485#define GM_RXCR_CRC_DIS (1<<13) /* Bit 13: Remove 4-byte CRC */
1486#define GM_RXCR_PASS_FC (1<<12) /* Bit 12: Pass FC packets to FIFO */
1487
1488/* GM_TX_PARAM 16 bit r/w Transmit Parameter Register */
1489#define GM_TXPA_JAMLEN_MSK (0x03<<14) /* Bit 15..14: Jam Length */
1490#define GM_TXPA_JAMIPG_MSK (0x1f<<9) /* Bit 13..9: Jam IPG */
1491#define GM_TXPA_JAMDAT_MSK (0x1f<<4) /* Bit 8..4: IPG Jam to Data */
1492 /* Bit 3..0: reserved */
1493
1494#define TX_JAM_LEN_VAL(x) (SHIFT14(x) & GM_TXPA_JAMLEN_MSK)
1495#define TX_JAM_IPG_VAL(x) (SHIFT9(x) & GM_TXPA_JAMIPG_MSK)
1496#define TX_IPG_JAM_DATA(x) (SHIFT4(x) & GM_TXPA_JAMDAT_MSK)
1497
1498#define TX_JAM_LEN_DEF 0x03
1499#define TX_JAM_IPG_DEF 0x0b
1500#define TX_IPG_JAM_DEF 0x1c
1501
1502/* GM_SERIAL_MODE 16 bit r/w Serial Mode Register */
1503#define GM_SMOD_DATABL_MSK (0x1f<<11) /* Bit 15..11: Data Blinder (r/o) */
1504#define GM_SMOD_LIMIT_4 (1<<10) /* Bit 10: 4 consecutive Tx trials */
1505#define GM_SMOD_VLAN_ENA (1<<9) /* Bit 9: Enable VLAN (Max. Frame Len) */
1506#define GM_SMOD_JUMBO_ENA (1<<8) /* Bit 8: Enable Jumbo (Max. Frame Len) */
1507 /* Bit 7..5: reserved */
1508#define GM_SMOD_IPG_MSK 0x1f /* Bit 4..0: Inter-Packet Gap (IPG) */
1509
1510#define DATA_BLIND_VAL(x) (SHIFT11(x) & GM_SMOD_DATABL_MSK)
1511#define DATA_BLIND_DEF 0x04
1512
1513#define IPG_DATA_VAL(x) (x & GM_SMOD_IPG_MSK)
1514#define IPG_DATA_DEF 0x1e
1515
1516/* GM_SMI_CTRL 16 bit r/w SMI Control Register */
1517#define GM_SMI_CT_PHY_A_MSK (0x1f<<11) /* Bit 15..11: PHY Device Address */
1518#define GM_SMI_CT_REG_A_MSK (0x1f<<6) /* Bit 10.. 6: PHY Register Address */
1519#define GM_SMI_CT_OP_RD (1<<5) /* Bit 5: OpCode Read (0=Write)*/
1520#define GM_SMI_CT_RD_VAL (1<<4) /* Bit 4: Read Valid (Read completed) */
1521#define GM_SMI_CT_BUSY (1<<3) /* Bit 3: Busy (Operation in progress) */
1522 /* Bit 2..0: reserved */
1523
1524#define GM_SMI_CT_PHY_AD(x) (SHIFT11(x) & GM_SMI_CT_PHY_A_MSK)
1525#define GM_SMI_CT_REG_AD(x) (SHIFT6(x) & GM_SMI_CT_REG_A_MSK)
1526
1527 /* GM_PHY_ADDR 16 bit r/w GPHY Address Register */
1528 /* Bit 15..6: reserved */
1529#define GM_PAR_MIB_CLR (1<<5) /* Bit 5: Set MIB Clear Counter Mode */
1530#define GM_PAR_MIB_TST (1<<4) /* Bit 4: MIB Load Counter (Test Mode) */
1531 /* Bit 3..0: reserved */
1532
1533/* Receive Frame Status Encoding */
1534#define GMR_FS_LEN (0xffffUL<<16) /* Bit 31..16: Rx Frame Length */
1535 /* Bit 15..14: reserved */
1536#define GMR_FS_VLAN (1L<<13) /* Bit 13: VLAN Packet */
1537#define GMR_FS_JABBER (1L<<12) /* Bit 12: Jabber Packet */
1538#define GMR_FS_UN_SIZE (1L<<11) /* Bit 11: Undersize Packet */
1539#define GMR_FS_MC (1L<<10) /* Bit 10: Multicast Packet */
1540#define GMR_FS_BC (1L<<9) /* Bit 9: Broadcast Packet */
1541#define GMR_FS_RX_OK (1L<<8) /* Bit 8: Receive OK (Good Packet) */
1542#define GMR_FS_GOOD_FC (1L<<7) /* Bit 7: Good Flow-Control Packet */
1543#define GMR_FS_BAD_FC (1L<<6) /* Bit 6: Bad Flow-Control Packet */
1544#define GMR_FS_MII_ERR (1L<<5) /* Bit 5: MII Error */
1545#define GMR_FS_LONG_ERR (1L<<4) /* Bit 4: Too Long Packet */
1546#define GMR_FS_FRAGMENT (1L<<3) /* Bit 3: Fragment */
1547 /* Bit 2: reserved */
1548#define GMR_FS_CRC_ERR (1L<<1) /* Bit 1: CRC Error */
1549#define GMR_FS_RX_FF_OV (1L<<0) /* Bit 0: Rx FIFO Overflow */
1550
1551/*
1552 * GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR)
1553 */
1554#define GMR_FS_ANY_ERR (GMR_FS_CRC_ERR | \
1555 GMR_FS_LONG_ERR | \
1556 GMR_FS_MII_ERR | \
1557 GMR_FS_BAD_FC | \
1558 GMR_FS_GOOD_FC | \
1559 GMR_FS_JABBER)
1560
1561/* Rx GMAC FIFO Flush Mask (default) */
1562#define RX_FF_FL_DEF_MSK (GMR_FS_CRC_ERR | \
1563 GMR_FS_RX_FF_OV | \
1564 GMR_FS_MII_ERR | \
1565 GMR_FS_BAD_FC | \
1566 GMR_FS_GOOD_FC | \
1567 GMR_FS_UN_SIZE | \
1568 GMR_FS_JABBER)
1569
1570/* typedefs *******************************************************************/
1571
1572
1573/* function prototypes ********************************************************/
1574
1575#ifdef __cplusplus
1576}
1577#endif /* __cplusplus */
1578
1579#endif /* __INC_XMAC_H */
diff --git a/drivers/net/sk98lin/skaddr.c b/drivers/net/sk98lin/skaddr.c
new file mode 100644
index 000000000000..a7e25edc7fc4
--- /dev/null
+++ b/drivers/net/sk98lin/skaddr.c
@@ -0,0 +1,1773 @@
1/******************************************************************************
2 *
3 * Name: skaddr.c
4 * Project: Gigabit Ethernet Adapters, ADDR-Module
5 * Version: $Revision: 1.52 $
6 * Date: $Date: 2003/06/02 13:46:15 $
7 * Purpose: Manage Addresses (Multicast and Unicast) and Promiscuous Mode.
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * This module is intended to manage multicast addresses, address override,
30 * and promiscuous mode on GEnesis and Yukon adapters.
31 *
32 * Address Layout:
33 * port address: physical MAC address
34 * 1st exact match: logical MAC address (GEnesis only)
35 * 2nd exact match: RLMT multicast (GEnesis only)
36 * exact match 3-13: OS-specific multicasts (GEnesis only)
37 *
38 * Include File Hierarchy:
39 *
40 * "skdrv1st.h"
41 * "skdrv2nd.h"
42 *
43 ******************************************************************************/
44
45#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
46static const char SysKonnectFileId[] =
47 "@(#) $Id: skaddr.c,v 1.52 2003/06/02 13:46:15 tschilli Exp $ (C) Marvell.";
48#endif /* DEBUG ||!LINT || !SK_SLIM */
49
50#define __SKADDR_C
51
52#ifdef __cplusplus
53extern "C" {
54#endif /* cplusplus */
55
56#include "h/skdrv1st.h"
57#include "h/skdrv2nd.h"
58
59/* defines ********************************************************************/
60
61
62#define XMAC_POLY 0xEDB88320UL /* CRC32-Poly - XMAC: Little Endian */
63#define GMAC_POLY 0x04C11DB7L /* CRC16-Poly - GMAC: Little Endian */
64#define HASH_BITS 6 /* #bits in hash */
65#define SK_MC_BIT 0x01
66
67/* Error numbers and messages. */
68
69#define SKERR_ADDR_E001 (SK_ERRBASE_ADDR + 0)
70#define SKERR_ADDR_E001MSG "Bad Flags."
71#define SKERR_ADDR_E002 (SKERR_ADDR_E001 + 1)
72#define SKERR_ADDR_E002MSG "New Error."
73
74/* typedefs *******************************************************************/
75
76/* None. */
77
78/* global variables ***********************************************************/
79
80/* 64-bit hash values with all bits set. */
81
82static const SK_U16 OnesHash[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
83
84/* local variables ************************************************************/
85
86#ifdef DEBUG
87static int Next0[SK_MAX_MACS] = {0};
88#endif /* DEBUG */
89
90/* functions ******************************************************************/
91
92/******************************************************************************
93 *
94 * SkAddrInit - initialize data, set state to init
95 *
96 * Description:
97 *
98 * SK_INIT_DATA
99 * ============
100 *
101 * This routine clears the multicast tables and resets promiscuous mode.
102 * Some entries are reserved for the "logical MAC address", the
103 * SK-RLMT multicast address, and the BPDU multicast address.
104 *
105 *
106 * SK_INIT_IO
107 * ==========
108 *
109 * All permanent MAC addresses are read from EPROM.
110 * If the current MAC addresses are not already set in software,
111 * they are set to the values of the permanent addresses.
112 * The current addresses are written to the corresponding MAC.
113 *
114 *
115 * SK_INIT_RUN
116 * ===========
117 *
118 * Nothing.
119 *
120 * Context:
121 * init, pageable
122 *
123 * Returns:
124 * SK_ADDR_SUCCESS
125 */
126int SkAddrInit(
127SK_AC *pAC, /* the adapter context */
128SK_IOC IoC, /* I/O context */
129int Level) /* initialization level */
130{
131 int j;
132 SK_U32 i;
133 SK_U8 *InAddr;
134 SK_U16 *OutAddr;
135 SK_ADDR_PORT *pAPort;
136
137 switch (Level) {
138 case SK_INIT_DATA:
139 SK_MEMSET((char *) &pAC->Addr, (SK_U8) 0,
140 (SK_U16) sizeof(SK_ADDR));
141
142 for (i = 0; i < SK_MAX_MACS; i++) {
143 pAPort = &pAC->Addr.Port[i];
144 pAPort->PromMode = SK_PROM_MODE_NONE;
145
146 pAPort->FirstExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
147 pAPort->FirstExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
148 pAPort->NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
149 pAPort->NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
150 }
151#ifdef xDEBUG
152 for (i = 0; i < SK_MAX_MACS; i++) {
153 if (pAC->Addr.Port[i].NextExactMatchRlmt <
154 SK_ADDR_FIRST_MATCH_RLMT) {
155 Next0[i] |= 4;
156 }
157 }
158#endif /* DEBUG */
159 /* pAC->Addr.InitDone = SK_INIT_DATA; */
160 break;
161
162 case SK_INIT_IO:
163#ifndef SK_NO_RLMT
164 for (i = 0; i < SK_MAX_NETS; i++) {
165 pAC->Addr.Net[i].ActivePort = pAC->Rlmt.Net[i].ActivePort;
166 }
167#endif /* !SK_NO_RLMT */
168#ifdef xDEBUG
169 for (i = 0; i < SK_MAX_MACS; i++) {
170 if (pAC->Addr.Port[i].NextExactMatchRlmt <
171 SK_ADDR_FIRST_MATCH_RLMT) {
172 Next0[i] |= 8;
173 }
174 }
175#endif /* DEBUG */
176
177 /* Read permanent logical MAC address from Control Register File. */
178 for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
179 InAddr = (SK_U8 *) &pAC->Addr.Net[0].PermanentMacAddress.a[j];
180 SK_IN8(IoC, B2_MAC_1 + j, InAddr);
181 }
182
183 if (!pAC->Addr.Net[0].CurrentMacAddressSet) {
184 /* Set the current logical MAC address to the permanent one. */
185 pAC->Addr.Net[0].CurrentMacAddress =
186 pAC->Addr.Net[0].PermanentMacAddress;
187 pAC->Addr.Net[0].CurrentMacAddressSet = SK_TRUE;
188 }
189
190 /* Set the current logical MAC address. */
191 pAC->Addr.Port[pAC->Addr.Net[0].ActivePort].Exact[0] =
192 pAC->Addr.Net[0].CurrentMacAddress;
193#if SK_MAX_NETS > 1
194 /* Set logical MAC address for net 2 to (log | 3). */
195 if (!pAC->Addr.Net[1].CurrentMacAddressSet) {
196 pAC->Addr.Net[1].PermanentMacAddress =
197 pAC->Addr.Net[0].PermanentMacAddress;
198 pAC->Addr.Net[1].PermanentMacAddress.a[5] |= 3;
199 /* Set the current logical MAC address to the permanent one. */
200 pAC->Addr.Net[1].CurrentMacAddress =
201 pAC->Addr.Net[1].PermanentMacAddress;
202 pAC->Addr.Net[1].CurrentMacAddressSet = SK_TRUE;
203 }
204#endif /* SK_MAX_NETS > 1 */
205
206#ifdef DEBUG
207 for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
208 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
209 ("Permanent MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n",
210 i,
211 pAC->Addr.Net[i].PermanentMacAddress.a[0],
212 pAC->Addr.Net[i].PermanentMacAddress.a[1],
213 pAC->Addr.Net[i].PermanentMacAddress.a[2],
214 pAC->Addr.Net[i].PermanentMacAddress.a[3],
215 pAC->Addr.Net[i].PermanentMacAddress.a[4],
216 pAC->Addr.Net[i].PermanentMacAddress.a[5]))
217
218 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
219 ("Logical MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n",
220 i,
221 pAC->Addr.Net[i].CurrentMacAddress.a[0],
222 pAC->Addr.Net[i].CurrentMacAddress.a[1],
223 pAC->Addr.Net[i].CurrentMacAddress.a[2],
224 pAC->Addr.Net[i].CurrentMacAddress.a[3],
225 pAC->Addr.Net[i].CurrentMacAddress.a[4],
226 pAC->Addr.Net[i].CurrentMacAddress.a[5]))
227 }
228#endif /* DEBUG */
229
230 for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
231 pAPort = &pAC->Addr.Port[i];
232
233 /* Read permanent port addresses from Control Register File. */
234 for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
235 InAddr = (SK_U8 *) &pAPort->PermanentMacAddress.a[j];
236 SK_IN8(IoC, B2_MAC_2 + 8 * i + j, InAddr);
237 }
238
239 if (!pAPort->CurrentMacAddressSet) {
240 /*
241 * Set the current and previous physical MAC address
242 * of this port to its permanent MAC address.
243 */
244 pAPort->CurrentMacAddress = pAPort->PermanentMacAddress;
245 pAPort->PreviousMacAddress = pAPort->PermanentMacAddress;
246 pAPort->CurrentMacAddressSet = SK_TRUE;
247 }
248
249 /* Set port's current physical MAC address. */
250 OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
251#ifdef GENESIS
252 if (pAC->GIni.GIGenesis) {
253 XM_OUTADDR(IoC, i, XM_SA, OutAddr);
254 }
255#endif /* GENESIS */
256#ifdef YUKON
257 if (!pAC->GIni.GIGenesis) {
258 GM_OUTADDR(IoC, i, GM_SRC_ADDR_1L, OutAddr);
259 }
260#endif /* YUKON */
261#ifdef DEBUG
262 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
263 ("SkAddrInit: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
264 pAPort->PermanentMacAddress.a[0],
265 pAPort->PermanentMacAddress.a[1],
266 pAPort->PermanentMacAddress.a[2],
267 pAPort->PermanentMacAddress.a[3],
268 pAPort->PermanentMacAddress.a[4],
269 pAPort->PermanentMacAddress.a[5]))
270
271 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
272 ("SkAddrInit: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
273 pAPort->CurrentMacAddress.a[0],
274 pAPort->CurrentMacAddress.a[1],
275 pAPort->CurrentMacAddress.a[2],
276 pAPort->CurrentMacAddress.a[3],
277 pAPort->CurrentMacAddress.a[4],
278 pAPort->CurrentMacAddress.a[5]))
279#endif /* DEBUG */
280 }
281 /* pAC->Addr.InitDone = SK_INIT_IO; */
282 break;
283
284 case SK_INIT_RUN:
285#ifdef xDEBUG
286 for (i = 0; i < SK_MAX_MACS; i++) {
287 if (pAC->Addr.Port[i].NextExactMatchRlmt <
288 SK_ADDR_FIRST_MATCH_RLMT) {
289 Next0[i] |= 16;
290 }
291 }
292#endif /* DEBUG */
293
294 /* pAC->Addr.InitDone = SK_INIT_RUN; */
295 break;
296
297 default: /* error */
298 break;
299 }
300
301 return (SK_ADDR_SUCCESS);
302
303} /* SkAddrInit */
304
305#ifndef SK_SLIM
306
307/******************************************************************************
308 *
309 * SkAddrMcClear - clear the multicast table
310 *
311 * Description:
312 * This routine clears the multicast table.
313 *
314 * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
315 * immediately.
316 *
317 * It calls either SkAddrXmacMcClear or SkAddrGmacMcClear, according
318 * to the adapter in use. The real work is done there.
319 *
320 * Context:
321 * runtime, pageable
322 * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
323 * may be called after SK_INIT_IO without limitation
324 *
325 * Returns:
326 * SK_ADDR_SUCCESS
327 * SK_ADDR_ILLEGAL_PORT
328 */
329int SkAddrMcClear(
330SK_AC *pAC, /* adapter context */
331SK_IOC IoC, /* I/O context */
332SK_U32 PortNumber, /* Index of affected port */
333int Flags) /* permanent/non-perm, sw-only */
334{
335 int ReturnCode;
336
337 if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
338 return (SK_ADDR_ILLEGAL_PORT);
339 }
340
341 if (pAC->GIni.GIGenesis) {
342 ReturnCode = SkAddrXmacMcClear(pAC, IoC, PortNumber, Flags);
343 }
344 else {
345 ReturnCode = SkAddrGmacMcClear(pAC, IoC, PortNumber, Flags);
346 }
347
348 return (ReturnCode);
349
350} /* SkAddrMcClear */
351
352#endif /* !SK_SLIM */
353
354#ifndef SK_SLIM
355
356/******************************************************************************
357 *
358 * SkAddrXmacMcClear - clear the multicast table
359 *
360 * Description:
361 * This routine clears the multicast table
362 * (either entry 2 or entries 3-16 and InexactFilter) of the given port.
363 * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
364 * immediately.
365 *
366 * Context:
367 * runtime, pageable
368 * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
369 * may be called after SK_INIT_IO without limitation
370 *
371 * Returns:
372 * SK_ADDR_SUCCESS
373 * SK_ADDR_ILLEGAL_PORT
374 */
375int SkAddrXmacMcClear(
376SK_AC *pAC, /* adapter context */
377SK_IOC IoC, /* I/O context */
378SK_U32 PortNumber, /* Index of affected port */
379int Flags) /* permanent/non-perm, sw-only */
380{
381 int i;
382
383 if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */
384
385 /* Clear RLMT multicast addresses. */
386 pAC->Addr.Port[PortNumber].NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
387 }
388 else { /* not permanent => DRV */
389
390 /* Clear InexactFilter */
391 for (i = 0; i < 8; i++) {
392 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
393 }
394
395 /* Clear DRV multicast addresses. */
396
397 pAC->Addr.Port[PortNumber].NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
398 }
399
400 if (!(Flags & SK_MC_SW_ONLY)) {
401 (void) SkAddrXmacMcUpdate(pAC, IoC, PortNumber);
402 }
403
404 return (SK_ADDR_SUCCESS);
405
406} /* SkAddrXmacMcClear */
407
408#endif /* !SK_SLIM */
409
410#ifndef SK_SLIM
411
412/******************************************************************************
413 *
414 * SkAddrGmacMcClear - clear the multicast table
415 *
416 * Description:
417 * This routine clears the multicast hashing table (InexactFilter)
418 * (either the RLMT or the driver bits) of the given port.
419 *
420 * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
421 * immediately.
422 *
423 * Context:
424 * runtime, pageable
425 * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
426 * may be called after SK_INIT_IO without limitation
427 *
428 * Returns:
429 * SK_ADDR_SUCCESS
430 * SK_ADDR_ILLEGAL_PORT
431 */
432int SkAddrGmacMcClear(
433SK_AC *pAC, /* adapter context */
434SK_IOC IoC, /* I/O context */
435SK_U32 PortNumber, /* Index of affected port */
436int Flags) /* permanent/non-perm, sw-only */
437{
438 int i;
439
440#ifdef DEBUG
441 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
442 ("GMAC InexactFilter (not cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n",
443 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0],
444 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1],
445 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2],
446 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3],
447 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4],
448 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5],
449 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6],
450 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]))
451#endif /* DEBUG */
452
453 /* Clear InexactFilter */
454 for (i = 0; i < 8; i++) {
455 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
456 }
457
458 if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */
459
460 /* Copy DRV bits to InexactFilter. */
461 for (i = 0; i < 8; i++) {
462 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
463 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i];
464
465 /* Clear InexactRlmtFilter. */
466 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i] = 0;
467
468 }
469 }
470 else { /* not permanent => DRV */
471
472 /* Copy RLMT bits to InexactFilter. */
473 for (i = 0; i < 8; i++) {
474 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
475 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i];
476
477 /* Clear InexactDrvFilter. */
478 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i] = 0;
479 }
480 }
481
482#ifdef DEBUG
483 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
484 ("GMAC InexactFilter (cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n",
485 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0],
486 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1],
487 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2],
488 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3],
489 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4],
490 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5],
491 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6],
492 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]))
493#endif /* DEBUG */
494
495 if (!(Flags & SK_MC_SW_ONLY)) {
496 (void) SkAddrGmacMcUpdate(pAC, IoC, PortNumber);
497 }
498
499 return (SK_ADDR_SUCCESS);
500
501} /* SkAddrGmacMcClear */
502
503#ifndef SK_ADDR_CHEAT
504
505/******************************************************************************
506 *
507 * SkXmacMcHash - hash multicast address
508 *
509 * Description:
510 * This routine computes the hash value for a multicast address.
511 * A CRC32 algorithm is used.
512 *
513 * Notes:
514 * The code was adapted from the XaQti data sheet.
515 *
516 * Context:
517 * runtime, pageable
518 *
519 * Returns:
520 * Hash value of multicast address.
521 */
522SK_U32 SkXmacMcHash(
523unsigned char *pMc) /* Multicast address */
524{
525 SK_U32 Idx;
526 SK_U32 Bit;
527 SK_U32 Data;
528 SK_U32 Crc;
529
530 Crc = 0xFFFFFFFFUL;
531 for (Idx = 0; Idx < SK_MAC_ADDR_LEN; Idx++) {
532 Data = *pMc++;
533 for (Bit = 0; Bit < 8; Bit++, Data >>= 1) {
534 Crc = (Crc >> 1) ^ (((Crc ^ Data) & 1) ? XMAC_POLY : 0);
535 }
536 }
537
538 return (Crc & ((1 << HASH_BITS) - 1));
539
540} /* SkXmacMcHash */
541
542
543/******************************************************************************
544 *
545 * SkGmacMcHash - hash multicast address
546 *
547 * Description:
548 * This routine computes the hash value for a multicast address.
549 * A CRC16 algorithm is used.
550 *
551 * Notes:
552 *
553 *
554 * Context:
555 * runtime, pageable
556 *
557 * Returns:
558 * Hash value of multicast address.
559 */
560SK_U32 SkGmacMcHash(
561unsigned char *pMc) /* Multicast address */
562{
563 SK_U32 Data;
564 SK_U32 TmpData;
565 SK_U32 Crc;
566 int Byte;
567 int Bit;
568
569 Crc = 0xFFFFFFFFUL;
570 for (Byte = 0; Byte < 6; Byte++) {
571 /* Get next byte. */
572 Data = (SK_U32) pMc[Byte];
573
574 /* Change bit order in byte. */
575 TmpData = Data;
576 for (Bit = 0; Bit < 8; Bit++) {
577 if (TmpData & 1L) {
578 Data |= 1L << (7 - Bit);
579 }
580 else {
581 Data &= ~(1L << (7 - Bit));
582 }
583 TmpData >>= 1;
584 }
585
586 Crc ^= (Data << 24);
587 for (Bit = 0; Bit < 8; Bit++) {
588 if (Crc & 0x80000000) {
589 Crc = (Crc << 1) ^ GMAC_POLY;
590 }
591 else {
592 Crc <<= 1;
593 }
594 }
595 }
596
597 return (Crc & ((1 << HASH_BITS) - 1));
598
599} /* SkGmacMcHash */
600
601#endif /* !SK_ADDR_CHEAT */
602
603/******************************************************************************
604 *
605 * SkAddrMcAdd - add a multicast address to a port
606 *
607 * Description:
608 * This routine enables reception for a given address on the given port.
609 *
610 * It calls either SkAddrXmacMcAdd or SkAddrGmacMcAdd, according to the
611 * adapter in use. The real work is done there.
612 *
613 * Notes:
614 * The return code is only valid for SK_PROM_MODE_NONE.
615 *
616 * Context:
617 * runtime, pageable
618 * may be called after SK_INIT_DATA
619 *
620 * Returns:
621 * SK_MC_FILTERING_EXACT
622 * SK_MC_FILTERING_INEXACT
623 * SK_MC_ILLEGAL_ADDRESS
624 * SK_MC_ILLEGAL_PORT
625 * SK_MC_RLMT_OVERFLOW
626 */
627int SkAddrMcAdd(
628SK_AC *pAC, /* adapter context */
629SK_IOC IoC, /* I/O context */
630SK_U32 PortNumber, /* Port Number */
631SK_MAC_ADDR *pMc, /* multicast address to be added */
632int Flags) /* permanent/non-permanent */
633{
634 int ReturnCode;
635
636 if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
637 return (SK_ADDR_ILLEGAL_PORT);
638 }
639
640 if (pAC->GIni.GIGenesis) {
641 ReturnCode = SkAddrXmacMcAdd(pAC, IoC, PortNumber, pMc, Flags);
642 }
643 else {
644 ReturnCode = SkAddrGmacMcAdd(pAC, IoC, PortNumber, pMc, Flags);
645 }
646
647 return (ReturnCode);
648
649} /* SkAddrMcAdd */
650
651
652/******************************************************************************
653 *
654 * SkAddrXmacMcAdd - add a multicast address to a port
655 *
656 * Description:
657 * This routine enables reception for a given address on the given port.
658 *
659 * Notes:
660 * The return code is only valid for SK_PROM_MODE_NONE.
661 *
662 * The multicast bit is only checked if there are no free exact match
663 * entries.
664 *
665 * Context:
666 * runtime, pageable
667 * may be called after SK_INIT_DATA
668 *
669 * Returns:
670 * SK_MC_FILTERING_EXACT
671 * SK_MC_FILTERING_INEXACT
672 * SK_MC_ILLEGAL_ADDRESS
673 * SK_MC_RLMT_OVERFLOW
674 */
675int SkAddrXmacMcAdd(
676SK_AC *pAC, /* adapter context */
677SK_IOC IoC, /* I/O context */
678SK_U32 PortNumber, /* Port Number */
679SK_MAC_ADDR *pMc, /* multicast address to be added */
680int Flags) /* permanent/non-permanent */
681{
682 int i;
683 SK_U8 Inexact;
684#ifndef SK_ADDR_CHEAT
685 SK_U32 HashBit;
686#endif /* !defined(SK_ADDR_CHEAT) */
687
688 if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */
689#ifdef xDEBUG
690 if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt <
691 SK_ADDR_FIRST_MATCH_RLMT) {
692 Next0[PortNumber] |= 1;
693 return (SK_MC_RLMT_OVERFLOW);
694 }
695#endif /* DEBUG */
696
697 if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt >
698 SK_ADDR_LAST_MATCH_RLMT) {
699 return (SK_MC_RLMT_OVERFLOW);
700 }
701
702 /* Set a RLMT multicast address. */
703
704 pAC->Addr.Port[PortNumber].Exact[
705 pAC->Addr.Port[PortNumber].NextExactMatchRlmt++] = *pMc;
706
707 return (SK_MC_FILTERING_EXACT);
708 }
709
710#ifdef xDEBUG
711 if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <
712 SK_ADDR_FIRST_MATCH_DRV) {
713 Next0[PortNumber] |= 2;
714 return (SK_MC_RLMT_OVERFLOW);
715 }
716#endif /* DEBUG */
717
718 if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {
719
720 /* Set exact match entry. */
721 pAC->Addr.Port[PortNumber].Exact[
722 pAC->Addr.Port[PortNumber].NextExactMatchDrv++] = *pMc;
723
724 /* Clear InexactFilter */
725 for (i = 0; i < 8; i++) {
726 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
727 }
728 }
729 else {
730 if (!(pMc->a[0] & SK_MC_BIT)) {
731 /* Hashing only possible with multicast addresses */
732 return (SK_MC_ILLEGAL_ADDRESS);
733 }
734#ifndef SK_ADDR_CHEAT
735 /* Compute hash value of address. */
736 HashBit = 63 - SkXmacMcHash(&pMc->a[0]);
737
738 /* Add bit to InexactFilter. */
739 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[HashBit / 8] |=
740 1 << (HashBit % 8);
741#else /* SK_ADDR_CHEAT */
742 /* Set all bits in InexactFilter. */
743 for (i = 0; i < 8; i++) {
744 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF;
745 }
746#endif /* SK_ADDR_CHEAT */
747 }
748
749 for (Inexact = 0, i = 0; i < 8; i++) {
750 Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
751 }
752
753 if (Inexact == 0 && pAC->Addr.Port[PortNumber].PromMode == 0) {
754 return (SK_MC_FILTERING_EXACT);
755 }
756 else {
757 return (SK_MC_FILTERING_INEXACT);
758 }
759
760} /* SkAddrXmacMcAdd */
761
762
763/******************************************************************************
764 *
765 * SkAddrGmacMcAdd - add a multicast address to a port
766 *
767 * Description:
768 * This routine enables reception for a given address on the given port.
769 *
770 * Notes:
771 * The return code is only valid for SK_PROM_MODE_NONE.
772 *
773 * Context:
774 * runtime, pageable
775 * may be called after SK_INIT_DATA
776 *
777 * Returns:
778 * SK_MC_FILTERING_INEXACT
779 * SK_MC_ILLEGAL_ADDRESS
780 */
781int SkAddrGmacMcAdd(
782SK_AC *pAC, /* adapter context */
783SK_IOC IoC, /* I/O context */
784SK_U32 PortNumber, /* Port Number */
785SK_MAC_ADDR *pMc, /* multicast address to be added */
786int Flags) /* permanent/non-permanent */
787{
788 int i;
789#ifndef SK_ADDR_CHEAT
790 SK_U32 HashBit;
791#endif /* !defined(SK_ADDR_CHEAT) */
792
793 if (!(pMc->a[0] & SK_MC_BIT)) {
794 /* Hashing only possible with multicast addresses */
795 return (SK_MC_ILLEGAL_ADDRESS);
796 }
797
798#ifndef SK_ADDR_CHEAT
799
800 /* Compute hash value of address. */
801 HashBit = SkGmacMcHash(&pMc->a[0]);
802
803 if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */
804
805 /* Add bit to InexactRlmtFilter. */
806 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[HashBit / 8] |=
807 1 << (HashBit % 8);
808
809 /* Copy bit to InexactFilter. */
810 for (i = 0; i < 8; i++) {
811 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
812 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i];
813 }
814#ifdef DEBUG
815 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
816 ("GMAC InexactRlmtFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n",
817 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[0],
818 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[1],
819 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[2],
820 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[3],
821 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[4],
822 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[5],
823 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[6],
824 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[7]))
825#endif /* DEBUG */
826 }
827 else { /* not permanent => DRV */
828
829 /* Add bit to InexactDrvFilter. */
830 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[HashBit / 8] |=
831 1 << (HashBit % 8);
832
833 /* Copy bit to InexactFilter. */
834 for (i = 0; i < 8; i++) {
835 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
836 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i];
837 }
838#ifdef DEBUG
839 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
840 ("GMAC InexactDrvFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n",
841 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[0],
842 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[1],
843 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[2],
844 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[3],
845 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[4],
846 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[5],
847 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[6],
848 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[7]))
849#endif /* DEBUG */
850 }
851
852#else /* SK_ADDR_CHEAT */
853
854 /* Set all bits in InexactFilter. */
855 for (i = 0; i < 8; i++) {
856 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF;
857 }
858#endif /* SK_ADDR_CHEAT */
859
860 return (SK_MC_FILTERING_INEXACT);
861
862} /* SkAddrGmacMcAdd */
863
864#endif /* !SK_SLIM */
865
866/******************************************************************************
867 *
868 * SkAddrMcUpdate - update the HW MC address table and set the MAC address
869 *
870 * Description:
871 * This routine enables reception of the addresses contained in a local
872 * table for a given port.
873 * It also programs the port's current physical MAC address.
874 *
875 * It calls either SkAddrXmacMcUpdate or SkAddrGmacMcUpdate, according
876 * to the adapter in use. The real work is done there.
877 *
878 * Notes:
879 * The return code is only valid for SK_PROM_MODE_NONE.
880 *
881 * Context:
882 * runtime, pageable
883 * may be called after SK_INIT_IO
884 *
885 * Returns:
886 * SK_MC_FILTERING_EXACT
887 * SK_MC_FILTERING_INEXACT
888 * SK_ADDR_ILLEGAL_PORT
889 */
890int SkAddrMcUpdate(
891SK_AC *pAC, /* adapter context */
892SK_IOC IoC, /* I/O context */
893SK_U32 PortNumber) /* Port Number */
894{
895 int ReturnCode = 0;
896#if (!defined(SK_SLIM) || defined(DEBUG))
897 if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
898 return (SK_ADDR_ILLEGAL_PORT);
899 }
900#endif /* !SK_SLIM || DEBUG */
901
902#ifdef GENESIS
903 if (pAC->GIni.GIGenesis) {
904 ReturnCode = SkAddrXmacMcUpdate(pAC, IoC, PortNumber);
905 }
906#endif /* GENESIS */
907#ifdef YUKON
908 if (!pAC->GIni.GIGenesis) {
909 ReturnCode = SkAddrGmacMcUpdate(pAC, IoC, PortNumber);
910 }
911#endif /* YUKON */
912 return (ReturnCode);
913
914} /* SkAddrMcUpdate */
915
916
917#ifdef GENESIS
918
919/******************************************************************************
920 *
921 * SkAddrXmacMcUpdate - update the HW MC address table and set the MAC address
922 *
923 * Description:
924 * This routine enables reception of the addresses contained in a local
925 * table for a given port.
926 * It also programs the port's current physical MAC address.
927 *
928 * Notes:
929 * The return code is only valid for SK_PROM_MODE_NONE.
930 *
931 * Context:
932 * runtime, pageable
933 * may be called after SK_INIT_IO
934 *
935 * Returns:
936 * SK_MC_FILTERING_EXACT
937 * SK_MC_FILTERING_INEXACT
938 * SK_ADDR_ILLEGAL_PORT
939 */
940int SkAddrXmacMcUpdate(
941SK_AC *pAC, /* adapter context */
942SK_IOC IoC, /* I/O context */
943SK_U32 PortNumber) /* Port Number */
944{
945 SK_U32 i;
946 SK_U8 Inexact;
947 SK_U16 *OutAddr;
948 SK_ADDR_PORT *pAPort;
949
950 SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
951 ("SkAddrXmacMcUpdate on Port %u.\n", PortNumber))
952
953 pAPort = &pAC->Addr.Port[PortNumber];
954
955#ifdef DEBUG
956 SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
957 ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]))
958#endif /* DEBUG */
959
960 /* Start with 0 to also program the logical MAC address. */
961 for (i = 0; i < pAPort->NextExactMatchRlmt; i++) {
962 /* Set exact match address i on XMAC */
963 OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0];
964 XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr);
965 }
966
967 /* Clear other permanent exact match addresses on XMAC */
968 if (pAPort->NextExactMatchRlmt <= SK_ADDR_LAST_MATCH_RLMT) {
969
970 SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchRlmt,
971 SK_ADDR_LAST_MATCH_RLMT);
972 }
973
974 for (i = pAPort->FirstExactMatchDrv; i < pAPort->NextExactMatchDrv; i++) {
975 OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0];
976 XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr);
977 }
978
979 /* Clear other non-permanent exact match addresses on XMAC */
980 if (pAPort->NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {
981
982 SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchDrv,
983 SK_ADDR_LAST_MATCH_DRV);
984 }
985
986 for (Inexact = 0, i = 0; i < 8; i++) {
987 Inexact |= pAPort->InexactFilter.Bytes[i];
988 }
989
990 if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) {
991
992 /* Set all bits in 64-bit hash register. */
993 XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash);
994
995 /* Enable Hashing */
996 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
997 }
998 else if (Inexact != 0) {
999
1000 /* Set 64-bit hash register to InexactFilter. */
1001 XM_OUTHASH(IoC, PortNumber, XM_HSM, &pAPort->InexactFilter.Bytes[0]);
1002
1003 /* Enable Hashing */
1004 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1005 }
1006 else {
1007 /* Disable Hashing */
1008 SkMacHashing(pAC, IoC, (int) PortNumber, SK_FALSE);
1009 }
1010
1011 if (pAPort->PromMode != SK_PROM_MODE_NONE) {
1012 (void) SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
1013 }
1014
1015 /* Set port's current physical MAC address. */
1016 OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
1017
1018 XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr);
1019
1020#ifdef xDEBUG
1021 for (i = 0; i < pAPort->NextExactMatchRlmt; i++) {
1022 SK_U8 InAddr8[6];
1023 SK_U16 *InAddr;
1024
1025 /* Get exact match address i from port PortNumber. */
1026 InAddr = (SK_U16 *) &InAddr8[0];
1027
1028 XM_INADDR(IoC, PortNumber, XM_EXM(i), InAddr);
1029
1030 SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
1031 ("SkAddrXmacMcUpdate: MC address %d on Port %u: ",
1032 "%02x %02x %02x %02x %02x %02x -- %02x %02x %02x %02x %02x %02x\n",
1033 i,
1034 PortNumber,
1035 InAddr8[0],
1036 InAddr8[1],
1037 InAddr8[2],
1038 InAddr8[3],
1039 InAddr8[4],
1040 InAddr8[5],
1041 pAPort->Exact[i].a[0],
1042 pAPort->Exact[i].a[1],
1043 pAPort->Exact[i].a[2],
1044 pAPort->Exact[i].a[3],
1045 pAPort->Exact[i].a[4],
1046 pAPort->Exact[i].a[5]))
1047 }
1048#endif /* DEBUG */
1049
1050 /* Determine return value. */
1051 if (Inexact == 0 && pAPort->PromMode == 0) {
1052 return (SK_MC_FILTERING_EXACT);
1053 }
1054 else {
1055 return (SK_MC_FILTERING_INEXACT);
1056 }
1057
1058} /* SkAddrXmacMcUpdate */
1059
1060#endif /* GENESIS */
1061
1062#ifdef YUKON
1063
1064/******************************************************************************
1065 *
1066 * SkAddrGmacMcUpdate - update the HW MC address table and set the MAC address
1067 *
1068 * Description:
1069 * This routine enables reception of the addresses contained in a local
1070 * table for a given port.
1071 * It also programs the port's current physical MAC address.
1072 *
1073 * Notes:
1074 * The return code is only valid for SK_PROM_MODE_NONE.
1075 *
1076 * Context:
1077 * runtime, pageable
1078 * may be called after SK_INIT_IO
1079 *
1080 * Returns:
1081 * SK_MC_FILTERING_EXACT
1082 * SK_MC_FILTERING_INEXACT
1083 * SK_ADDR_ILLEGAL_PORT
1084 */
1085int SkAddrGmacMcUpdate(
1086SK_AC *pAC, /* adapter context */
1087SK_IOC IoC, /* I/O context */
1088SK_U32 PortNumber) /* Port Number */
1089{
1090#ifndef SK_SLIM
1091 SK_U32 i;
1092 SK_U8 Inexact;
1093#endif /* not SK_SLIM */
1094 SK_U16 *OutAddr;
1095 SK_ADDR_PORT *pAPort;
1096
1097 SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
1098 ("SkAddrGmacMcUpdate on Port %u.\n", PortNumber))
1099
1100 pAPort = &pAC->Addr.Port[PortNumber];
1101
1102#ifdef DEBUG
1103 SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
1104 ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]))
1105#endif /* DEBUG */
1106
1107#ifndef SK_SLIM
1108 for (Inexact = 0, i = 0; i < 8; i++) {
1109 Inexact |= pAPort->InexactFilter.Bytes[i];
1110 }
1111
1112 /* Set 64-bit hash register to InexactFilter. */
1113 GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1,
1114 &pAPort->InexactFilter.Bytes[0]);
1115
1116 if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) {
1117
1118 /* Set all bits in 64-bit hash register. */
1119 GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash);
1120
1121 /* Enable Hashing */
1122 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1123 }
1124 else {
1125 /* Enable Hashing. */
1126 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1127 }
1128
1129 if (pAPort->PromMode != SK_PROM_MODE_NONE) {
1130 (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
1131 }
1132#else /* SK_SLIM */
1133
1134 /* Set all bits in 64-bit hash register. */
1135 GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash);
1136
1137 /* Enable Hashing */
1138 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1139
1140 (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
1141
1142#endif /* SK_SLIM */
1143
1144 /* Set port's current physical MAC address. */
1145 OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
1146 GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr);
1147
1148 /* Set port's current logical MAC address. */
1149 OutAddr = (SK_U16 *) &pAPort->Exact[0].a[0];
1150 GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_2L, OutAddr);
1151
1152#ifdef DEBUG
1153 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
1154 ("SkAddrGmacMcUpdate: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
1155 pAPort->Exact[0].a[0],
1156 pAPort->Exact[0].a[1],
1157 pAPort->Exact[0].a[2],
1158 pAPort->Exact[0].a[3],
1159 pAPort->Exact[0].a[4],
1160 pAPort->Exact[0].a[5]))
1161
1162 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
1163 ("SkAddrGmacMcUpdate: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
1164 pAPort->CurrentMacAddress.a[0],
1165 pAPort->CurrentMacAddress.a[1],
1166 pAPort->CurrentMacAddress.a[2],
1167 pAPort->CurrentMacAddress.a[3],
1168 pAPort->CurrentMacAddress.a[4],
1169 pAPort->CurrentMacAddress.a[5]))
1170#endif /* DEBUG */
1171
1172#ifndef SK_SLIM
1173 /* Determine return value. */
1174 if (Inexact == 0 && pAPort->PromMode == 0) {
1175 return (SK_MC_FILTERING_EXACT);
1176 }
1177 else {
1178 return (SK_MC_FILTERING_INEXACT);
1179 }
1180#else /* SK_SLIM */
1181 return (SK_MC_FILTERING_INEXACT);
1182#endif /* SK_SLIM */
1183
1184} /* SkAddrGmacMcUpdate */
1185
1186#endif /* YUKON */
1187
1188#ifndef SK_NO_MAO
1189
1190/******************************************************************************
1191 *
1192 * SkAddrOverride - override a port's MAC address
1193 *
1194 * Description:
1195 * This routine overrides the MAC address of one port.
1196 *
1197 * Context:
1198 * runtime, pageable
1199 * may be called after SK_INIT_IO
1200 *
1201 * Returns:
1202 * SK_ADDR_SUCCESS if successful.
1203 * SK_ADDR_DUPLICATE_ADDRESS if duplicate MAC address.
1204 * SK_ADDR_MULTICAST_ADDRESS if multicast or broadcast address.
1205 * SK_ADDR_TOO_EARLY if SK_INIT_IO was not executed before.
1206 */
1207int SkAddrOverride(
1208SK_AC *pAC, /* adapter context */
1209SK_IOC IoC, /* I/O context */
1210SK_U32 PortNumber, /* Port Number */
1211SK_MAC_ADDR SK_FAR *pNewAddr, /* new MAC address */
1212int Flags) /* logical/physical MAC address */
1213{
1214#ifndef SK_NO_RLMT
1215 SK_EVPARA Para;
1216#endif /* !SK_NO_RLMT */
1217 SK_U32 NetNumber;
1218 SK_U32 i;
1219 SK_U16 SK_FAR *OutAddr;
1220
1221#ifndef SK_NO_RLMT
1222 NetNumber = pAC->Rlmt.Port[PortNumber].Net->NetNumber;
1223#else
1224 NetNumber = 0;
1225#endif /* SK_NO_RLMT */
1226#if (!defined(SK_SLIM) || defined(DEBUG))
1227 if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
1228 return (SK_ADDR_ILLEGAL_PORT);
1229 }
1230#endif /* !SK_SLIM || DEBUG */
1231 if (pNewAddr != NULL && (pNewAddr->a[0] & SK_MC_BIT) != 0) {
1232 return (SK_ADDR_MULTICAST_ADDRESS);
1233 }
1234
1235 if (!pAC->Addr.Net[NetNumber].CurrentMacAddressSet) {
1236 return (SK_ADDR_TOO_EARLY);
1237 }
1238
1239 if (Flags & SK_ADDR_SET_LOGICAL) { /* Activate logical MAC address. */
1240 /* Parameter *pNewAddr is ignored. */
1241 for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
1242 if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
1243 return (SK_ADDR_TOO_EARLY);
1244 }
1245 }
1246#ifndef SK_NO_RLMT
1247 /* Set PortNumber to number of net's active port. */
1248 PortNumber = pAC->Rlmt.Net[NetNumber].
1249 Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
1250#endif /* !SK_NO_RLMT */
1251 pAC->Addr.Port[PortNumber].Exact[0] =
1252 pAC->Addr.Net[NetNumber].CurrentMacAddress;
1253
1254 /* Write address to first exact match entry of active port. */
1255 (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
1256 }
1257 else if (Flags & SK_ADDR_CLEAR_LOGICAL) {
1258 /* Deactivate logical MAC address. */
1259 /* Parameter *pNewAddr is ignored. */
1260 for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
1261 if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
1262 return (SK_ADDR_TOO_EARLY);
1263 }
1264 }
1265#ifndef SK_NO_RLMT
1266 /* Set PortNumber to number of net's active port. */
1267 PortNumber = pAC->Rlmt.Net[NetNumber].
1268 Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
1269#endif /* !SK_NO_RLMT */
1270 for (i = 0; i < SK_MAC_ADDR_LEN; i++ ) {
1271 pAC->Addr.Port[PortNumber].Exact[0].a[i] = 0;
1272 }
1273
1274 /* Write address to first exact match entry of active port. */
1275 (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
1276 }
1277 else if (Flags & SK_ADDR_PHYSICAL_ADDRESS) { /* Physical MAC address. */
1278 if (SK_ADDR_EQUAL(pNewAddr->a,
1279 pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {
1280 return (SK_ADDR_DUPLICATE_ADDRESS);
1281 }
1282
1283 for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
1284 if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
1285 return (SK_ADDR_TOO_EARLY);
1286 }
1287
1288 if (SK_ADDR_EQUAL(pNewAddr->a,
1289 pAC->Addr.Port[i].CurrentMacAddress.a)) {
1290 if (i == PortNumber) {
1291 return (SK_ADDR_SUCCESS);
1292 }
1293 else {
1294 return (SK_ADDR_DUPLICATE_ADDRESS);
1295 }
1296 }
1297 }
1298
1299 pAC->Addr.Port[PortNumber].PreviousMacAddress =
1300 pAC->Addr.Port[PortNumber].CurrentMacAddress;
1301 pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr;
1302
1303 /* Change port's physical MAC address. */
1304 OutAddr = (SK_U16 SK_FAR *) pNewAddr;
1305#ifdef GENESIS
1306 if (pAC->GIni.GIGenesis) {
1307 XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr);
1308 }
1309#endif /* GENESIS */
1310#ifdef YUKON
1311 if (!pAC->GIni.GIGenesis) {
1312 GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr);
1313 }
1314#endif /* YUKON */
1315
1316#ifndef SK_NO_RLMT
1317 /* Report address change to RLMT. */
1318 Para.Para32[0] = PortNumber;
1319 Para.Para32[0] = -1;
1320 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para);
1321#endif /* !SK_NO_RLMT */
1322 }
1323 else { /* Logical MAC address. */
1324 if (SK_ADDR_EQUAL(pNewAddr->a,
1325 pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {
1326 return (SK_ADDR_SUCCESS);
1327 }
1328
1329 for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
1330 if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
1331 return (SK_ADDR_TOO_EARLY);
1332 }
1333
1334 if (SK_ADDR_EQUAL(pNewAddr->a,
1335 pAC->Addr.Port[i].CurrentMacAddress.a)) {
1336 return (SK_ADDR_DUPLICATE_ADDRESS);
1337 }
1338 }
1339
1340 /*
1341 * In case that the physical and the logical MAC addresses are equal
1342 * we must also change the physical MAC address here.
1343 * In this case we have an adapter which initially was programmed with
1344 * two identical MAC addresses.
1345 */
1346 if (SK_ADDR_EQUAL(pAC->Addr.Port[PortNumber].CurrentMacAddress.a,
1347 pAC->Addr.Port[PortNumber].Exact[0].a)) {
1348
1349 pAC->Addr.Port[PortNumber].PreviousMacAddress =
1350 pAC->Addr.Port[PortNumber].CurrentMacAddress;
1351 pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr;
1352
1353#ifndef SK_NO_RLMT
1354 /* Report address change to RLMT. */
1355 Para.Para32[0] = PortNumber;
1356 Para.Para32[0] = -1;
1357 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para);
1358#endif /* !SK_NO_RLMT */
1359 }
1360
1361#ifndef SK_NO_RLMT
1362 /* Set PortNumber to number of net's active port. */
1363 PortNumber = pAC->Rlmt.Net[NetNumber].
1364 Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
1365#endif /* !SK_NO_RLMT */
1366 pAC->Addr.Net[NetNumber].CurrentMacAddress = *pNewAddr;
1367 pAC->Addr.Port[PortNumber].Exact[0] = *pNewAddr;
1368#ifdef DEBUG
1369 SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
1370 ("SkAddrOverride: Permanent MAC Address: %02X %02X %02X %02X %02X %02X\n",
1371 pAC->Addr.Net[NetNumber].PermanentMacAddress.a[0],
1372 pAC->Addr.Net[NetNumber].PermanentMacAddress.a[1],
1373 pAC->Addr.Net[NetNumber].PermanentMacAddress.a[2],
1374 pAC->Addr.Net[NetNumber].PermanentMacAddress.a[3],
1375 pAC->Addr.Net[NetNumber].PermanentMacAddress.a[4],
1376 pAC->Addr.Net[NetNumber].PermanentMacAddress.a[5]))
1377
1378 SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
1379 ("SkAddrOverride: New logical MAC Address: %02X %02X %02X %02X %02X %02X\n",
1380 pAC->Addr.Net[NetNumber].CurrentMacAddress.a[0],
1381 pAC->Addr.Net[NetNumber].CurrentMacAddress.a[1],
1382 pAC->Addr.Net[NetNumber].CurrentMacAddress.a[2],
1383 pAC->Addr.Net[NetNumber].CurrentMacAddress.a[3],
1384 pAC->Addr.Net[NetNumber].CurrentMacAddress.a[4],
1385 pAC->Addr.Net[NetNumber].CurrentMacAddress.a[5]))
1386#endif /* DEBUG */
1387
1388 /* Write address to first exact match entry of active port. */
1389 (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
1390 }
1391
1392 return (SK_ADDR_SUCCESS);
1393
1394} /* SkAddrOverride */
1395
1396
1397#endif /* SK_NO_MAO */
1398
1399/******************************************************************************
1400 *
1401 * SkAddrPromiscuousChange - set promiscuous mode for given port
1402 *
1403 * Description:
1404 * This routine manages promiscuous mode:
1405 * - none
1406 * - all LLC frames
1407 * - all MC frames
1408 *
1409 * It calls either SkAddrXmacPromiscuousChange or
1410 * SkAddrGmacPromiscuousChange, according to the adapter in use.
1411 * The real work is done there.
1412 *
1413 * Context:
1414 * runtime, pageable
1415 * may be called after SK_INIT_IO
1416 *
1417 * Returns:
1418 * SK_ADDR_SUCCESS
1419 * SK_ADDR_ILLEGAL_PORT
1420 */
1421int SkAddrPromiscuousChange(
1422SK_AC *pAC, /* adapter context */
1423SK_IOC IoC, /* I/O context */
1424SK_U32 PortNumber, /* port whose promiscuous mode changes */
1425int NewPromMode) /* new promiscuous mode */
1426{
1427 int ReturnCode = 0;
1428#if (!defined(SK_SLIM) || defined(DEBUG))
1429 if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
1430 return (SK_ADDR_ILLEGAL_PORT);
1431 }
1432#endif /* !SK_SLIM || DEBUG */
1433
1434#ifdef GENESIS
1435 if (pAC->GIni.GIGenesis) {
1436 ReturnCode =
1437 SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode);
1438 }
1439#endif /* GENESIS */
1440#ifdef YUKON
1441 if (!pAC->GIni.GIGenesis) {
1442 ReturnCode =
1443 SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode);
1444 }
1445#endif /* YUKON */
1446
1447 return (ReturnCode);
1448
1449} /* SkAddrPromiscuousChange */
1450
1451#ifdef GENESIS
1452
1453/******************************************************************************
1454 *
1455 * SkAddrXmacPromiscuousChange - set promiscuous mode for given port
1456 *
1457 * Description:
1458 * This routine manages promiscuous mode:
1459 * - none
1460 * - all LLC frames
1461 * - all MC frames
1462 *
1463 * Context:
1464 * runtime, pageable
1465 * may be called after SK_INIT_IO
1466 *
1467 * Returns:
1468 * SK_ADDR_SUCCESS
1469 * SK_ADDR_ILLEGAL_PORT
1470 */
1471int SkAddrXmacPromiscuousChange(
1472SK_AC *pAC, /* adapter context */
1473SK_IOC IoC, /* I/O context */
1474SK_U32 PortNumber, /* port whose promiscuous mode changes */
1475int NewPromMode) /* new promiscuous mode */
1476{
1477 int i;
1478 SK_BOOL InexactModeBit;
1479 SK_U8 Inexact;
1480 SK_U8 HwInexact;
1481 SK_FILTER64 HwInexactFilter;
1482 SK_U16 LoMode; /* Lower 16 bits of XMAC Mode Register. */
1483 int CurPromMode = SK_PROM_MODE_NONE;
1484
1485 /* Read CurPromMode from Hardware. */
1486 XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
1487
1488 if ((LoMode & XM_MD_ENA_PROM) != 0) {
1489 /* Promiscuous mode! */
1490 CurPromMode |= SK_PROM_MODE_LLC;
1491 }
1492
1493 for (Inexact = 0xFF, i = 0; i < 8; i++) {
1494 Inexact &= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
1495 }
1496 if (Inexact == 0xFF) {
1497 CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC);
1498 }
1499 else {
1500 /* Get InexactModeBit (bit XM_MD_ENA_HASH in mode register) */
1501 XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
1502
1503 InexactModeBit = (LoMode & XM_MD_ENA_HASH) != 0;
1504
1505 /* Read 64-bit hash register from XMAC */
1506 XM_INHASH(IoC, PortNumber, XM_HSM, &HwInexactFilter.Bytes[0]);
1507
1508 for (HwInexact = 0xFF, i = 0; i < 8; i++) {
1509 HwInexact &= HwInexactFilter.Bytes[i];
1510 }
1511
1512 if (InexactModeBit && (HwInexact == 0xFF)) {
1513 CurPromMode |= SK_PROM_MODE_ALL_MC;
1514 }
1515 }
1516
1517 pAC->Addr.Port[PortNumber].PromMode = NewPromMode;
1518
1519 if (NewPromMode == CurPromMode) {
1520 return (SK_ADDR_SUCCESS);
1521 }
1522
1523 if ((NewPromMode & SK_PROM_MODE_ALL_MC) &&
1524 !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC. */
1525
1526 /* Set all bits in 64-bit hash register. */
1527 XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash);
1528
1529 /* Enable Hashing */
1530 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1531 }
1532 else if ((CurPromMode & SK_PROM_MODE_ALL_MC) &&
1533 !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm MC. */
1534 for (Inexact = 0, i = 0; i < 8; i++) {
1535 Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
1536 }
1537 if (Inexact == 0) {
1538 /* Disable Hashing */
1539 SkMacHashing(pAC, IoC, (int) PortNumber, SK_FALSE);
1540 }
1541 else {
1542 /* Set 64-bit hash register to InexactFilter. */
1543 XM_OUTHASH(IoC, PortNumber, XM_HSM,
1544 &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]);
1545
1546 /* Enable Hashing */
1547 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1548 }
1549 }
1550
1551 if ((NewPromMode & SK_PROM_MODE_LLC) &&
1552 !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */
1553 /* Set the MAC in Promiscuous Mode */
1554 SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_TRUE);
1555 }
1556 else if ((CurPromMode & SK_PROM_MODE_LLC) &&
1557 !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC. */
1558 /* Clear Promiscuous Mode */
1559 SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_FALSE);
1560 }
1561
1562 return (SK_ADDR_SUCCESS);
1563
1564} /* SkAddrXmacPromiscuousChange */
1565
1566#endif /* GENESIS */
1567
1568#ifdef YUKON
1569
1570/******************************************************************************
1571 *
1572 * SkAddrGmacPromiscuousChange - set promiscuous mode for given port
1573 *
1574 * Description:
1575 * This routine manages promiscuous mode:
1576 * - none
1577 * - all LLC frames
1578 * - all MC frames
1579 *
1580 * Context:
1581 * runtime, pageable
1582 * may be called after SK_INIT_IO
1583 *
1584 * Returns:
1585 * SK_ADDR_SUCCESS
1586 * SK_ADDR_ILLEGAL_PORT
1587 */
1588int SkAddrGmacPromiscuousChange(
1589SK_AC *pAC, /* adapter context */
1590SK_IOC IoC, /* I/O context */
1591SK_U32 PortNumber, /* port whose promiscuous mode changes */
1592int NewPromMode) /* new promiscuous mode */
1593{
1594 SK_U16 ReceiveControl; /* GMAC Receive Control Register */
1595 int CurPromMode = SK_PROM_MODE_NONE;
1596
1597 /* Read CurPromMode from Hardware. */
1598 GM_IN16(IoC, PortNumber, GM_RX_CTRL, &ReceiveControl);
1599
1600 if ((ReceiveControl & (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA)) == 0) {
1601 /* Promiscuous mode! */
1602 CurPromMode |= SK_PROM_MODE_LLC;
1603 }
1604
1605 if ((ReceiveControl & GM_RXCR_MCF_ENA) == 0) {
1606 /* All Multicast mode! */
1607 CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC);
1608 }
1609
1610 pAC->Addr.Port[PortNumber].PromMode = NewPromMode;
1611
1612 if (NewPromMode == CurPromMode) {
1613 return (SK_ADDR_SUCCESS);
1614 }
1615
1616 if ((NewPromMode & SK_PROM_MODE_ALL_MC) &&
1617 !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC */
1618
1619 /* Set all bits in 64-bit hash register. */
1620 GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash);
1621
1622 /* Enable Hashing */
1623 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1624 }
1625
1626 if ((CurPromMode & SK_PROM_MODE_ALL_MC) &&
1627 !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm. MC */
1628
1629 /* Set 64-bit hash register to InexactFilter. */
1630 GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1,
1631 &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]);
1632
1633 /* Enable Hashing. */
1634 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1635 }
1636
1637 if ((NewPromMode & SK_PROM_MODE_LLC) &&
1638 !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */
1639
1640 /* Set the MAC to Promiscuous Mode. */
1641 SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_TRUE);
1642 }
1643 else if ((CurPromMode & SK_PROM_MODE_LLC) &&
1644 !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC */
1645
1646 /* Clear Promiscuous Mode. */
1647 SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_FALSE);
1648 }
1649
1650 return (SK_ADDR_SUCCESS);
1651
1652} /* SkAddrGmacPromiscuousChange */
1653
1654#endif /* YUKON */
1655
1656#ifndef SK_SLIM
1657
1658/******************************************************************************
1659 *
1660 * SkAddrSwap - swap address info
1661 *
1662 * Description:
1663 * This routine swaps address info of two ports.
1664 *
1665 * Context:
1666 * runtime, pageable
1667 * may be called after SK_INIT_IO
1668 *
1669 * Returns:
1670 * SK_ADDR_SUCCESS
1671 * SK_ADDR_ILLEGAL_PORT
1672 */
1673int SkAddrSwap(
1674SK_AC *pAC, /* adapter context */
1675SK_IOC IoC, /* I/O context */
1676SK_U32 FromPortNumber, /* Port1 Index */
1677SK_U32 ToPortNumber) /* Port2 Index */
1678{
1679 int i;
1680 SK_U8 Byte;
1681 SK_MAC_ADDR MacAddr;
1682 SK_U32 DWord;
1683
1684 if (FromPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
1685 return (SK_ADDR_ILLEGAL_PORT);
1686 }
1687
1688 if (ToPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
1689 return (SK_ADDR_ILLEGAL_PORT);
1690 }
1691
1692 if (pAC->Rlmt.Port[FromPortNumber].Net != pAC->Rlmt.Port[ToPortNumber].Net) {
1693 return (SK_ADDR_ILLEGAL_PORT);
1694 }
1695
1696 /*
1697 * Swap:
1698 * - Exact Match Entries (GEnesis and Yukon)
1699 * Yukon uses first entry for the logical MAC
1700 * address (stored in the second GMAC register).
1701 * - FirstExactMatchRlmt (GEnesis only)
1702 * - NextExactMatchRlmt (GEnesis only)
1703 * - FirstExactMatchDrv (GEnesis only)
1704 * - NextExactMatchDrv (GEnesis only)
1705 * - 64-bit filter (InexactFilter)
1706 * - Promiscuous Mode
1707 * of ports.
1708 */
1709
1710 for (i = 0; i < SK_ADDR_EXACT_MATCHES; i++) {
1711 MacAddr = pAC->Addr.Port[FromPortNumber].Exact[i];
1712 pAC->Addr.Port[FromPortNumber].Exact[i] =
1713 pAC->Addr.Port[ToPortNumber].Exact[i];
1714 pAC->Addr.Port[ToPortNumber].Exact[i] = MacAddr;
1715 }
1716
1717 for (i = 0; i < 8; i++) {
1718 Byte = pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i];
1719 pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i] =
1720 pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i];
1721 pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i] = Byte;
1722 }
1723
1724 i = pAC->Addr.Port[FromPortNumber].PromMode;
1725 pAC->Addr.Port[FromPortNumber].PromMode = pAC->Addr.Port[ToPortNumber].PromMode;
1726 pAC->Addr.Port[ToPortNumber].PromMode = i;
1727
1728 if (pAC->GIni.GIGenesis) {
1729 DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt;
1730 pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt =
1731 pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt;
1732 pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt = DWord;
1733
1734 DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt;
1735 pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt =
1736 pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt;
1737 pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt = DWord;
1738
1739 DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv;
1740 pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv =
1741 pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv;
1742 pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv = DWord;
1743
1744 DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchDrv;
1745 pAC->Addr.Port[FromPortNumber].NextExactMatchDrv =
1746 pAC->Addr.Port[ToPortNumber].NextExactMatchDrv;
1747 pAC->Addr.Port[ToPortNumber].NextExactMatchDrv = DWord;
1748 }
1749
1750 /* CAUTION: Solution works if only ports of one adapter are in use. */
1751 for (i = 0; (SK_U32) i < pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].
1752 Net->NetNumber].NumPorts; i++) {
1753 if (pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber].
1754 Port[i]->PortNumber == ToPortNumber) {
1755 pAC->Addr.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber].
1756 ActivePort = i;
1757 /* 20001207 RA: Was "ToPortNumber;". */
1758 }
1759 }
1760
1761 (void) SkAddrMcUpdate(pAC, IoC, FromPortNumber);
1762 (void) SkAddrMcUpdate(pAC, IoC, ToPortNumber);
1763
1764 return (SK_ADDR_SUCCESS);
1765
1766} /* SkAddrSwap */
1767
1768#endif /* !SK_SLIM */
1769
1770#ifdef __cplusplus
1771}
1772#endif /* __cplusplus */
1773
diff --git a/drivers/net/sk98lin/skcsum.c b/drivers/net/sk98lin/skcsum.c
new file mode 100644
index 000000000000..38a6e7a631f3
--- /dev/null
+++ b/drivers/net/sk98lin/skcsum.c
@@ -0,0 +1,871 @@
1/******************************************************************************
2 *
3 * Name: skcsum.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.12 $
6 * Date: $Date: 2003/08/20 13:55:53 $
7 * Purpose: Store/verify Internet checksum in send/receive packets.
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2003 SysKonnect GmbH.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * The information in this file is provided "AS IS" without warranty.
21 *
22 ******************************************************************************/
23
24#ifdef SK_USE_CSUM /* Check if CSUM is to be used. */
25
26#ifndef lint
27static const char SysKonnectFileId[] =
28 "@(#) $Id: skcsum.c,v 1.12 2003/08/20 13:55:53 mschmid Exp $ (C) SysKonnect.";
29#endif /* !lint */
30
31/******************************************************************************
32 *
33 * Description:
34 *
35 * This is the "GEnesis" common module "CSUM".
36 *
37 * This module contains the code necessary to calculate, store, and verify the
38 * Internet Checksum of IP, TCP, and UDP frames.
39 *
40 * "GEnesis" is an abbreviation of "Gigabit Ethernet Network System in Silicon"
41 * and is the code name of this SysKonnect project.
42 *
43 * Compilation Options:
44 *
45 * SK_USE_CSUM - Define if CSUM is to be used. Otherwise, CSUM will be an
46 * empty module.
47 *
48 * SKCS_OVERWRITE_PROTO - Define to overwrite the default protocol id
49 * definitions. In this case, all SKCS_PROTO_xxx definitions must be made
50 * external.
51 *
52 * SKCS_OVERWRITE_STATUS - Define to overwrite the default return status
53 * definitions. In this case, all SKCS_STATUS_xxx definitions must be made
54 * external.
55 *
56 * Include File Hierarchy:
57 *
58 * "h/skdrv1st.h"
59 * "h/skcsum.h"
60 * "h/sktypes.h"
61 * "h/skqueue.h"
62 * "h/skdrv2nd.h"
63 *
64 ******************************************************************************/
65
66#include "h/skdrv1st.h"
67#include "h/skcsum.h"
68#include "h/skdrv2nd.h"
69
70/* defines ********************************************************************/
71
72/* The size of an Ethernet MAC header. */
73#define SKCS_ETHERNET_MAC_HEADER_SIZE (6+6+2)
74
75/* The size of the used topology's MAC header. */
76#define SKCS_MAC_HEADER_SIZE SKCS_ETHERNET_MAC_HEADER_SIZE
77
78/* The size of the IP header without any option fields. */
79#define SKCS_IP_HEADER_SIZE 20
80
81/*
82 * Field offsets within the IP header.
83 */
84
85/* "Internet Header Version" and "Length". */
86#define SKCS_OFS_IP_HEADER_VERSION_AND_LENGTH 0
87
88/* "Total Length". */
89#define SKCS_OFS_IP_TOTAL_LENGTH 2
90
91/* "Flags" "Fragment Offset". */
92#define SKCS_OFS_IP_FLAGS_AND_FRAGMENT_OFFSET 6
93
94/* "Next Level Protocol" identifier. */
95#define SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL 9
96
97/* Source IP address. */
98#define SKCS_OFS_IP_SOURCE_ADDRESS 12
99
100/* Destination IP address. */
101#define SKCS_OFS_IP_DESTINATION_ADDRESS 16
102
103
104/*
105 * Field offsets within the UDP header.
106 */
107
108/* UDP checksum. */
109#define SKCS_OFS_UDP_CHECKSUM 6
110
111/* IP "Next Level Protocol" identifiers (see RFC 790). */
112#define SKCS_PROTO_ID_TCP 6 /* Transport Control Protocol */
113#define SKCS_PROTO_ID_UDP 17 /* User Datagram Protocol */
114
115/* IP "Don't Fragment" bit. */
116#define SKCS_IP_DONT_FRAGMENT SKCS_HTON16(0x4000)
117
118/* Add a byte offset to a pointer. */
119#define SKCS_IDX(pPtr, Ofs) ((void *) ((char *) (pPtr) + (Ofs)))
120
121/*
122 * Macros that convert host to network representation and vice versa, i.e.
123 * little/big endian conversion on little endian machines only.
124 */
125#ifdef SK_LITTLE_ENDIAN
126#define SKCS_HTON16(Val16) (((unsigned) (Val16) >> 8) | (((Val16) & 0xff) << 8))
127#endif /* SK_LITTLE_ENDIAN */
128#ifdef SK_BIG_ENDIAN
129#define SKCS_HTON16(Val16) (Val16)
130#endif /* SK_BIG_ENDIAN */
131#define SKCS_NTOH16(Val16) SKCS_HTON16(Val16)
132
133/* typedefs *******************************************************************/
134
135/* function prototypes ********************************************************/
136
137/******************************************************************************
138 *
139 * SkCsGetSendInfo - get checksum information for a send packet
140 *
141 * Description:
142 * Get all checksum information necessary to send a TCP or UDP packet. The
143 * function checks the IP header passed to it. If the high-level protocol
144 * is either TCP or UDP the pseudo header checksum is calculated and
145 * returned.
146 *
147 * The function returns the total length of the IP header (including any
148 * IP option fields), which is the same as the start offset of the IP data
149 * which in turn is the start offset of the TCP or UDP header.
150 *
151 * The function also returns the TCP or UDP pseudo header checksum, which
152 * should be used as the start value for the hardware checksum calculation.
153 * (Note that any actual pseudo header checksum can never calculate to
154 * zero.)
155 *
156 * Note:
157 * There is a bug in the GENESIS ASIC which may lead to wrong checksums.
158 *
159 * Arguments:
160 * pAc - A pointer to the adapter context struct.
161 *
162 * pIpHeader - Pointer to IP header. Must be at least the IP header *not*
163 * including any option fields, i.e. at least 20 bytes.
164 *
165 * Note: This pointer will be used to address 8-, 16-, and 32-bit
166 * variables with the respective alignment offsets relative to the pointer.
167 * Thus, the pointer should point to a 32-bit aligned address. If the
168 * target system cannot address 32-bit variables on non 32-bit aligned
169 * addresses, then the pointer *must* point to a 32-bit aligned address.
170 *
171 * pPacketInfo - A pointer to the packet information structure for this
172 * packet. Before calling this SkCsGetSendInfo(), the following field must
173 * be initialized:
174 *
175 * ProtocolFlags - Initialize with any combination of
176 * SKCS_PROTO_XXX bit flags. SkCsGetSendInfo() will only work on
177 * the protocols specified here. Any protocol(s) not specified
178 * here will be ignored.
179 *
180 * Note: Only one checksum can be calculated in hardware. Thus, if
181 * SKCS_PROTO_IP is specified in the 'ProtocolFlags',
182 * SkCsGetSendInfo() must calculate the IP header checksum in
183 * software. It might be a better idea to have the calling
184 * protocol stack calculate the IP header checksum.
185 *
186 * Returns: N/A
187 * On return, the following fields in 'pPacketInfo' may or may not have
188 * been filled with information, depending on the protocol(s) found in the
189 * packet:
190 *
191 * ProtocolFlags - Returns the SKCS_PROTO_XXX bit flags of the protocol(s)
192 * that were both requested by the caller and actually found in the packet.
193 * Protocol(s) not specified by the caller and/or not found in the packet
194 * will have their respective SKCS_PROTO_XXX bit flags reset.
195 *
196 * Note: For IP fragments, TCP and UDP packet information is ignored.
197 *
198 * IpHeaderLength - The total length in bytes of the complete IP header
199 * including any option fields is returned here. This is the start offset
200 * of the IP data, i.e. the TCP or UDP header if present.
201 *
202 * IpHeaderChecksum - If IP has been specified in the 'ProtocolFlags', the
203 * 16-bit Internet Checksum of the IP header is returned here. This value
204 * is to be stored into the packet's 'IP Header Checksum' field.
205 *
206 * PseudoHeaderChecksum - If this is a TCP or UDP packet and if TCP or UDP
207 * has been specified in the 'ProtocolFlags', the 16-bit Internet Checksum
208 * of the TCP or UDP pseudo header is returned here.
209 */
210void SkCsGetSendInfo(
211SK_AC *pAc, /* Adapter context struct. */
212void *pIpHeader, /* IP header. */
213SKCS_PACKET_INFO *pPacketInfo, /* Packet information struct. */
214int NetNumber) /* Net number */
215{
216 /* Internet Header Version found in IP header. */
217 unsigned InternetHeaderVersion;
218
219 /* Length of the IP header as found in IP header. */
220 unsigned IpHeaderLength;
221
222 /* Bit field specifiying the desired/found protocols. */
223 unsigned ProtocolFlags;
224
225 /* Next level protocol identifier found in IP header. */
226 unsigned NextLevelProtocol;
227
228 /* Length of IP data portion. */
229 unsigned IpDataLength;
230
231 /* TCP/UDP pseudo header checksum. */
232 unsigned long PseudoHeaderChecksum;
233
234 /* Pointer to next level protocol statistics structure. */
235 SKCS_PROTO_STATS *NextLevelProtoStats;
236
237 /* Temporary variable. */
238 unsigned Tmp;
239
240 Tmp = *(SK_U8 *)
241 SKCS_IDX(pIpHeader, SKCS_OFS_IP_HEADER_VERSION_AND_LENGTH);
242
243 /* Get the Internet Header Version (IHV). */
244 /* Note: The IHV is stored in the upper four bits. */
245
246 InternetHeaderVersion = Tmp >> 4;
247
248 /* Check the Internet Header Version. */
249 /* Note: We currently only support IP version 4. */
250
251 if (InternetHeaderVersion != 4) { /* IPv4? */
252 SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_TX,
253 ("Tx: Unknown Internet Header Version %u.\n",
254 InternetHeaderVersion));
255 pPacketInfo->ProtocolFlags = 0;
256 pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxUnableCts++;
257 return;
258 }
259
260 /* Get the IP header length (IHL). */
261 /*
262 * Note: The IHL is stored in the lower four bits as the number of
263 * 4-byte words.
264 */
265
266 IpHeaderLength = (Tmp & 0xf) * 4;
267 pPacketInfo->IpHeaderLength = IpHeaderLength;
268
269 /* Check the IP header length. */
270
271 /* 04-Aug-1998 sw - Really check the IHL? Necessary? */
272
273 if (IpHeaderLength < 5*4) {
274 SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_TX,
275 ("Tx: Invalid IP Header Length %u.\n", IpHeaderLength));
276 pPacketInfo->ProtocolFlags = 0;
277 pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxUnableCts++;
278 return;
279 }
280
281 /* This is an IPv4 frame with a header of valid length. */
282
283 pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxOkCts++;
284
285 /* Check if we should calculate the IP header checksum. */
286
287 ProtocolFlags = pPacketInfo->ProtocolFlags;
288
289 if (ProtocolFlags & SKCS_PROTO_IP) {
290 pPacketInfo->IpHeaderChecksum =
291 SkCsCalculateChecksum(pIpHeader, IpHeaderLength);
292 }
293
294 /* Get the next level protocol identifier. */
295
296 NextLevelProtocol =
297 *(SK_U8 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL);
298
299 /*
300 * Check if this is a TCP or UDP frame and if we should calculate the
301 * TCP/UDP pseudo header checksum.
302 *
303 * Also clear all protocol bit flags of protocols not present in the
304 * frame.
305 */
306
307 if ((ProtocolFlags & SKCS_PROTO_TCP) != 0 &&
308 NextLevelProtocol == SKCS_PROTO_ID_TCP) {
309 /* TCP/IP frame. */
310 ProtocolFlags &= SKCS_PROTO_TCP | SKCS_PROTO_IP;
311 NextLevelProtoStats =
312 &pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_TCP];
313 }
314 else if ((ProtocolFlags & SKCS_PROTO_UDP) != 0 &&
315 NextLevelProtocol == SKCS_PROTO_ID_UDP) {
316 /* UDP/IP frame. */
317 ProtocolFlags &= SKCS_PROTO_UDP | SKCS_PROTO_IP;
318 NextLevelProtoStats =
319 &pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_UDP];
320 }
321 else {
322 /*
323 * Either not a TCP or UDP frame and/or TCP/UDP processing not
324 * specified.
325 */
326 pPacketInfo->ProtocolFlags = ProtocolFlags & SKCS_PROTO_IP;
327 return;
328 }
329
330 /* Check if this is an IP fragment. */
331
332 /*
333 * Note: An IP fragment has a non-zero "Fragment Offset" field and/or
334 * the "More Fragments" bit set. Thus, if both the "Fragment Offset"
335 * and the "More Fragments" are zero, it is *not* a fragment. We can
336 * easily check both at the same time since they are in the same 16-bit
337 * word.
338 */
339
340 if ((*(SK_U16 *)
341 SKCS_IDX(pIpHeader, SKCS_OFS_IP_FLAGS_AND_FRAGMENT_OFFSET) &
342 ~SKCS_IP_DONT_FRAGMENT) != 0) {
343 /* IP fragment; ignore all other protocols. */
344 pPacketInfo->ProtocolFlags = ProtocolFlags & SKCS_PROTO_IP;
345 NextLevelProtoStats->TxUnableCts++;
346 return;
347 }
348
349 /*
350 * Calculate the TCP/UDP pseudo header checksum.
351 */
352
353 /* Get total length of IP header and data. */
354
355 IpDataLength =
356 *(SK_U16 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_TOTAL_LENGTH);
357
358 /* Get length of IP data portion. */
359
360 IpDataLength = SKCS_NTOH16(IpDataLength) - IpHeaderLength;
361
362 /* Calculate the sum of all pseudo header fields (16-bit). */
363
364 PseudoHeaderChecksum =
365 (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
366 SKCS_OFS_IP_SOURCE_ADDRESS + 0) +
367 (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
368 SKCS_OFS_IP_SOURCE_ADDRESS + 2) +
369 (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
370 SKCS_OFS_IP_DESTINATION_ADDRESS + 0) +
371 (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
372 SKCS_OFS_IP_DESTINATION_ADDRESS + 2) +
373 (unsigned long) SKCS_HTON16(NextLevelProtocol) +
374 (unsigned long) SKCS_HTON16(IpDataLength);
375
376 /* Add-in any carries. */
377
378 SKCS_OC_ADD(PseudoHeaderChecksum, PseudoHeaderChecksum, 0);
379
380 /* Add-in any new carry. */
381
382 SKCS_OC_ADD(pPacketInfo->PseudoHeaderChecksum, PseudoHeaderChecksum, 0);
383
384 pPacketInfo->ProtocolFlags = ProtocolFlags;
385 NextLevelProtoStats->TxOkCts++; /* Success. */
386} /* SkCsGetSendInfo */
387
388
389/******************************************************************************
390 *
391 * SkCsGetReceiveInfo - verify checksum information for a received packet
392 *
393 * Description:
394 * Verify a received frame's checksum. The function returns a status code
395 * reflecting the result of the verification.
396 *
397 * Note:
398 * Before calling this function you have to verify that the frame is
399 * not padded and Checksum1 and Checksum2 are bigger than 1.
400 *
401 * Arguments:
402 * pAc - Pointer to adapter context struct.
403 *
404 * pIpHeader - Pointer to IP header. Must be at least the length in bytes
405 * of the received IP header including any option fields. For UDP packets,
406 * 8 additional bytes are needed to access the UDP checksum.
407 *
408 * Note: The actual length of the IP header is stored in the lower four
409 * bits of the first octet of the IP header as the number of 4-byte words,
410 * so it must be multiplied by four to get the length in bytes. Thus, the
411 * maximum IP header length is 15 * 4 = 60 bytes.
412 *
413 * Checksum1 - The first 16-bit Internet Checksum calculated by the
414 * hardware starting at the offset returned by SkCsSetReceiveFlags().
415 *
416 * Checksum2 - The second 16-bit Internet Checksum calculated by the
417 * hardware starting at the offset returned by SkCsSetReceiveFlags().
418 *
419 * Returns:
420 * SKCS_STATUS_UNKNOWN_IP_VERSION - Not an IP v4 frame.
421 * SKCS_STATUS_IP_CSUM_ERROR - IP checksum error.
422 * SKCS_STATUS_IP_CSUM_ERROR_TCP - IP checksum error in TCP frame.
423 * SKCS_STATUS_IP_CSUM_ERROR_UDP - IP checksum error in UDP frame
424 * SKCS_STATUS_IP_FRAGMENT - IP fragment (IP checksum ok).
425 * SKCS_STATUS_IP_CSUM_OK - IP checksum ok (not a TCP or UDP frame).
426 * SKCS_STATUS_TCP_CSUM_ERROR - TCP checksum error (IP checksum ok).
427 * SKCS_STATUS_UDP_CSUM_ERROR - UDP checksum error (IP checksum ok).
428 * SKCS_STATUS_TCP_CSUM_OK - IP and TCP checksum ok.
429 * SKCS_STATUS_UDP_CSUM_OK - IP and UDP checksum ok.
430 * SKCS_STATUS_IP_CSUM_OK_NO_UDP - IP checksum OK and no UDP checksum.
431 *
432 * Note: If SKCS_OVERWRITE_STATUS is defined, the SKCS_STATUS_XXX values
433 * returned here can be defined in some header file by the module using CSUM.
434 * In this way, the calling module can assign return values for its own needs,
435 * e.g. by assigning bit flags to the individual protocols.
436 */
437SKCS_STATUS SkCsGetReceiveInfo(
438SK_AC *pAc, /* Adapter context struct. */
439void *pIpHeader, /* IP header. */
440unsigned Checksum1, /* Hardware checksum 1. */
441unsigned Checksum2, /* Hardware checksum 2. */
442int NetNumber) /* Net number */
443{
444 /* Internet Header Version found in IP header. */
445 unsigned InternetHeaderVersion;
446
447 /* Length of the IP header as found in IP header. */
448 unsigned IpHeaderLength;
449
450 /* Length of IP data portion. */
451 unsigned IpDataLength;
452
453 /* IP header checksum. */
454 unsigned IpHeaderChecksum;
455
456 /* IP header options checksum, if any. */
457 unsigned IpOptionsChecksum;
458
459 /* IP data checksum, i.e. TCP/UDP checksum. */
460 unsigned IpDataChecksum;
461
462 /* Next level protocol identifier found in IP header. */
463 unsigned NextLevelProtocol;
464
465 /* The checksum of the "next level protocol", i.e. TCP or UDP. */
466 unsigned long NextLevelProtocolChecksum;
467
468 /* Pointer to next level protocol statistics structure. */
469 SKCS_PROTO_STATS *NextLevelProtoStats;
470
471 /* Temporary variable. */
472 unsigned Tmp;
473
474 Tmp = *(SK_U8 *)
475 SKCS_IDX(pIpHeader, SKCS_OFS_IP_HEADER_VERSION_AND_LENGTH);
476
477 /* Get the Internet Header Version (IHV). */
478 /* Note: The IHV is stored in the upper four bits. */
479
480 InternetHeaderVersion = Tmp >> 4;
481
482 /* Check the Internet Header Version. */
483 /* Note: We currently only support IP version 4. */
484
485 if (InternetHeaderVersion != 4) { /* IPv4? */
486 SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_RX,
487 ("Rx: Unknown Internet Header Version %u.\n",
488 InternetHeaderVersion));
489 pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxUnableCts++;
490 return (SKCS_STATUS_UNKNOWN_IP_VERSION);
491 }
492
493 /* Get the IP header length (IHL). */
494 /*
495 * Note: The IHL is stored in the lower four bits as the number of
496 * 4-byte words.
497 */
498
499 IpHeaderLength = (Tmp & 0xf) * 4;
500
501 /* Check the IP header length. */
502
503 /* 04-Aug-1998 sw - Really check the IHL? Necessary? */
504
505 if (IpHeaderLength < 5*4) {
506 SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_RX,
507 ("Rx: Invalid IP Header Length %u.\n", IpHeaderLength));
508 pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxErrCts++;
509 return (SKCS_STATUS_IP_CSUM_ERROR);
510 }
511
512 /* This is an IPv4 frame with a header of valid length. */
513
514 /* Get the IP header and data checksum. */
515
516 IpDataChecksum = Checksum2;
517
518 /*
519 * The IP header checksum is calculated as follows:
520 *
521 * IpHeaderChecksum = Checksum1 - Checksum2
522 */
523
524 SKCS_OC_SUB(IpHeaderChecksum, Checksum1, Checksum2);
525
526 /* Check if any IP header options. */
527
528 if (IpHeaderLength > SKCS_IP_HEADER_SIZE) {
529
530 /* Get the IP options checksum. */
531
532 IpOptionsChecksum = SkCsCalculateChecksum(
533 SKCS_IDX(pIpHeader, SKCS_IP_HEADER_SIZE),
534 IpHeaderLength - SKCS_IP_HEADER_SIZE);
535
536 /* Adjust the IP header and IP data checksums. */
537
538 SKCS_OC_ADD(IpHeaderChecksum, IpHeaderChecksum, IpOptionsChecksum);
539
540 SKCS_OC_SUB(IpDataChecksum, IpDataChecksum, IpOptionsChecksum);
541 }
542
543 /*
544 * Check if the IP header checksum is ok.
545 *
546 * NOTE: We must check the IP header checksum even if the caller just wants
547 * us to check upper-layer checksums, because we cannot do any further
548 * processing of the packet without a valid IP checksum.
549 */
550
551 /* Get the next level protocol identifier. */
552
553 NextLevelProtocol = *(SK_U8 *)
554 SKCS_IDX(pIpHeader, SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL);
555
556 if (IpHeaderChecksum != 0xffff) {
557 pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxErrCts++;
558 /* the NDIS tester wants to know the upper level protocol too */
559 if (NextLevelProtocol == SKCS_PROTO_ID_TCP) {
560 return(SKCS_STATUS_IP_CSUM_ERROR_TCP);
561 }
562 else if (NextLevelProtocol == SKCS_PROTO_ID_UDP) {
563 return(SKCS_STATUS_IP_CSUM_ERROR_UDP);
564 }
565 return (SKCS_STATUS_IP_CSUM_ERROR);
566 }
567
568 /*
569 * Check if this is a TCP or UDP frame and if we should calculate the
570 * TCP/UDP pseudo header checksum.
571 *
572 * Also clear all protocol bit flags of protocols not present in the
573 * frame.
574 */
575
576 if ((pAc->Csum.ReceiveFlags[NetNumber] & SKCS_PROTO_TCP) != 0 &&
577 NextLevelProtocol == SKCS_PROTO_ID_TCP) {
578 /* TCP/IP frame. */
579 NextLevelProtoStats =
580 &pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_TCP];
581 }
582 else if ((pAc->Csum.ReceiveFlags[NetNumber] & SKCS_PROTO_UDP) != 0 &&
583 NextLevelProtocol == SKCS_PROTO_ID_UDP) {
584 /* UDP/IP frame. */
585 NextLevelProtoStats =
586 &pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_UDP];
587 }
588 else {
589 /*
590 * Either not a TCP or UDP frame and/or TCP/UDP processing not
591 * specified.
592 */
593 return (SKCS_STATUS_IP_CSUM_OK);
594 }
595
596 /* Check if this is an IP fragment. */
597
598 /*
599 * Note: An IP fragment has a non-zero "Fragment Offset" field and/or
600 * the "More Fragments" bit set. Thus, if both the "Fragment Offset"
601 * and the "More Fragments" are zero, it is *not* a fragment. We can
602 * easily check both at the same time since they are in the same 16-bit
603 * word.
604 */
605
606 if ((*(SK_U16 *)
607 SKCS_IDX(pIpHeader, SKCS_OFS_IP_FLAGS_AND_FRAGMENT_OFFSET) &
608 ~SKCS_IP_DONT_FRAGMENT) != 0) {
609 /* IP fragment; ignore all other protocols. */
610 NextLevelProtoStats->RxUnableCts++;
611 return (SKCS_STATUS_IP_FRAGMENT);
612 }
613
614 /*
615 * 08-May-2000 ra
616 *
617 * From RFC 768 (UDP)
618 * If the computed checksum is zero, it is transmitted as all ones (the
619 * equivalent in one's complement arithmetic). An all zero transmitted
620 * checksum value means that the transmitter generated no checksum (for
621 * debugging or for higher level protocols that don't care).
622 */
623
624 if (NextLevelProtocol == SKCS_PROTO_ID_UDP &&
625 *(SK_U16*)SKCS_IDX(pIpHeader, IpHeaderLength + 6) == 0x0000) {
626
627 NextLevelProtoStats->RxOkCts++;
628
629 return (SKCS_STATUS_IP_CSUM_OK_NO_UDP);
630 }
631
632 /*
633 * Calculate the TCP/UDP checksum.
634 */
635
636 /* Get total length of IP header and data. */
637
638 IpDataLength =
639 *(SK_U16 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_TOTAL_LENGTH);
640
641 /* Get length of IP data portion. */
642
643 IpDataLength = SKCS_NTOH16(IpDataLength) - IpHeaderLength;
644
645 NextLevelProtocolChecksum =
646
647 /* Calculate the pseudo header checksum. */
648
649 (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
650 SKCS_OFS_IP_SOURCE_ADDRESS + 0) +
651 (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
652 SKCS_OFS_IP_SOURCE_ADDRESS + 2) +
653 (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
654 SKCS_OFS_IP_DESTINATION_ADDRESS + 0) +
655 (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
656 SKCS_OFS_IP_DESTINATION_ADDRESS + 2) +
657 (unsigned long) SKCS_HTON16(NextLevelProtocol) +
658 (unsigned long) SKCS_HTON16(IpDataLength) +
659
660 /* Add the TCP/UDP header checksum. */
661
662 (unsigned long) IpDataChecksum;
663
664 /* Add-in any carries. */
665
666 SKCS_OC_ADD(NextLevelProtocolChecksum, NextLevelProtocolChecksum, 0);
667
668 /* Add-in any new carry. */
669
670 SKCS_OC_ADD(NextLevelProtocolChecksum, NextLevelProtocolChecksum, 0);
671
672 /* Check if the TCP/UDP checksum is ok. */
673
674 if ((unsigned) NextLevelProtocolChecksum == 0xffff) {
675
676 /* TCP/UDP checksum ok. */
677
678 NextLevelProtoStats->RxOkCts++;
679
680 return (NextLevelProtocol == SKCS_PROTO_ID_TCP ?
681 SKCS_STATUS_TCP_CSUM_OK : SKCS_STATUS_UDP_CSUM_OK);
682 }
683
684 /* TCP/UDP checksum error. */
685
686 NextLevelProtoStats->RxErrCts++;
687
688 return (NextLevelProtocol == SKCS_PROTO_ID_TCP ?
689 SKCS_STATUS_TCP_CSUM_ERROR : SKCS_STATUS_UDP_CSUM_ERROR);
690} /* SkCsGetReceiveInfo */
691
692
693/******************************************************************************
694 *
695 * SkCsSetReceiveFlags - set checksum receive flags
696 *
697 * Description:
698 * Use this function to set the various receive flags. According to the
699 * protocol flags set by the caller, the start offsets within received
700 * packets of the two hardware checksums are returned. These offsets must
701 * be stored in all receive descriptors.
702 *
703 * Arguments:
704 * pAc - Pointer to adapter context struct.
705 *
706 * ReceiveFlags - Any combination of SK_PROTO_XXX flags of the protocols
707 * for which the caller wants checksum information on received frames.
708 *
709 * pChecksum1Offset - The start offset of the first receive descriptor
710 * hardware checksum to be calculated for received frames is returned
711 * here.
712 *
713 * pChecksum2Offset - The start offset of the second receive descriptor
714 * hardware checksum to be calculated for received frames is returned
715 * here.
716 *
717 * Returns: N/A
718 * Returns the two hardware checksum start offsets.
719 */
720void SkCsSetReceiveFlags(
721SK_AC *pAc, /* Adapter context struct. */
722unsigned ReceiveFlags, /* New receive flags. */
723unsigned *pChecksum1Offset, /* Offset for hardware checksum 1. */
724unsigned *pChecksum2Offset, /* Offset for hardware checksum 2. */
725int NetNumber)
726{
727 /* Save the receive flags. */
728
729 pAc->Csum.ReceiveFlags[NetNumber] = ReceiveFlags;
730
731 /* First checksum start offset is the IP header. */
732 *pChecksum1Offset = SKCS_MAC_HEADER_SIZE;
733
734 /*
735 * Second checksum start offset is the IP data. Note that this may vary
736 * if there are any IP header options in the actual packet.
737 */
738 *pChecksum2Offset = SKCS_MAC_HEADER_SIZE + SKCS_IP_HEADER_SIZE;
739} /* SkCsSetReceiveFlags */
740
741#ifndef SK_CS_CALCULATE_CHECKSUM
742
743/******************************************************************************
744 *
745 * SkCsCalculateChecksum - calculate checksum for specified data
746 *
747 * Description:
748 * Calculate and return the 16-bit Internet Checksum for the specified
749 * data.
750 *
751 * Arguments:
752 * pData - Pointer to data for which the checksum shall be calculated.
753 * Note: The pointer should be aligned on a 16-bit boundary.
754 *
755 * Length - Length in bytes of data to checksum.
756 *
757 * Returns:
758 * The 16-bit Internet Checksum for the specified data.
759 *
760 * Note: The checksum is calculated in the machine's natural byte order,
761 * i.e. little vs. big endian. Thus, the resulting checksum is different
762 * for the same input data on little and big endian machines.
763 *
764 * However, when written back to the network packet, the byte order is
765 * always in correct network order.
766 */
767unsigned SkCsCalculateChecksum(
768void *pData, /* Data to checksum. */
769unsigned Length) /* Length of data. */
770{
771 SK_U16 *pU16; /* Pointer to the data as 16-bit words. */
772 unsigned long Checksum; /* Checksum; must be at least 32 bits. */
773
774 /* Sum up all 16-bit words. */
775
776 pU16 = (SK_U16 *) pData;
777 for (Checksum = 0; Length > 1; Length -= 2) {
778 Checksum += *pU16++;
779 }
780
781 /* If this is an odd number of bytes, add-in the last byte. */
782
783 if (Length > 0) {
784#ifdef SK_BIG_ENDIAN
785 /* Add the last byte as the high byte. */
786 Checksum += ((unsigned) *(SK_U8 *) pU16) << 8;
787#else /* !SK_BIG_ENDIAN */
788 /* Add the last byte as the low byte. */
789 Checksum += *(SK_U8 *) pU16;
790#endif /* !SK_BIG_ENDIAN */
791 }
792
793 /* Add-in any carries. */
794
795 SKCS_OC_ADD(Checksum, Checksum, 0);
796
797 /* Add-in any new carry. */
798
799 SKCS_OC_ADD(Checksum, Checksum, 0);
800
801 /* Note: All bits beyond the 16-bit limit are now zero. */
802
803 return ((unsigned) Checksum);
804} /* SkCsCalculateChecksum */
805
806#endif /* SK_CS_CALCULATE_CHECKSUM */
807
808/******************************************************************************
809 *
810 * SkCsEvent - the CSUM event dispatcher
811 *
812 * Description:
813 * This is the event handler for the CSUM module.
814 *
815 * Arguments:
816 * pAc - Pointer to adapter context.
817 *
818 * Ioc - I/O context.
819 *
820 * Event - Event id.
821 *
822 * Param - Event dependent parameter.
823 *
824 * Returns:
825 * The 16-bit Internet Checksum for the specified data.
826 *
827 * Note: The checksum is calculated in the machine's natural byte order,
828 * i.e. little vs. big endian. Thus, the resulting checksum is different
829 * for the same input data on little and big endian machines.
830 *
831 * However, when written back to the network packet, the byte order is
832 * always in correct network order.
833 */
834int SkCsEvent(
835SK_AC *pAc, /* Pointer to adapter context. */
836SK_IOC Ioc, /* I/O context. */
837SK_U32 Event, /* Event id. */
838SK_EVPARA Param) /* Event dependent parameter. */
839{
840 int ProtoIndex;
841 int NetNumber;
842
843 switch (Event) {
844 /*
845 * Clear protocol statistics.
846 *
847 * Param - Protocol index, or -1 for all protocols.
848 * - Net number.
849 */
850 case SK_CSUM_EVENT_CLEAR_PROTO_STATS:
851
852 ProtoIndex = (int)Param.Para32[1];
853 NetNumber = (int)Param.Para32[0];
854 if (ProtoIndex < 0) { /* Clear for all protocols. */
855 if (NetNumber >= 0) {
856 SK_MEMSET(&pAc->Csum.ProtoStats[NetNumber][0], 0,
857 sizeof(pAc->Csum.ProtoStats[NetNumber]));
858 }
859 }
860 else { /* Clear for individual protocol. */
861 SK_MEMSET(&pAc->Csum.ProtoStats[NetNumber][ProtoIndex], 0,
862 sizeof(pAc->Csum.ProtoStats[NetNumber][ProtoIndex]));
863 }
864 break;
865 default:
866 break;
867 }
868 return (0); /* Success. */
869} /* SkCsEvent */
870
871#endif /* SK_USE_CSUM */
diff --git a/drivers/net/sk98lin/skdim.c b/drivers/net/sk98lin/skdim.c
new file mode 100644
index 000000000000..0fddf61047b4
--- /dev/null
+++ b/drivers/net/sk98lin/skdim.c
@@ -0,0 +1,742 @@
1/******************************************************************************
2 *
3 * Name: skdim.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.5 $
6 * Date: $Date: 2003/11/28 12:55:40 $
7 * Purpose: All functions to maintain interrupt moderation
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * This module is intended to manage the dynamic interrupt moderation on both
30 * GEnesis and Yukon adapters.
31 *
32 * Include File Hierarchy:
33 *
34 * "skdrv1st.h"
35 * "skdrv2nd.h"
36 *
37 ******************************************************************************/
38
39#ifndef lint
40static const char SysKonnectFileId[] =
41 "@(#) $Id: skdim.c,v 1.5 2003/11/28 12:55:40 rroesler Exp $ (C) SysKonnect.";
42#endif
43
44#define __SKADDR_C
45
46#ifdef __cplusplus
47#error C++ is not yet supported.
48extern "C" {
49#endif
50
51/*******************************************************************************
52**
53** Includes
54**
55*******************************************************************************/
56
57#ifndef __INC_SKDRV1ST_H
58#include "h/skdrv1st.h"
59#endif
60
61#ifndef __INC_SKDRV2ND_H
62#include "h/skdrv2nd.h"
63#endif
64
65#include <linux/kernel_stat.h>
66
67/*******************************************************************************
68**
69** Defines
70**
71*******************************************************************************/
72
73/*******************************************************************************
74**
75** Typedefs
76**
77*******************************************************************************/
78
79/*******************************************************************************
80**
81** Local function prototypes
82**
83*******************************************************************************/
84
85static unsigned int GetCurrentSystemLoad(SK_AC *pAC);
86static SK_U64 GetIsrCalls(SK_AC *pAC);
87static SK_BOOL IsIntModEnabled(SK_AC *pAC);
88static void SetCurrIntCtr(SK_AC *pAC);
89static void EnableIntMod(SK_AC *pAC);
90static void DisableIntMod(SK_AC *pAC);
91static void ResizeDimTimerDuration(SK_AC *pAC);
92static void DisplaySelectedModerationType(SK_AC *pAC);
93static void DisplaySelectedModerationMask(SK_AC *pAC);
94static void DisplayDescrRatio(SK_AC *pAC);
95
96/*******************************************************************************
97**
98** Global variables
99**
100*******************************************************************************/
101
102/*******************************************************************************
103**
104** Local variables
105**
106*******************************************************************************/
107
108/*******************************************************************************
109**
110** Global functions
111**
112*******************************************************************************/
113
114/*******************************************************************************
115** Function : SkDimModerate
116** Description : Called in every ISR to check if moderation is to be applied
117** or not for the current number of interrupts
118** Programmer : Ralph Roesler
119** Last Modified: 22-mar-03
120** Returns : void (!)
121** Notes : -
122*******************************************************************************/
123
124void
125SkDimModerate(SK_AC *pAC) {
126 unsigned int CurrSysLoad = 0; /* expressed in percent */
127 unsigned int LoadIncrease = 0; /* expressed in percent */
128 SK_U64 ThresholdInts = 0;
129 SK_U64 IsrCallsPerSec = 0;
130
131#define M_DIMINFO pAC->DynIrqModInfo
132
133 if (!IsIntModEnabled(pAC)) {
134 if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
135 CurrSysLoad = GetCurrentSystemLoad(pAC);
136 if (CurrSysLoad > 75) {
137 /*
138 ** More than 75% total system load! Enable the moderation
139 ** to shield the system against too many interrupts.
140 */
141 EnableIntMod(pAC);
142 } else if (CurrSysLoad > M_DIMINFO.PrevSysLoad) {
143 LoadIncrease = (CurrSysLoad - M_DIMINFO.PrevSysLoad);
144 if (LoadIncrease > ((M_DIMINFO.PrevSysLoad *
145 C_INT_MOD_ENABLE_PERCENTAGE) / 100)) {
146 if (CurrSysLoad > 10) {
147 /*
148 ** More than 50% increase with respect to the
149 ** previous load of the system. Most likely this
150 ** is due to our ISR-proc...
151 */
152 EnableIntMod(pAC);
153 }
154 }
155 } else {
156 /*
157 ** Neither too much system load at all nor too much increase
158 ** with respect to the previous system load. Hence, we can leave
159 ** the ISR-handling like it is without enabling moderation.
160 */
161 }
162 M_DIMINFO.PrevSysLoad = CurrSysLoad;
163 }
164 } else {
165 if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
166 ThresholdInts = ((M_DIMINFO.MaxModIntsPerSec *
167 C_INT_MOD_DISABLE_PERCENTAGE) / 100);
168 IsrCallsPerSec = GetIsrCalls(pAC);
169 if (IsrCallsPerSec <= ThresholdInts) {
170 /*
171 ** The number of interrupts within the last second is
172 ** lower than the disable_percentage of the desried
173 ** maxrate. Therefore we can disable the moderation.
174 */
175 DisableIntMod(pAC);
176 M_DIMINFO.MaxModIntsPerSec =
177 (M_DIMINFO.MaxModIntsPerSecUpperLimit +
178 M_DIMINFO.MaxModIntsPerSecLowerLimit) / 2;
179 } else {
180 /*
181 ** The number of interrupts per sec is the same as expected.
182 ** Evalulate the descriptor-ratio. If it has changed, a resize
183 ** in the moderation timer might be usefull
184 */
185 if (M_DIMINFO.AutoSizing) {
186 ResizeDimTimerDuration(pAC);
187 }
188 }
189 }
190 }
191
192 /*
193 ** Some information to the log...
194 */
195 if (M_DIMINFO.DisplayStats) {
196 DisplaySelectedModerationType(pAC);
197 DisplaySelectedModerationMask(pAC);
198 DisplayDescrRatio(pAC);
199 }
200
201 M_DIMINFO.NbrProcessedDescr = 0;
202 SetCurrIntCtr(pAC);
203}
204
205/*******************************************************************************
206** Function : SkDimStartModerationTimer
207** Description : Starts the audit-timer for the dynamic interrupt moderation
208** Programmer : Ralph Roesler
209** Last Modified: 22-mar-03
210** Returns : void (!)
211** Notes : -
212*******************************************************************************/
213
214void
215SkDimStartModerationTimer(SK_AC *pAC) {
216 SK_EVPARA EventParam; /* Event struct for timer event */
217
218 SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
219 EventParam.Para32[0] = SK_DRV_MODERATION_TIMER;
220 SkTimerStart(pAC, pAC->IoBase, &pAC->DynIrqModInfo.ModTimer,
221 SK_DRV_MODERATION_TIMER_LENGTH,
222 SKGE_DRV, SK_DRV_TIMER, EventParam);
223}
224
225/*******************************************************************************
226** Function : SkDimEnableModerationIfNeeded
227** Description : Either enables or disables moderation
228** Programmer : Ralph Roesler
229** Last Modified: 22-mar-03
230** Returns : void (!)
231** Notes : This function is called when a particular adapter is opened
232** There is no Disable function, because when all interrupts
233** might be disable, the moderation timer has no meaning at all
234******************************************************************************/
235
236void
237SkDimEnableModerationIfNeeded(SK_AC *pAC) {
238
239 if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_STATIC) {
240 EnableIntMod(pAC); /* notification print in this function */
241 } else if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
242 SkDimStartModerationTimer(pAC);
243 if (M_DIMINFO.DisplayStats) {
244 printk("Dynamic moderation has been enabled\n");
245 }
246 } else {
247 if (M_DIMINFO.DisplayStats) {
248 printk("No moderation has been enabled\n");
249 }
250 }
251}
252
253/*******************************************************************************
254** Function : SkDimDisplayModerationSettings
255** Description : Displays the current settings regaring interrupt moderation
256** Programmer : Ralph Roesler
257** Last Modified: 22-mar-03
258** Returns : void (!)
259** Notes : -
260*******************************************************************************/
261
262void
263SkDimDisplayModerationSettings(SK_AC *pAC) {
264 DisplaySelectedModerationType(pAC);
265 DisplaySelectedModerationMask(pAC);
266}
267
268/*******************************************************************************
269**
270** Local functions
271**
272*******************************************************************************/
273
274/*******************************************************************************
275** Function : GetCurrentSystemLoad
276** Description : Retrieves the current system load of the system. This load
277** is evaluated for all processors within the system.
278** Programmer : Ralph Roesler
279** Last Modified: 22-mar-03
280** Returns : unsigned int: load expressed in percentage
281** Notes : The possible range being returned is from 0 up to 100.
282** Whereas 0 means 'no load at all' and 100 'system fully loaded'
283** It is impossible to determine what actually causes the system
284** to be in 100%, but maybe that is due to too much interrupts.
285*******************************************************************************/
286
287static unsigned int
288GetCurrentSystemLoad(SK_AC *pAC) {
289 unsigned long jif = jiffies;
290 unsigned int UserTime = 0;
291 unsigned int SystemTime = 0;
292 unsigned int NiceTime = 0;
293 unsigned int IdleTime = 0;
294 unsigned int TotalTime = 0;
295 unsigned int UsedTime = 0;
296 unsigned int SystemLoad = 0;
297
298 /* unsigned int NbrCpu = 0; */
299
300 /*
301 ** The following lines have been commented out, because
302 ** from kernel 2.5.44 onwards, the kernel-owned structure
303 **
304 ** struct kernel_stat kstat
305 **
306 ** is not marked as an exported symbol in the file
307 **
308 ** kernel/ksyms.c
309 **
310 ** As a consequence, using this driver as KLM is not possible
311 ** and any access of the structure kernel_stat via the
312 ** dedicated macros kstat_cpu(i).cpustat.xxx is to be avoided.
313 **
314 ** The kstat-information might be added again in future
315 ** versions of the 2.5.xx kernel, but for the time being,
316 ** number of interrupts will serve as indication how much
317 ** load we currently have...
318 **
319 ** for (NbrCpu = 0; NbrCpu < num_online_cpus(); NbrCpu++) {
320 ** UserTime = UserTime + kstat_cpu(NbrCpu).cpustat.user;
321 ** NiceTime = NiceTime + kstat_cpu(NbrCpu).cpustat.nice;
322 ** SystemTime = SystemTime + kstat_cpu(NbrCpu).cpustat.system;
323 ** }
324 */
325 SK_U64 ThresholdInts = 0;
326 SK_U64 IsrCallsPerSec = 0;
327
328 ThresholdInts = ((M_DIMINFO.MaxModIntsPerSec *
329 C_INT_MOD_ENABLE_PERCENTAGE) + 100);
330 IsrCallsPerSec = GetIsrCalls(pAC);
331 if (IsrCallsPerSec >= ThresholdInts) {
332 /*
333 ** We do not know how much the real CPU-load is!
334 ** Return 80% as a default in order to activate DIM
335 */
336 SystemLoad = 80;
337 return (SystemLoad);
338 }
339
340 UsedTime = UserTime + NiceTime + SystemTime;
341
342 IdleTime = jif * num_online_cpus() - UsedTime;
343 TotalTime = UsedTime + IdleTime;
344
345 SystemLoad = ( 100 * (UsedTime - M_DIMINFO.PrevUsedTime) ) /
346 (TotalTime - M_DIMINFO.PrevTotalTime);
347
348 if (M_DIMINFO.DisplayStats) {
349 printk("Current system load is: %u\n", SystemLoad);
350 }
351
352 M_DIMINFO.PrevTotalTime = TotalTime;
353 M_DIMINFO.PrevUsedTime = UsedTime;
354
355 return (SystemLoad);
356}
357
358/*******************************************************************************
359** Function : GetIsrCalls
360** Description : Depending on the selected moderation mask, this function will
361** return the number of interrupts handled in the previous time-
362** frame. This evaluated number is based on the current number
363** of interrupts stored in PNMI-context and the previous stored
364** interrupts.
365** Programmer : Ralph Roesler
366** Last Modified: 23-mar-03
367** Returns : int: the number of interrupts being executed in the last
368** timeframe
369** Notes : It makes only sense to call this function, when dynamic
370** interrupt moderation is applied
371*******************************************************************************/
372
373static SK_U64
374GetIsrCalls(SK_AC *pAC) {
375 SK_U64 RxPort0IntDiff = 0;
376 SK_U64 RxPort1IntDiff = 0;
377 SK_U64 TxPort0IntDiff = 0;
378 SK_U64 TxPort1IntDiff = 0;
379
380 if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_TX_ONLY) {
381 if (pAC->GIni.GIMacsFound == 2) {
382 TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts -
383 pAC->DynIrqModInfo.PrevPort1TxIntrCts;
384 }
385 TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts -
386 pAC->DynIrqModInfo.PrevPort0TxIntrCts;
387 } else if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_RX_ONLY) {
388 if (pAC->GIni.GIMacsFound == 2) {
389 RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts -
390 pAC->DynIrqModInfo.PrevPort1RxIntrCts;
391 }
392 RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts -
393 pAC->DynIrqModInfo.PrevPort0RxIntrCts;
394 } else {
395 if (pAC->GIni.GIMacsFound == 2) {
396 RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts -
397 pAC->DynIrqModInfo.PrevPort1RxIntrCts;
398 TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts -
399 pAC->DynIrqModInfo.PrevPort1TxIntrCts;
400 }
401 RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts -
402 pAC->DynIrqModInfo.PrevPort0RxIntrCts;
403 TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts -
404 pAC->DynIrqModInfo.PrevPort0TxIntrCts;
405 }
406
407 return (RxPort0IntDiff + RxPort1IntDiff + TxPort0IntDiff + TxPort1IntDiff);
408}
409
410/*******************************************************************************
411** Function : GetRxCalls
412** Description : This function will return the number of times a receive inter-
413** rupt was processed. This is needed to evaluate any resizing
414** factor.
415** Programmer : Ralph Roesler
416** Last Modified: 23-mar-03
417** Returns : SK_U64: the number of RX-ints being processed
418** Notes : It makes only sense to call this function, when dynamic
419** interrupt moderation is applied
420*******************************************************************************/
421
422static SK_U64
423GetRxCalls(SK_AC *pAC) {
424 SK_U64 RxPort0IntDiff = 0;
425 SK_U64 RxPort1IntDiff = 0;
426
427 if (pAC->GIni.GIMacsFound == 2) {
428 RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts -
429 pAC->DynIrqModInfo.PrevPort1RxIntrCts;
430 }
431 RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts -
432 pAC->DynIrqModInfo.PrevPort0RxIntrCts;
433
434 return (RxPort0IntDiff + RxPort1IntDiff);
435}
436
437/*******************************************************************************
438** Function : SetCurrIntCtr
439** Description : Will store the current number orf occured interrupts in the
440** adapter context. This is needed to evaluated the number of
441** interrupts within a current timeframe.
442** Programmer : Ralph Roesler
443** Last Modified: 23-mar-03
444** Returns : void (!)
445** Notes : -
446*******************************************************************************/
447
448static void
449SetCurrIntCtr(SK_AC *pAC) {
450 if (pAC->GIni.GIMacsFound == 2) {
451 pAC->DynIrqModInfo.PrevPort1RxIntrCts = pAC->Pnmi.Port[1].RxIntrCts;
452 pAC->DynIrqModInfo.PrevPort1TxIntrCts = pAC->Pnmi.Port[1].TxIntrCts;
453 }
454 pAC->DynIrqModInfo.PrevPort0RxIntrCts = pAC->Pnmi.Port[0].RxIntrCts;
455 pAC->DynIrqModInfo.PrevPort0TxIntrCts = pAC->Pnmi.Port[0].TxIntrCts;
456}
457
458/*******************************************************************************
459** Function : IsIntModEnabled()
460** Description : Retrieves the current value of the interrupts moderation
461** command register. Its content determines whether any
462** moderation is running or not.
463** Programmer : Ralph Roesler
464** Last Modified: 23-mar-03
465** Returns : SK_TRUE : if mod timer running
466** SK_FALSE : if no moderation is being performed
467** Notes : -
468*******************************************************************************/
469
470static SK_BOOL
471IsIntModEnabled(SK_AC *pAC) {
472 unsigned long CtrCmd;
473
474 SK_IN32(pAC->IoBase, B2_IRQM_CTRL, &CtrCmd);
475 if ((CtrCmd & TIM_START) == TIM_START) {
476 return SK_TRUE;
477 } else {
478 return SK_FALSE;
479 }
480}
481
482/*******************************************************************************
483** Function : EnableIntMod()
484** Description : Enables the interrupt moderation using the values stored in
485** in the pAC->DynIntMod data structure
486** Programmer : Ralph Roesler
487** Last Modified: 22-mar-03
488** Returns : -
489** Notes : -
490*******************************************************************************/
491
492static void
493EnableIntMod(SK_AC *pAC) {
494 unsigned long ModBase;
495
496 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
497 ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec;
498 } else {
499 ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec;
500 }
501
502 SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
503 SK_OUT32(pAC->IoBase, B2_IRQM_MSK, pAC->DynIrqModInfo.MaskIrqModeration);
504 SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START);
505 if (M_DIMINFO.DisplayStats) {
506 printk("Enabled interrupt moderation (%i ints/sec)\n",
507 M_DIMINFO.MaxModIntsPerSec);
508 }
509}
510
511/*******************************************************************************
512** Function : DisableIntMod()
513** Description : Disbles the interrupt moderation independent of what inter-
514** rupts are running or not
515** Programmer : Ralph Roesler
516** Last Modified: 23-mar-03
517** Returns : -
518** Notes : -
519*******************************************************************************/
520
521static void
522DisableIntMod(SK_AC *pAC) {
523
524 SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_STOP);
525 if (M_DIMINFO.DisplayStats) {
526 printk("Disabled interrupt moderation\n");
527 }
528}
529
530/*******************************************************************************
531** Function : ResizeDimTimerDuration();
532** Description : Checks the current used descriptor ratio and resizes the
533** duration timer (longer/smaller) if possible.
534** Programmer : Ralph Roesler
535** Last Modified: 23-mar-03
536** Returns : -
537** Notes : There are both maximum and minimum timer duration value.
538** This function assumes that interrupt moderation is already
539** enabled!
540*******************************************************************************/
541
542static void
543ResizeDimTimerDuration(SK_AC *pAC) {
544 SK_BOOL IncreaseTimerDuration;
545 int TotalMaxNbrDescr;
546 int UsedDescrRatio;
547 int RatioDiffAbs;
548 int RatioDiffRel;
549 int NewMaxModIntsPerSec;
550 int ModAdjValue;
551 long ModBase;
552
553 /*
554 ** Check first if we are allowed to perform any modification
555 */
556 if (IsIntModEnabled(pAC)) {
557 if (M_DIMINFO.IntModTypeSelect != C_INT_MOD_DYNAMIC) {
558 return;
559 } else {
560 if (M_DIMINFO.ModJustEnabled) {
561 M_DIMINFO.ModJustEnabled = SK_FALSE;
562 return;
563 }
564 }
565 }
566
567 /*
568 ** If we got until here, we have to evaluate the amount of the
569 ** descriptor ratio change...
570 */
571 TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC);
572 UsedDescrRatio = (M_DIMINFO.NbrProcessedDescr * 100) / TotalMaxNbrDescr;
573
574 if (UsedDescrRatio > M_DIMINFO.PrevUsedDescrRatio) {
575 RatioDiffAbs = (UsedDescrRatio - M_DIMINFO.PrevUsedDescrRatio);
576 RatioDiffRel = (RatioDiffAbs * 100) / UsedDescrRatio;
577 M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
578 IncreaseTimerDuration = SK_FALSE; /* in other words: DECREASE */
579 } else if (UsedDescrRatio < M_DIMINFO.PrevUsedDescrRatio) {
580 RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio);
581 RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio;
582 M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
583 IncreaseTimerDuration = SK_TRUE; /* in other words: INCREASE */
584 } else {
585 RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio);
586 RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio;
587 M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
588 IncreaseTimerDuration = SK_TRUE; /* in other words: INCREASE */
589 }
590
591 /*
592 ** Now we can determine the change in percent
593 */
594 if ((RatioDiffRel >= 0) && (RatioDiffRel <= 5) ) {
595 ModAdjValue = 1; /* 1% change - maybe some other value in future */
596 } else if ((RatioDiffRel > 5) && (RatioDiffRel <= 10) ) {
597 ModAdjValue = 1; /* 1% change - maybe some other value in future */
598 } else if ((RatioDiffRel > 10) && (RatioDiffRel <= 15) ) {
599 ModAdjValue = 1; /* 1% change - maybe some other value in future */
600 } else {
601 ModAdjValue = 1; /* 1% change - maybe some other value in future */
602 }
603
604 if (IncreaseTimerDuration) {
605 NewMaxModIntsPerSec = M_DIMINFO.MaxModIntsPerSec +
606 (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100;
607 } else {
608 NewMaxModIntsPerSec = M_DIMINFO.MaxModIntsPerSec -
609 (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100;
610 }
611
612 /*
613 ** Check if we exceed boundaries...
614 */
615 if ( (NewMaxModIntsPerSec > M_DIMINFO.MaxModIntsPerSecUpperLimit) ||
616 (NewMaxModIntsPerSec < M_DIMINFO.MaxModIntsPerSecLowerLimit)) {
617 if (M_DIMINFO.DisplayStats) {
618 printk("Cannot change ModTim from %i to %i ints/sec\n",
619 M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec);
620 }
621 return;
622 } else {
623 if (M_DIMINFO.DisplayStats) {
624 printk("Resized ModTim from %i to %i ints/sec\n",
625 M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec);
626 }
627 }
628
629 M_DIMINFO.MaxModIntsPerSec = NewMaxModIntsPerSec;
630
631 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
632 ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec;
633 } else {
634 ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec;
635 }
636
637 /*
638 ** We do not need to touch any other registers
639 */
640 SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
641}
642
643/*******************************************************************************
644** Function : DisplaySelectedModerationType()
645** Description : Displays what type of moderation we have
646** Programmer : Ralph Roesler
647** Last Modified: 23-mar-03
648** Returns : void!
649** Notes : -
650*******************************************************************************/
651
652static void
653DisplaySelectedModerationType(SK_AC *pAC) {
654
655 if (pAC->DynIrqModInfo.DisplayStats) {
656 if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC) {
657 printk("Static int moderation runs with %i INTS/sec\n",
658 pAC->DynIrqModInfo.MaxModIntsPerSec);
659 } else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
660 if (IsIntModEnabled(pAC)) {
661 printk("Dynamic int moderation runs with %i INTS/sec\n",
662 pAC->DynIrqModInfo.MaxModIntsPerSec);
663 } else {
664 printk("Dynamic int moderation currently not applied\n");
665 }
666 } else {
667 printk("No interrupt moderation selected!\n");
668 }
669 }
670}
671
672/*******************************************************************************
673** Function : DisplaySelectedModerationMask()
674** Description : Displays what interrupts are moderated
675** Programmer : Ralph Roesler
676** Last Modified: 23-mar-03
677** Returns : void!
678** Notes : -
679*******************************************************************************/
680
681static void
682DisplaySelectedModerationMask(SK_AC *pAC) {
683
684 if (pAC->DynIrqModInfo.DisplayStats) {
685 if (pAC->DynIrqModInfo.IntModTypeSelect != C_INT_MOD_NONE) {
686 switch (pAC->DynIrqModInfo.MaskIrqModeration) {
687 case IRQ_MASK_TX_ONLY:
688 printk("Only Tx-interrupts are moderated\n");
689 break;
690 case IRQ_MASK_RX_ONLY:
691 printk("Only Rx-interrupts are moderated\n");
692 break;
693 case IRQ_MASK_SP_ONLY:
694 printk("Only special-interrupts are moderated\n");
695 break;
696 case IRQ_MASK_TX_RX:
697 printk("Tx- and Rx-interrupts are moderated\n");
698 break;
699 case IRQ_MASK_SP_RX:
700 printk("Special- and Rx-interrupts are moderated\n");
701 break;
702 case IRQ_MASK_SP_TX:
703 printk("Special- and Tx-interrupts are moderated\n");
704 break;
705 case IRQ_MASK_RX_TX_SP:
706 printk("All Rx-, Tx and special-interrupts are moderated\n");
707 break;
708 default:
709 printk("Don't know what is moderated\n");
710 break;
711 }
712 } else {
713 printk("No specific interrupts masked for moderation\n");
714 }
715 }
716}
717
718/*******************************************************************************
719** Function : DisplayDescrRatio
720** Description : Like the name states...
721** Programmer : Ralph Roesler
722** Last Modified: 23-mar-03
723** Returns : void!
724** Notes : -
725*******************************************************************************/
726
727static void
728DisplayDescrRatio(SK_AC *pAC) {
729 int TotalMaxNbrDescr = 0;
730
731 if (pAC->DynIrqModInfo.DisplayStats) {
732 TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC);
733 printk("Ratio descriptors: %i/%i\n",
734 M_DIMINFO.NbrProcessedDescr, TotalMaxNbrDescr);
735 }
736}
737
738/*******************************************************************************
739**
740** End of file
741**
742*******************************************************************************/
diff --git a/drivers/net/sk98lin/skethtool.c b/drivers/net/sk98lin/skethtool.c
new file mode 100644
index 000000000000..fb639959292b
--- /dev/null
+++ b/drivers/net/sk98lin/skethtool.c
@@ -0,0 +1,552 @@
1/******************************************************************************
2 *
3 * Name: skethtool.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.7 $
6 * Date: $Date: 2004/09/29 13:32:07 $
7 * Purpose: All functions regarding ethtool handling
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2004 Marvell.
15 *
16 * Driver for Marvell Yukon/2 chipset and SysKonnect Gigabit Ethernet
17 * Server Adapters.
18 *
19 * Author: Ralph Roesler (rroesler@syskonnect.de)
20 * Mirko Lindner (mlindner@syskonnect.de)
21 *
22 * Address all question to: linux@syskonnect.de
23 *
24 * The technical manual for the adapters is available from SysKonnect's
25 * web pages: www.syskonnect.com
26 *
27 * This program is free software; you can redistribute it and/or modify
28 * it under the terms of the GNU General Public License as published by
29 * the Free Software Foundation; either version 2 of the License, or
30 * (at your option) any later version.
31 *
32 * The information in this file is provided "AS IS" without warranty.
33 *
34 *****************************************************************************/
35
36#include "h/skdrv1st.h"
37#include "h/skdrv2nd.h"
38#include "h/skversion.h"
39
40#include <linux/ethtool.h>
41#include <linux/timer.h>
42#include <linux/delay.h>
43
44/******************************************************************************
45 *
46 * Defines
47 *
48 *****************************************************************************/
49
50#define SUPP_COPPER_ALL (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \
51 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
52 SUPPORTED_1000baseT_Half| SUPPORTED_1000baseT_Full| \
53 SUPPORTED_TP)
54
55#define ADV_COPPER_ALL (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \
56 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \
57 ADVERTISED_1000baseT_Half| ADVERTISED_1000baseT_Full| \
58 ADVERTISED_TP)
59
60#define SUPP_FIBRE_ALL (SUPPORTED_1000baseT_Full | \
61 SUPPORTED_FIBRE | \
62 SUPPORTED_Autoneg)
63
64#define ADV_FIBRE_ALL (ADVERTISED_1000baseT_Full | \
65 ADVERTISED_FIBRE | \
66 ADVERTISED_Autoneg)
67
68
69/******************************************************************************
70 *
71 * Local Functions
72 *
73 *****************************************************************************/
74
75/*****************************************************************************
76 *
77 * getSettings - retrieves the current settings of the selected adapter
78 *
79 * Description:
80 * The current configuration of the selected adapter is returned.
81 * This configuration involves a)speed, b)duplex and c)autoneg plus
82 * a number of other variables.
83 *
84 * Returns: always 0
85 *
86 */
87static int getSettings(struct net_device *dev, struct ethtool_cmd *ecmd)
88{
89 const DEV_NET *pNet = netdev_priv(dev);
90 int port = pNet->PortNr;
91 const SK_AC *pAC = pNet->pAC;
92 const SK_GEPORT *pPort = &pAC->GIni.GP[port];
93
94 static int DuplexAutoNegConfMap[9][3]= {
95 { -1 , -1 , -1 },
96 { 0 , -1 , -1 },
97 { SK_LMODE_HALF , DUPLEX_HALF, AUTONEG_DISABLE },
98 { SK_LMODE_FULL , DUPLEX_FULL, AUTONEG_DISABLE },
99 { SK_LMODE_AUTOHALF , DUPLEX_HALF, AUTONEG_ENABLE },
100 { SK_LMODE_AUTOFULL , DUPLEX_FULL, AUTONEG_ENABLE },
101 { SK_LMODE_AUTOBOTH , DUPLEX_FULL, AUTONEG_ENABLE },
102 { SK_LMODE_AUTOSENSE , -1 , -1 },
103 { SK_LMODE_INDETERMINATED, -1 , -1 }
104 };
105 static int SpeedConfMap[6][2] = {
106 { 0 , -1 },
107 { SK_LSPEED_AUTO , -1 },
108 { SK_LSPEED_10MBPS , SPEED_10 },
109 { SK_LSPEED_100MBPS , SPEED_100 },
110 { SK_LSPEED_1000MBPS , SPEED_1000 },
111 { SK_LSPEED_INDETERMINATED, -1 }
112 };
113 static int AdvSpeedMap[6][2] = {
114 { 0 , -1 },
115 { SK_LSPEED_AUTO , -1 },
116 { SK_LSPEED_10MBPS , ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full },
117 { SK_LSPEED_100MBPS , ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full },
118 { SK_LSPEED_1000MBPS , ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full},
119 { SK_LSPEED_INDETERMINATED, -1 }
120 };
121
122 ecmd->phy_address = port;
123 ecmd->speed = SpeedConfMap[pPort->PLinkSpeedUsed][1];
124 ecmd->duplex = DuplexAutoNegConfMap[pPort->PLinkModeStatus][1];
125 ecmd->autoneg = DuplexAutoNegConfMap[pPort->PLinkModeStatus][2];
126 ecmd->transceiver = XCVR_INTERNAL;
127
128 if (pAC->GIni.GICopperType) {
129 ecmd->port = PORT_TP;
130 ecmd->supported = (SUPP_COPPER_ALL|SUPPORTED_Autoneg);
131 if (pAC->GIni.GIGenesis) {
132 ecmd->supported &= ~(SUPPORTED_10baseT_Half);
133 ecmd->supported &= ~(SUPPORTED_10baseT_Full);
134 ecmd->supported &= ~(SUPPORTED_100baseT_Half);
135 ecmd->supported &= ~(SUPPORTED_100baseT_Full);
136 } else {
137 if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
138 ecmd->supported &= ~(SUPPORTED_1000baseT_Half);
139 }
140#ifdef CHIP_ID_YUKON_FE
141 if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
142 ecmd->supported &= ~(SUPPORTED_1000baseT_Half);
143 ecmd->supported &= ~(SUPPORTED_1000baseT_Full);
144 }
145#endif
146 }
147 if (pAC->GIni.GP[0].PLinkSpeed != SK_LSPEED_AUTO) {
148 ecmd->advertising = AdvSpeedMap[pPort->PLinkSpeed][1];
149 if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
150 ecmd->advertising &= ~(SUPPORTED_1000baseT_Half);
151 }
152 } else {
153 ecmd->advertising = ecmd->supported;
154 }
155
156 if (ecmd->autoneg == AUTONEG_ENABLE)
157 ecmd->advertising |= ADVERTISED_Autoneg;
158 } else {
159 ecmd->port = PORT_FIBRE;
160 ecmd->supported = SUPP_FIBRE_ALL;
161 ecmd->advertising = ADV_FIBRE_ALL;
162 }
163 return 0;
164}
165
166/*
167 * MIB infrastructure uses instance value starting at 1
168 * based on board and port.
169 */
170static inline u32 pnmiInstance(const DEV_NET *pNet)
171{
172 return 1 + (pNet->pAC->RlmtNets == 2) + pNet->PortNr;
173}
174
175/*****************************************************************************
176 *
177 * setSettings - configures the settings of a selected adapter
178 *
179 * Description:
180 * Possible settings that may be altered are a)speed, b)duplex or
181 * c)autonegotiation.
182 *
183 * Returns:
184 * 0: everything fine, no error
185 * <0: the return value is the error code of the failure
186 */
187static int setSettings(struct net_device *dev, struct ethtool_cmd *ecmd)
188{
189 DEV_NET *pNet = netdev_priv(dev);
190 SK_AC *pAC = pNet->pAC;
191 u32 instance;
192 char buf[4];
193 int len = 1;
194
195 if (ecmd->speed != SPEED_10 && ecmd->speed != SPEED_100
196 && ecmd->speed != SPEED_1000)
197 return -EINVAL;
198
199 if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
200 return -EINVAL;
201
202 if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE)
203 return -EINVAL;
204
205 if (ecmd->autoneg == AUTONEG_DISABLE)
206 *buf = (ecmd->duplex == DUPLEX_FULL)
207 ? SK_LMODE_FULL : SK_LMODE_HALF;
208 else
209 *buf = (ecmd->duplex == DUPLEX_FULL)
210 ? SK_LMODE_AUTOFULL : SK_LMODE_AUTOHALF;
211
212 instance = pnmiInstance(pNet);
213 if (SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_LINK_MODE,
214 &buf, &len, instance, pNet->NetNr) != SK_PNMI_ERR_OK)
215 return -EINVAL;
216
217 switch(ecmd->speed) {
218 case SPEED_1000:
219 *buf = SK_LSPEED_1000MBPS;
220 break;
221 case SPEED_100:
222 *buf = SK_LSPEED_100MBPS;
223 break;
224 case SPEED_10:
225 *buf = SK_LSPEED_10MBPS;
226 }
227
228 if (SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE,
229 &buf, &len, instance, pNet->NetNr) != SK_PNMI_ERR_OK)
230 return -EINVAL;
231
232 return 0;
233}
234
235/*****************************************************************************
236 *
237 * getDriverInfo - returns generic driver and adapter information
238 *
239 * Description:
240 * Generic driver information is returned via this function, such as
241 * the name of the driver, its version and and firmware version.
242 * In addition to this, the location of the selected adapter is
243 * returned as a bus info string (e.g. '01:05.0').
244 *
245 * Returns: N/A
246 *
247 */
248static void getDriverInfo(struct net_device *dev, struct ethtool_drvinfo *info)
249{
250 const DEV_NET *pNet = netdev_priv(dev);
251 const SK_AC *pAC = pNet->pAC;
252 char vers[32];
253
254 snprintf(vers, sizeof(vers)-1, VER_STRING "(v%d.%d)",
255 (pAC->GIni.GIPciHwRev >> 4) & 0xf, pAC->GIni.GIPciHwRev & 0xf);
256
257 strlcpy(info->driver, DRIVER_FILE_NAME, sizeof(info->driver));
258 strcpy(info->version, vers);
259 strcpy(info->fw_version, "N/A");
260 strlcpy(info->bus_info, pci_name(pAC->PciDev), ETHTOOL_BUSINFO_LEN);
261}
262
263/*
264 * Ethtool statistics support.
265 */
266static const char StringsStats[][ETH_GSTRING_LEN] = {
267 "rx_packets", "tx_packets",
268 "rx_bytes", "tx_bytes",
269 "rx_errors", "tx_errors",
270 "rx_dropped", "tx_dropped",
271 "multicasts", "collisions",
272 "rx_length_errors", "rx_buffer_overflow_errors",
273 "rx_crc_errors", "rx_frame_errors",
274 "rx_too_short_errors", "rx_too_long_errors",
275 "rx_carrier_extension_errors", "rx_symbol_errors",
276 "rx_llc_mac_size_errors", "rx_carrier_errors",
277 "rx_jabber_errors", "rx_missed_errors",
278 "tx_abort_collision_errors", "tx_carrier_errors",
279 "tx_buffer_underrun_errors", "tx_heartbeat_errors",
280 "tx_window_errors",
281};
282
283static int getStatsCount(struct net_device *dev)
284{
285 return ARRAY_SIZE(StringsStats);
286}
287
288static void getStrings(struct net_device *dev, u32 stringset, u8 *data)
289{
290 switch(stringset) {
291 case ETH_SS_STATS:
292 memcpy(data, *StringsStats, sizeof(StringsStats));
293 break;
294 }
295}
296
297static void getEthtoolStats(struct net_device *dev,
298 struct ethtool_stats *stats, u64 *data)
299{
300 const DEV_NET *pNet = netdev_priv(dev);
301 const SK_AC *pAC = pNet->pAC;
302 const SK_PNMI_STRUCT_DATA *pPnmiStruct = &pAC->PnmiStruct;
303
304 *data++ = pPnmiStruct->Stat[0].StatRxOkCts;
305 *data++ = pPnmiStruct->Stat[0].StatTxOkCts;
306 *data++ = pPnmiStruct->Stat[0].StatRxOctetsOkCts;
307 *data++ = pPnmiStruct->Stat[0].StatTxOctetsOkCts;
308 *data++ = pPnmiStruct->InErrorsCts;
309 *data++ = pPnmiStruct->Stat[0].StatTxSingleCollisionCts;
310 *data++ = pPnmiStruct->RxNoBufCts;
311 *data++ = pPnmiStruct->TxNoBufCts;
312 *data++ = pPnmiStruct->Stat[0].StatRxMulticastOkCts;
313 *data++ = pPnmiStruct->Stat[0].StatTxSingleCollisionCts;
314 *data++ = pPnmiStruct->Stat[0].StatRxRuntCts;
315 *data++ = pPnmiStruct->Stat[0].StatRxFifoOverflowCts;
316 *data++ = pPnmiStruct->Stat[0].StatRxFcsCts;
317 *data++ = pPnmiStruct->Stat[0].StatRxFramingCts;
318 *data++ = pPnmiStruct->Stat[0].StatRxShortsCts;
319 *data++ = pPnmiStruct->Stat[0].StatRxTooLongCts;
320 *data++ = pPnmiStruct->Stat[0].StatRxCextCts;
321 *data++ = pPnmiStruct->Stat[0].StatRxSymbolCts;
322 *data++ = pPnmiStruct->Stat[0].StatRxIRLengthCts;
323 *data++ = pPnmiStruct->Stat[0].StatRxCarrierCts;
324 *data++ = pPnmiStruct->Stat[0].StatRxJabberCts;
325 *data++ = pPnmiStruct->Stat[0].StatRxMissedCts;
326 *data++ = pAC->stats.tx_aborted_errors;
327 *data++ = pPnmiStruct->Stat[0].StatTxCarrierCts;
328 *data++ = pPnmiStruct->Stat[0].StatTxFifoUnderrunCts;
329 *data++ = pPnmiStruct->Stat[0].StatTxCarrierCts;
330 *data++ = pAC->stats.tx_window_errors;
331}
332
333
334/*****************************************************************************
335 *
336 * toggleLeds - Changes the LED state of an adapter
337 *
338 * Description:
339 * This function changes the current state of all LEDs of an adapter so
340 * that it can be located by a user.
341 *
342 * Returns: N/A
343 *
344 */
345static void toggleLeds(DEV_NET *pNet, int on)
346{
347 SK_AC *pAC = pNet->pAC;
348 int port = pNet->PortNr;
349 void __iomem *io = pAC->IoBase;
350
351 if (pAC->GIni.GIGenesis) {
352 SK_OUT8(io, MR_ADDR(port,LNK_LED_REG),
353 on ? SK_LNK_ON : SK_LNK_OFF);
354 SkGeYellowLED(pAC, io,
355 on ? (LED_ON >> 1) : (LED_OFF >> 1));
356 SkGeXmitLED(pAC, io, MR_ADDR(port,RX_LED_INI),
357 on ? SK_LED_TST : SK_LED_DIS);
358
359 if (pAC->GIni.GP[port].PhyType == SK_PHY_BCOM)
360 SkXmPhyWrite(pAC, io, port, PHY_BCOM_P_EXT_CTRL,
361 on ? PHY_B_PEC_LED_ON : PHY_B_PEC_LED_OFF);
362 else if (pAC->GIni.GP[port].PhyType == SK_PHY_LONE)
363 SkXmPhyWrite(pAC, io, port, PHY_LONE_LED_CFG,
364 on ? 0x0800 : PHY_L_LC_LEDT);
365 else
366 SkGeXmitLED(pAC, io, MR_ADDR(port,TX_LED_INI),
367 on ? SK_LED_TST : SK_LED_DIS);
368 } else {
369 const u16 YukLedOn = (PHY_M_LED_MO_DUP(MO_LED_ON) |
370 PHY_M_LED_MO_10(MO_LED_ON) |
371 PHY_M_LED_MO_100(MO_LED_ON) |
372 PHY_M_LED_MO_1000(MO_LED_ON) |
373 PHY_M_LED_MO_RX(MO_LED_ON));
374 const u16 YukLedOff = (PHY_M_LED_MO_DUP(MO_LED_OFF) |
375 PHY_M_LED_MO_10(MO_LED_OFF) |
376 PHY_M_LED_MO_100(MO_LED_OFF) |
377 PHY_M_LED_MO_1000(MO_LED_OFF) |
378 PHY_M_LED_MO_RX(MO_LED_OFF));
379
380
381 SkGmPhyWrite(pAC,io,port,PHY_MARV_LED_CTRL,0);
382 SkGmPhyWrite(pAC,io,port,PHY_MARV_LED_OVER,
383 on ? YukLedOn : YukLedOff);
384 }
385}
386
387/*****************************************************************************
388 *
389 * skGeBlinkTimer - Changes the LED state of an adapter
390 *
391 * Description:
392 * This function changes the current state of all LEDs of an adapter so
393 * that it can be located by a user. If the requested time interval for
394 * this test has elapsed, this function cleans up everything that was
395 * temporarily setup during the locate NIC test. This involves of course
396 * also closing or opening any adapter so that the initial board state
397 * is recovered.
398 *
399 * Returns: N/A
400 *
401 */
402void SkGeBlinkTimer(unsigned long data)
403{
404 struct net_device *dev = (struct net_device *) data;
405 DEV_NET *pNet = netdev_priv(dev);
406 SK_AC *pAC = pNet->pAC;
407
408 toggleLeds(pNet, pAC->LedsOn);
409
410 pAC->LedsOn = !pAC->LedsOn;
411 mod_timer(&pAC->BlinkTimer, jiffies + HZ/4);
412}
413
414/*****************************************************************************
415 *
416 * locateDevice - start the locate NIC feature of the elected adapter
417 *
418 * Description:
419 * This function is used if the user want to locate a particular NIC.
420 * All LEDs are regularly switched on and off, so the NIC can easily
421 * be identified.
422 *
423 * Returns:
424 * ==0: everything fine, no error, locateNIC test was started
425 * !=0: one locateNIC test runs already
426 *
427 */
428static int locateDevice(struct net_device *dev, u32 data)
429{
430 DEV_NET *pNet = netdev_priv(dev);
431 SK_AC *pAC = pNet->pAC;
432
433 if(!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
434 data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
435
436 /* start blinking */
437 pAC->LedsOn = 0;
438 mod_timer(&pAC->BlinkTimer, jiffies);
439 msleep_interruptible(data * 1000);
440 del_timer_sync(&pAC->BlinkTimer);
441 toggleLeds(pNet, 0);
442
443 return 0;
444}
445
446/*****************************************************************************
447 *
448 * getPauseParams - retrieves the pause parameters
449 *
450 * Description:
451 * All current pause parameters of a selected adapter are placed
452 * in the passed ethtool_pauseparam structure and are returned.
453 *
454 * Returns: N/A
455 *
456 */
457static void getPauseParams(struct net_device *dev, struct ethtool_pauseparam *epause)
458{
459 DEV_NET *pNet = netdev_priv(dev);
460 SK_AC *pAC = pNet->pAC;
461 SK_GEPORT *pPort = &pAC->GIni.GP[pNet->PortNr];
462
463 epause->rx_pause = (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC) ||
464 (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM);
465
466 epause->tx_pause = epause->rx_pause || (pPort->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND);
467 epause->autoneg = epause->rx_pause || epause->tx_pause;
468}
469
470/*****************************************************************************
471 *
472 * setPauseParams - configures the pause parameters of an adapter
473 *
474 * Description:
475 * This function sets the Rx or Tx pause parameters
476 *
477 * Returns:
478 * ==0: everything fine, no error
479 * !=0: the return value is the error code of the failure
480 */
481static int setPauseParams(struct net_device *dev , struct ethtool_pauseparam *epause)
482{
483 DEV_NET *pNet = netdev_priv(dev);
484 SK_AC *pAC = pNet->pAC;
485 SK_GEPORT *pPort = &pAC->GIni.GP[pNet->PortNr];
486 u32 instance = pnmiInstance(pNet);
487 struct ethtool_pauseparam old;
488 u8 oldspeed = pPort->PLinkSpeedUsed;
489 char buf[4];
490 int len = 1;
491 int ret;
492
493 /*
494 ** we have to determine the current settings to see if
495 ** the operator requested any modification of the flow
496 ** control parameters...
497 */
498 getPauseParams(dev, &old);
499
500 /*
501 ** perform modifications regarding the changes
502 ** requested by the operator
503 */
504 if (epause->autoneg != old.autoneg)
505 *buf = epause->autoneg ? SK_FLOW_MODE_NONE : SK_FLOW_MODE_SYMMETRIC;
506 else {
507 if (epause->rx_pause && epause->tx_pause)
508 *buf = SK_FLOW_MODE_SYMMETRIC;
509 else if (epause->rx_pause && !epause->tx_pause)
510 *buf = SK_FLOW_MODE_SYM_OR_REM;
511 else if (!epause->rx_pause && epause->tx_pause)
512 *buf = SK_FLOW_MODE_LOC_SEND;
513 else
514 *buf = SK_FLOW_MODE_NONE;
515 }
516
517 ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_FLOWCTRL_MODE,
518 &buf, &len, instance, pNet->NetNr);
519
520 if (ret != SK_PNMI_ERR_OK) {
521 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL,
522 ("ethtool (sk98lin): error changing rx/tx pause (%i)\n", ret));
523 goto err;
524 }
525
526 /*
527 ** It may be that autoneg has been disabled! Therefore
528 ** set the speed to the previously used value...
529 */
530 if (!epause->autoneg) {
531 len = 1;
532 ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE,
533 &oldspeed, &len, instance, pNet->NetNr);
534 if (ret != SK_PNMI_ERR_OK)
535 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL,
536 ("ethtool (sk98lin): error setting speed (%i)\n", ret));
537 }
538 err:
539 return ret ? -EIO : 0;
540}
541
542struct ethtool_ops SkGeEthtoolOps = {
543 .get_settings = getSettings,
544 .set_settings = setSettings,
545 .get_drvinfo = getDriverInfo,
546 .get_strings = getStrings,
547 .get_stats_count = getStatsCount,
548 .get_ethtool_stats = getEthtoolStats,
549 .phys_id = locateDevice,
550 .get_pauseparam = getPauseParams,
551 .set_pauseparam = setPauseParams,
552};
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
new file mode 100644
index 000000000000..05b827f79f54
--- /dev/null
+++ b/drivers/net/sk98lin/skge.c
@@ -0,0 +1,5186 @@
1/******************************************************************************
2 *
3 * Name: skge.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.45 $
6 * Date: $Date: 2004/02/12 14:41:02 $
7 * Purpose: The main driver source module
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * Driver for Marvell Yukon chipset and SysKonnect Gigabit Ethernet
17 * Server Adapters.
18 *
19 * Created 10-Feb-1999, based on Linux' acenic.c, 3c59x.c and
20 * SysKonnects GEnesis Solaris driver
21 * Author: Christoph Goos (cgoos@syskonnect.de)
22 * Mirko Lindner (mlindner@syskonnect.de)
23 *
24 * Address all question to: linux@syskonnect.de
25 *
26 * The technical manual for the adapters is available from SysKonnect's
27 * web pages: www.syskonnect.com
28 * Goto "Support" and search Knowledge Base for "manual".
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * The information in this file is provided "AS IS" without warranty.
36 *
37 ******************************************************************************/
38
39/******************************************************************************
40 *
41 * Possible compiler options (#define xxx / -Dxxx):
42 *
43 * debugging can be enable by changing SK_DEBUG_CHKMOD and
44 * SK_DEBUG_CHKCAT in makefile (described there).
45 *
46 ******************************************************************************/
47
48/******************************************************************************
49 *
50 * Description:
51 *
52 * This is the main module of the Linux GE driver.
53 *
54 * All source files except skge.c, skdrv1st.h, skdrv2nd.h and sktypes.h
55 * are part of SysKonnect's COMMON MODULES for the SK-98xx adapters.
56 * Those are used for drivers on multiple OS', so some thing may seem
57 * unnecessary complicated on Linux. Please do not try to 'clean up'
58 * them without VERY good reasons, because this will make it more
59 * difficult to keep the Linux driver in synchronisation with the
60 * other versions.
61 *
62 * Include file hierarchy:
63 *
64 * <linux/module.h>
65 *
66 * "h/skdrv1st.h"
67 * <linux/types.h>
68 * <linux/kernel.h>
69 * <linux/string.h>
70 * <linux/errno.h>
71 * <linux/ioport.h>
72 * <linux/slab.h>
73 * <linux/interrupt.h>
74 * <linux/pci.h>
75 * <linux/bitops.h>
76 * <asm/byteorder.h>
77 * <asm/io.h>
78 * <linux/netdevice.h>
79 * <linux/etherdevice.h>
80 * <linux/skbuff.h>
81 * those three depending on kernel version used:
82 * <linux/bios32.h>
83 * <linux/init.h>
84 * <asm/uaccess.h>
85 * <net/checksum.h>
86 *
87 * "h/skerror.h"
88 * "h/skdebug.h"
89 * "h/sktypes.h"
90 * "h/lm80.h"
91 * "h/xmac_ii.h"
92 *
93 * "h/skdrv2nd.h"
94 * "h/skqueue.h"
95 * "h/skgehwt.h"
96 * "h/sktimer.h"
97 * "h/ski2c.h"
98 * "h/skgepnmi.h"
99 * "h/skvpd.h"
100 * "h/skgehw.h"
101 * "h/skgeinit.h"
102 * "h/skaddr.h"
103 * "h/skgesirq.h"
104 * "h/skcsum.h"
105 * "h/skrlmt.h"
106 *
107 ******************************************************************************/
108
109#include "h/skversion.h"
110
111#include <linux/module.h>
112#include <linux/moduleparam.h>
113#include <linux/init.h>
114#include <linux/proc_fs.h>
115
116#include "h/skdrv1st.h"
117#include "h/skdrv2nd.h"
118
119/*******************************************************************************
120 *
121 * Defines
122 *
123 ******************************************************************************/
124
125/* for debuging on x86 only */
126/* #define BREAKPOINT() asm(" int $3"); */
127
128/* use the transmit hw checksum driver functionality */
129#define USE_SK_TX_CHECKSUM
130
131/* use the receive hw checksum driver functionality */
132#define USE_SK_RX_CHECKSUM
133
134/* use the scatter-gather functionality with sendfile() */
135#define SK_ZEROCOPY
136
137/* use of a transmit complete interrupt */
138#define USE_TX_COMPLETE
139
140/*
141 * threshold for copying small receive frames
142 * set to 0 to avoid copying, set to 9001 to copy all frames
143 */
144#define SK_COPY_THRESHOLD 50
145
146/* number of adapters that can be configured via command line params */
147#define SK_MAX_CARD_PARAM 16
148
149
150
151/*
152 * use those defines for a compile-in version of the driver instead
153 * of command line parameters
154 */
155// #define LINK_SPEED_A {"Auto", }
156// #define LINK_SPEED_B {"Auto", }
157// #define AUTO_NEG_A {"Sense", }
158// #define AUTO_NEG_B {"Sense", }
159// #define DUP_CAP_A {"Both", }
160// #define DUP_CAP_B {"Both", }
161// #define FLOW_CTRL_A {"SymOrRem", }
162// #define FLOW_CTRL_B {"SymOrRem", }
163// #define ROLE_A {"Auto", }
164// #define ROLE_B {"Auto", }
165// #define PREF_PORT {"A", }
166// #define CON_TYPE {"Auto", }
167// #define RLMT_MODE {"CheckLinkState", }
168
169#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb)
170#define DEV_KFREE_SKB_IRQ(skb) dev_kfree_skb_irq(skb)
171#define DEV_KFREE_SKB_ANY(skb) dev_kfree_skb_any(skb)
172
173
174/* Set blink mode*/
175#define OEM_CONFIG_VALUE ( SK_ACT_LED_BLINK | \
176 SK_DUP_LED_NORMAL | \
177 SK_LED_LINK100_ON)
178
179
180/* Isr return value */
181#define SkIsrRetVar irqreturn_t
182#define SkIsrRetNone IRQ_NONE
183#define SkIsrRetHandled IRQ_HANDLED
184
185
186/*******************************************************************************
187 *
188 * Local Function Prototypes
189 *
190 ******************************************************************************/
191
192static void FreeResources(struct SK_NET_DEVICE *dev);
193static int SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC);
194static SK_BOOL BoardAllocMem(SK_AC *pAC);
195static void BoardFreeMem(SK_AC *pAC);
196static void BoardInitMem(SK_AC *pAC);
197static void SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**, int*, SK_BOOL);
198static SkIsrRetVar SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs);
199static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs);
200static int SkGeOpen(struct SK_NET_DEVICE *dev);
201static int SkGeClose(struct SK_NET_DEVICE *dev);
202static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev);
203static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p);
204static void SkGeSetRxMode(struct SK_NET_DEVICE *dev);
205static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev);
206static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd);
207static void GetConfiguration(SK_AC*);
208static void ProductStr(SK_AC*);
209static int XmitFrame(SK_AC*, TX_PORT*, struct sk_buff*);
210static void FreeTxDescriptors(SK_AC*pAC, TX_PORT*);
211static void FillRxRing(SK_AC*, RX_PORT*);
212static SK_BOOL FillRxDescriptor(SK_AC*, RX_PORT*);
213static void ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL);
214static void ClearAndStartRx(SK_AC*, int);
215static void ClearTxIrq(SK_AC*, int, int);
216static void ClearRxRing(SK_AC*, RX_PORT*);
217static void ClearTxRing(SK_AC*, TX_PORT*);
218static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int new_mtu);
219static void PortReInitBmu(SK_AC*, int);
220static int SkGeIocMib(DEV_NET*, unsigned int, int);
221static int SkGeInitPCI(SK_AC *pAC);
222static void StartDrvCleanupTimer(SK_AC *pAC);
223static void StopDrvCleanupTimer(SK_AC *pAC);
224static int XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*);
225
226#ifdef SK_DIAG_SUPPORT
227static SK_U32 ParseDeviceNbrFromSlotName(const char *SlotName);
228static int SkDrvInitAdapter(SK_AC *pAC, int devNbr);
229static int SkDrvDeInitAdapter(SK_AC *pAC, int devNbr);
230#endif
231
232/*******************************************************************************
233 *
234 * Extern Function Prototypes
235 *
236 ******************************************************************************/
237static const char SKRootName[] = "sk98lin";
238static struct proc_dir_entry *pSkRootDir;
239extern struct file_operations sk_proc_fops;
240
241static inline void SkGeProcCreate(struct net_device *dev)
242{
243 struct proc_dir_entry *pe;
244
245 if (pSkRootDir &&
246 (pe = create_proc_entry(dev->name, S_IRUGO, pSkRootDir))) {
247 pe->proc_fops = &sk_proc_fops;
248 pe->data = dev;
249 pe->owner = THIS_MODULE;
250 }
251}
252
253static inline void SkGeProcRemove(struct net_device *dev)
254{
255 if (pSkRootDir)
256 remove_proc_entry(dev->name, pSkRootDir);
257}
258
259extern void SkDimEnableModerationIfNeeded(SK_AC *pAC);
260extern void SkDimDisplayModerationSettings(SK_AC *pAC);
261extern void SkDimStartModerationTimer(SK_AC *pAC);
262extern void SkDimModerate(SK_AC *pAC);
263extern void SkGeBlinkTimer(unsigned long data);
264
265#ifdef DEBUG
266static void DumpMsg(struct sk_buff*, char*);
267static void DumpData(char*, int);
268static void DumpLong(char*, int);
269#endif
270
271/* global variables *********************************************************/
272static SK_BOOL DoPrintInterfaceChange = SK_TRUE;
273extern struct ethtool_ops SkGeEthtoolOps;
274
275/* local variables **********************************************************/
276static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};
277static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480};
278
279/*****************************************************************************
280 *
281 * SkGeInitPCI - Init the PCI resources
282 *
283 * Description:
284 * This function initialize the PCI resources and IO
285 *
286 * Returns: N/A
287 *
288 */
289int SkGeInitPCI(SK_AC *pAC)
290{
291 struct SK_NET_DEVICE *dev = pAC->dev[0];
292 struct pci_dev *pdev = pAC->PciDev;
293 int retval;
294
295 if (pci_enable_device(pdev) != 0) {
296 return 1;
297 }
298
299 dev->mem_start = pci_resource_start (pdev, 0);
300 pci_set_master(pdev);
301
302 if (pci_request_regions(pdev, pAC->Name) != 0) {
303 retval = 2;
304 goto out_disable;
305 }
306
307#ifdef SK_BIG_ENDIAN
308 /*
309 * On big endian machines, we use the adapter's aibility of
310 * reading the descriptors as big endian.
311 */
312 {
313 SK_U32 our2;
314 SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2);
315 our2 |= PCI_REV_DESC;
316 SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2);
317 }
318#endif
319
320 /*
321 * Remap the regs into kernel space.
322 */
323 pAC->IoBase = ioremap_nocache(dev->mem_start, 0x4000);
324
325 if (!pAC->IoBase){
326 retval = 3;
327 goto out_release;
328 }
329
330 return 0;
331
332 out_release:
333 pci_release_regions(pdev);
334 out_disable:
335 pci_disable_device(pdev);
336 return retval;
337}
338
339
340/*****************************************************************************
341 *
342 * FreeResources - release resources allocated for adapter
343 *
344 * Description:
345 * This function releases the IRQ, unmaps the IO and
346 * frees the desriptor ring.
347 *
348 * Returns: N/A
349 *
350 */
351static void FreeResources(struct SK_NET_DEVICE *dev)
352{
353SK_U32 AllocFlag;
354DEV_NET *pNet;
355SK_AC *pAC;
356
357 pNet = netdev_priv(dev);
358 pAC = pNet->pAC;
359 AllocFlag = pAC->AllocFlag;
360 if (pAC->PciDev) {
361 pci_release_regions(pAC->PciDev);
362 }
363 if (AllocFlag & SK_ALLOC_IRQ) {
364 free_irq(dev->irq, dev);
365 }
366 if (pAC->IoBase) {
367 iounmap(pAC->IoBase);
368 }
369 if (pAC->pDescrMem) {
370 BoardFreeMem(pAC);
371 }
372
373} /* FreeResources */
374
375MODULE_AUTHOR("Mirko Lindner <mlindner@syskonnect.de>");
376MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver");
377MODULE_LICENSE("GPL");
378
379#ifdef LINK_SPEED_A
380static char *Speed_A[SK_MAX_CARD_PARAM] = LINK_SPEED;
381#else
382static char *Speed_A[SK_MAX_CARD_PARAM] = {"", };
383#endif
384
385#ifdef LINK_SPEED_B
386static char *Speed_B[SK_MAX_CARD_PARAM] = LINK_SPEED;
387#else
388static char *Speed_B[SK_MAX_CARD_PARAM] = {"", };
389#endif
390
391#ifdef AUTO_NEG_A
392static char *AutoNeg_A[SK_MAX_CARD_PARAM] = AUTO_NEG_A;
393#else
394static char *AutoNeg_A[SK_MAX_CARD_PARAM] = {"", };
395#endif
396
397#ifdef DUP_CAP_A
398static char *DupCap_A[SK_MAX_CARD_PARAM] = DUP_CAP_A;
399#else
400static char *DupCap_A[SK_MAX_CARD_PARAM] = {"", };
401#endif
402
403#ifdef FLOW_CTRL_A
404static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = FLOW_CTRL_A;
405#else
406static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = {"", };
407#endif
408
409#ifdef ROLE_A
410static char *Role_A[SK_MAX_CARD_PARAM] = ROLE_A;
411#else
412static char *Role_A[SK_MAX_CARD_PARAM] = {"", };
413#endif
414
415#ifdef AUTO_NEG_B
416static char *AutoNeg_B[SK_MAX_CARD_PARAM] = AUTO_NEG_B;
417#else
418static char *AutoNeg_B[SK_MAX_CARD_PARAM] = {"", };
419#endif
420
421#ifdef DUP_CAP_B
422static char *DupCap_B[SK_MAX_CARD_PARAM] = DUP_CAP_B;
423#else
424static char *DupCap_B[SK_MAX_CARD_PARAM] = {"", };
425#endif
426
427#ifdef FLOW_CTRL_B
428static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = FLOW_CTRL_B;
429#else
430static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = {"", };
431#endif
432
433#ifdef ROLE_B
434static char *Role_B[SK_MAX_CARD_PARAM] = ROLE_B;
435#else
436static char *Role_B[SK_MAX_CARD_PARAM] = {"", };
437#endif
438
439#ifdef CON_TYPE
440static char *ConType[SK_MAX_CARD_PARAM] = CON_TYPE;
441#else
442static char *ConType[SK_MAX_CARD_PARAM] = {"", };
443#endif
444
445#ifdef PREF_PORT
446static char *PrefPort[SK_MAX_CARD_PARAM] = PREF_PORT;
447#else
448static char *PrefPort[SK_MAX_CARD_PARAM] = {"", };
449#endif
450
451#ifdef RLMT_MODE
452static char *RlmtMode[SK_MAX_CARD_PARAM] = RLMT_MODE;
453#else
454static char *RlmtMode[SK_MAX_CARD_PARAM] = {"", };
455#endif
456
457static int IntsPerSec[SK_MAX_CARD_PARAM];
458static char *Moderation[SK_MAX_CARD_PARAM];
459static char *ModerationMask[SK_MAX_CARD_PARAM];
460static char *AutoSizing[SK_MAX_CARD_PARAM];
461static char *Stats[SK_MAX_CARD_PARAM];
462
463module_param_array(Speed_A, charp, NULL, 0);
464module_param_array(Speed_B, charp, NULL, 0);
465module_param_array(AutoNeg_A, charp, NULL, 0);
466module_param_array(AutoNeg_B, charp, NULL, 0);
467module_param_array(DupCap_A, charp, NULL, 0);
468module_param_array(DupCap_B, charp, NULL, 0);
469module_param_array(FlowCtrl_A, charp, NULL, 0);
470module_param_array(FlowCtrl_B, charp, NULL, 0);
471module_param_array(Role_A, charp, NULL, 0);
472module_param_array(Role_B, charp, NULL, 0);
473module_param_array(ConType, charp, NULL, 0);
474module_param_array(PrefPort, charp, NULL, 0);
475module_param_array(RlmtMode, charp, NULL, 0);
476/* used for interrupt moderation */
477module_param_array(IntsPerSec, int, NULL, 0);
478module_param_array(Moderation, charp, NULL, 0);
479module_param_array(Stats, charp, NULL, 0);
480module_param_array(ModerationMask, charp, NULL, 0);
481module_param_array(AutoSizing, charp, NULL, 0);
482
483/*****************************************************************************
484 *
485 * SkGeBoardInit - do level 0 and 1 initialization
486 *
487 * Description:
488 * This function prepares the board hardware for running. The desriptor
489 * ring is set up, the IRQ is allocated and the configuration settings
490 * are examined.
491 *
492 * Returns:
493 * 0, if everything is ok
494 * !=0, on error
495 */
496static int __init SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC)
497{
498short i;
499unsigned long Flags;
500char *DescrString = "sk98lin: Driver for Linux"; /* this is given to PNMI */
501char *VerStr = VER_STRING;
502int Ret; /* return code of request_irq */
503SK_BOOL DualNet;
504
505 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
506 ("IoBase: %08lX\n", (unsigned long)pAC->IoBase));
507 for (i=0; i<SK_MAX_MACS; i++) {
508 pAC->TxPort[i][0].HwAddr = pAC->IoBase + TxQueueAddr[i][0];
509 pAC->TxPort[i][0].PortIndex = i;
510 pAC->RxPort[i].HwAddr = pAC->IoBase + RxQueueAddr[i];
511 pAC->RxPort[i].PortIndex = i;
512 }
513
514 /* Initialize the mutexes */
515 for (i=0; i<SK_MAX_MACS; i++) {
516 spin_lock_init(&pAC->TxPort[i][0].TxDesRingLock);
517 spin_lock_init(&pAC->RxPort[i].RxDesRingLock);
518 }
519 spin_lock_init(&pAC->SlowPathLock);
520
521 /* setup phy_id blink timer */
522 pAC->BlinkTimer.function = SkGeBlinkTimer;
523 pAC->BlinkTimer.data = (unsigned long) dev;
524 init_timer(&pAC->BlinkTimer);
525
526 /* level 0 init common modules here */
527
528 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
529 /* Does a RESET on board ...*/
530 if (SkGeInit(pAC, pAC->IoBase, SK_INIT_DATA) != 0) {
531 printk("HWInit (0) failed.\n");
532 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
533 return(-EAGAIN);
534 }
535 SkI2cInit( pAC, pAC->IoBase, SK_INIT_DATA);
536 SkEventInit(pAC, pAC->IoBase, SK_INIT_DATA);
537 SkPnmiInit( pAC, pAC->IoBase, SK_INIT_DATA);
538 SkAddrInit( pAC, pAC->IoBase, SK_INIT_DATA);
539 SkRlmtInit( pAC, pAC->IoBase, SK_INIT_DATA);
540 SkTimerInit(pAC, pAC->IoBase, SK_INIT_DATA);
541
542 pAC->BoardLevel = SK_INIT_DATA;
543 pAC->RxBufSize = ETH_BUF_SIZE;
544
545 SK_PNMI_SET_DRIVER_DESCR(pAC, DescrString);
546 SK_PNMI_SET_DRIVER_VER(pAC, VerStr);
547
548 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
549
550 /* level 1 init common modules here (HW init) */
551 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
552 if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
553 printk("sk98lin: HWInit (1) failed.\n");
554 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
555 return(-EAGAIN);
556 }
557 SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO);
558 SkEventInit(pAC, pAC->IoBase, SK_INIT_IO);
559 SkPnmiInit( pAC, pAC->IoBase, SK_INIT_IO);
560 SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO);
561 SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO);
562 SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO);
563
564 /* Set chipset type support */
565 pAC->ChipsetType = 0;
566 if ((pAC->GIni.GIChipId == CHIP_ID_YUKON) ||
567 (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE)) {
568 pAC->ChipsetType = 1;
569 }
570
571 GetConfiguration(pAC);
572 if (pAC->RlmtNets == 2) {
573 pAC->GIni.GIPortUsage = SK_MUL_LINK;
574 }
575
576 pAC->BoardLevel = SK_INIT_IO;
577 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
578
579 if (pAC->GIni.GIMacsFound == 2) {
580 Ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, pAC->Name, dev);
581 } else if (pAC->GIni.GIMacsFound == 1) {
582 Ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ,
583 pAC->Name, dev);
584 } else {
585 printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n",
586 pAC->GIni.GIMacsFound);
587 return -EAGAIN;
588 }
589
590 if (Ret) {
591 printk(KERN_WARNING "sk98lin: Requested IRQ %d is busy.\n",
592 dev->irq);
593 return -EAGAIN;
594 }
595 pAC->AllocFlag |= SK_ALLOC_IRQ;
596
597 /* Alloc memory for this board (Mem for RxD/TxD) : */
598 if(!BoardAllocMem(pAC)) {
599 printk("No memory for descriptor rings.\n");
600 return(-EAGAIN);
601 }
602
603 SkCsSetReceiveFlags(pAC,
604 SKCS_PROTO_IP | SKCS_PROTO_TCP | SKCS_PROTO_UDP,
605 &pAC->CsOfs1, &pAC->CsOfs2, 0);
606 pAC->CsOfs = (pAC->CsOfs2 << 16) | pAC->CsOfs1;
607
608 BoardInitMem(pAC);
609 /* tschilling: New common function with minimum size check. */
610 DualNet = SK_FALSE;
611 if (pAC->RlmtNets == 2) {
612 DualNet = SK_TRUE;
613 }
614
615 if (SkGeInitAssignRamToQueues(
616 pAC,
617 pAC->ActivePort,
618 DualNet)) {
619 BoardFreeMem(pAC);
620 printk("sk98lin: SkGeInitAssignRamToQueues failed.\n");
621 return(-EAGAIN);
622 }
623
624 return (0);
625} /* SkGeBoardInit */
626
627
628/*****************************************************************************
629 *
630 * BoardAllocMem - allocate the memory for the descriptor rings
631 *
632 * Description:
633 * This function allocates the memory for all descriptor rings.
634 * Each ring is aligned for the desriptor alignment and no ring
635 * has a 4 GByte boundary in it (because the upper 32 bit must
636 * be constant for all descriptiors in one rings).
637 *
638 * Returns:
639 * SK_TRUE, if all memory could be allocated
640 * SK_FALSE, if not
641 */
642static SK_BOOL BoardAllocMem(
643SK_AC *pAC)
644{
645caddr_t pDescrMem; /* pointer to descriptor memory area */
646size_t AllocLength; /* length of complete descriptor area */
647int i; /* loop counter */
648unsigned long BusAddr;
649
650
651 /* rings plus one for alignment (do not cross 4 GB boundary) */
652 /* RX_RING_SIZE is assumed bigger than TX_RING_SIZE */
653#if (BITS_PER_LONG == 32)
654 AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;
655#else
656 AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound
657 + RX_RING_SIZE + 8;
658#endif
659
660 pDescrMem = pci_alloc_consistent(pAC->PciDev, AllocLength,
661 &pAC->pDescrMemDMA);
662
663 if (pDescrMem == NULL) {
664 return (SK_FALSE);
665 }
666 pAC->pDescrMem = pDescrMem;
667 BusAddr = (unsigned long) pAC->pDescrMemDMA;
668
669 /* Descriptors need 8 byte alignment, and this is ensured
670 * by pci_alloc_consistent.
671 */
672 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
673 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
674 ("TX%d/A: pDescrMem: %lX, PhysDescrMem: %lX\n",
675 i, (unsigned long) pDescrMem,
676 BusAddr));
677 pAC->TxPort[i][0].pTxDescrRing = pDescrMem;
678 pAC->TxPort[i][0].VTxDescrRing = BusAddr;
679 pDescrMem += TX_RING_SIZE;
680 BusAddr += TX_RING_SIZE;
681
682 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
683 ("RX%d: pDescrMem: %lX, PhysDescrMem: %lX\n",
684 i, (unsigned long) pDescrMem,
685 (unsigned long)BusAddr));
686 pAC->RxPort[i].pRxDescrRing = pDescrMem;
687 pAC->RxPort[i].VRxDescrRing = BusAddr;
688 pDescrMem += RX_RING_SIZE;
689 BusAddr += RX_RING_SIZE;
690 } /* for */
691
692 return (SK_TRUE);
693} /* BoardAllocMem */
694
695
696/****************************************************************************
697 *
698 * BoardFreeMem - reverse of BoardAllocMem
699 *
700 * Description:
701 * Free all memory allocated in BoardAllocMem: adapter context,
702 * descriptor rings, locks.
703 *
704 * Returns: N/A
705 */
706static void BoardFreeMem(
707SK_AC *pAC)
708{
709size_t AllocLength; /* length of complete descriptor area */
710
711 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
712 ("BoardFreeMem\n"));
713#if (BITS_PER_LONG == 32)
714 AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;
715#else
716 AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound
717 + RX_RING_SIZE + 8;
718#endif
719
720 pci_free_consistent(pAC->PciDev, AllocLength,
721 pAC->pDescrMem, pAC->pDescrMemDMA);
722 pAC->pDescrMem = NULL;
723} /* BoardFreeMem */
724
725
726/*****************************************************************************
727 *
728 * BoardInitMem - initiate the descriptor rings
729 *
730 * Description:
731 * This function sets the descriptor rings up in memory.
732 * The adapter is initialized with the descriptor start addresses.
733 *
734 * Returns: N/A
735 */
736static void BoardInitMem(
737SK_AC *pAC) /* pointer to adapter context */
738{
739int i; /* loop counter */
740int RxDescrSize; /* the size of a rx descriptor rounded up to alignment*/
741int TxDescrSize; /* the size of a tx descriptor rounded up to alignment*/
742
743 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
744 ("BoardInitMem\n"));
745
746 RxDescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
747 pAC->RxDescrPerRing = RX_RING_SIZE / RxDescrSize;
748 TxDescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
749 pAC->TxDescrPerRing = TX_RING_SIZE / RxDescrSize;
750
751 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
752 SetupRing(
753 pAC,
754 pAC->TxPort[i][0].pTxDescrRing,
755 pAC->TxPort[i][0].VTxDescrRing,
756 (RXD**)&pAC->TxPort[i][0].pTxdRingHead,
757 (RXD**)&pAC->TxPort[i][0].pTxdRingTail,
758 (RXD**)&pAC->TxPort[i][0].pTxdRingPrev,
759 &pAC->TxPort[i][0].TxdRingFree,
760 SK_TRUE);
761 SetupRing(
762 pAC,
763 pAC->RxPort[i].pRxDescrRing,
764 pAC->RxPort[i].VRxDescrRing,
765 &pAC->RxPort[i].pRxdRingHead,
766 &pAC->RxPort[i].pRxdRingTail,
767 &pAC->RxPort[i].pRxdRingPrev,
768 &pAC->RxPort[i].RxdRingFree,
769 SK_FALSE);
770 }
771} /* BoardInitMem */
772
773
774/*****************************************************************************
775 *
776 * SetupRing - create one descriptor ring
777 *
778 * Description:
779 * This function creates one descriptor ring in the given memory area.
780 * The head, tail and number of free descriptors in the ring are set.
781 *
782 * Returns:
783 * none
784 */
785static void SetupRing(
786SK_AC *pAC,
787void *pMemArea, /* a pointer to the memory area for the ring */
788uintptr_t VMemArea, /* the virtual bus address of the memory area */
789RXD **ppRingHead, /* address where the head should be written */
790RXD **ppRingTail, /* address where the tail should be written */
791RXD **ppRingPrev, /* address where the tail should be written */
792int *pRingFree, /* address where the # of free descr. goes */
793SK_BOOL IsTx) /* flag: is this a tx ring */
794{
795int i; /* loop counter */
796int DescrSize; /* the size of a descriptor rounded up to alignment*/
797int DescrNum; /* number of descriptors per ring */
798RXD *pDescr; /* pointer to a descriptor (receive or transmit) */
799RXD *pNextDescr; /* pointer to the next descriptor */
800RXD *pPrevDescr; /* pointer to the previous descriptor */
801uintptr_t VNextDescr; /* the virtual bus address of the next descriptor */
802
803 if (IsTx == SK_TRUE) {
804 DescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) *
805 DESCR_ALIGN;
806 DescrNum = TX_RING_SIZE / DescrSize;
807 } else {
808 DescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) *
809 DESCR_ALIGN;
810 DescrNum = RX_RING_SIZE / DescrSize;
811 }
812
813 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
814 ("Descriptor size: %d Descriptor Number: %d\n",
815 DescrSize,DescrNum));
816
817 pDescr = (RXD*) pMemArea;
818 pPrevDescr = NULL;
819 pNextDescr = (RXD*) (((char*)pDescr) + DescrSize);
820 VNextDescr = VMemArea + DescrSize;
821 for(i=0; i<DescrNum; i++) {
822 /* set the pointers right */
823 pDescr->VNextRxd = VNextDescr & 0xffffffffULL;
824 pDescr->pNextRxd = pNextDescr;
825 pDescr->TcpSumStarts = pAC->CsOfs;
826
827 /* advance one step */
828 pPrevDescr = pDescr;
829 pDescr = pNextDescr;
830 pNextDescr = (RXD*) (((char*)pDescr) + DescrSize);
831 VNextDescr += DescrSize;
832 }
833 pPrevDescr->pNextRxd = (RXD*) pMemArea;
834 pPrevDescr->VNextRxd = VMemArea;
835 pDescr = (RXD*) pMemArea;
836 *ppRingHead = (RXD*) pMemArea;
837 *ppRingTail = *ppRingHead;
838 *ppRingPrev = pPrevDescr;
839 *pRingFree = DescrNum;
840} /* SetupRing */
841
842
843/*****************************************************************************
844 *
845 * PortReInitBmu - re-initiate the descriptor rings for one port
846 *
847 * Description:
848 * This function reinitializes the descriptor rings of one port
849 * in memory. The port must be stopped before.
850 * The HW is initialized with the descriptor start addresses.
851 *
852 * Returns:
853 * none
854 */
855static void PortReInitBmu(
856SK_AC *pAC, /* pointer to adapter context */
857int PortIndex) /* index of the port for which to re-init */
858{
859 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
860 ("PortReInitBmu "));
861
862 /* set address of first descriptor of ring in BMU */
863 SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ Q_DA_L,
864 (uint32_t)(((caddr_t)
865 (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) -
866 pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing +
867 pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) &
868 0xFFFFFFFF));
869 SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ Q_DA_H,
870 (uint32_t)(((caddr_t)
871 (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) -
872 pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing +
873 pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) >> 32));
874 SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+Q_DA_L,
875 (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) -
876 pAC->RxPort[PortIndex].pRxDescrRing +
877 pAC->RxPort[PortIndex].VRxDescrRing) & 0xFFFFFFFF));
878 SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+Q_DA_H,
879 (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) -
880 pAC->RxPort[PortIndex].pRxDescrRing +
881 pAC->RxPort[PortIndex].VRxDescrRing) >> 32));
882} /* PortReInitBmu */
883
884
885/****************************************************************************
886 *
887 * SkGeIsr - handle adapter interrupts
888 *
889 * Description:
890 * The interrupt routine is called when the network adapter
891 * generates an interrupt. It may also be called if another device
892 * shares this interrupt vector with the driver.
893 *
894 * Returns: N/A
895 *
896 */
897static SkIsrRetVar SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs)
898{
899struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
900DEV_NET *pNet;
901SK_AC *pAC;
902SK_U32 IntSrc; /* interrupts source register contents */
903
904 pNet = netdev_priv(dev);
905 pAC = pNet->pAC;
906
907 /*
908 * Check and process if its our interrupt
909 */
910 SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc);
911 if (IntSrc == 0) {
912 return SkIsrRetNone;
913 }
914
915 while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
916#if 0 /* software irq currently not used */
917 if (IntSrc & IS_IRQ_SW) {
918 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
919 SK_DBGCAT_DRV_INT_SRC,
920 ("Software IRQ\n"));
921 }
922#endif
923 if (IntSrc & IS_R1_F) {
924 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
925 SK_DBGCAT_DRV_INT_SRC,
926 ("EOF RX1 IRQ\n"));
927 ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
928 SK_PNMI_CNT_RX_INTR(pAC, 0);
929 }
930 if (IntSrc & IS_R2_F) {
931 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
932 SK_DBGCAT_DRV_INT_SRC,
933 ("EOF RX2 IRQ\n"));
934 ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE);
935 SK_PNMI_CNT_RX_INTR(pAC, 1);
936 }
937#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
938 if (IntSrc & IS_XA1_F) {
939 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
940 SK_DBGCAT_DRV_INT_SRC,
941 ("EOF AS TX1 IRQ\n"));
942 SK_PNMI_CNT_TX_INTR(pAC, 0);
943 spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
944 FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
945 spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
946 }
947 if (IntSrc & IS_XA2_F) {
948 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
949 SK_DBGCAT_DRV_INT_SRC,
950 ("EOF AS TX2 IRQ\n"));
951 SK_PNMI_CNT_TX_INTR(pAC, 1);
952 spin_lock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
953 FreeTxDescriptors(pAC, &pAC->TxPort[1][TX_PRIO_LOW]);
954 spin_unlock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
955 }
956#if 0 /* only if sync. queues used */
957 if (IntSrc & IS_XS1_F) {
958 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
959 SK_DBGCAT_DRV_INT_SRC,
960 ("EOF SY TX1 IRQ\n"));
961 SK_PNMI_CNT_TX_INTR(pAC, 1);
962 spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
963 FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
964 spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
965 ClearTxIrq(pAC, 0, TX_PRIO_HIGH);
966 }
967 if (IntSrc & IS_XS2_F) {
968 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
969 SK_DBGCAT_DRV_INT_SRC,
970 ("EOF SY TX2 IRQ\n"));
971 SK_PNMI_CNT_TX_INTR(pAC, 1);
972 spin_lock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
973 FreeTxDescriptors(pAC, 1, TX_PRIO_HIGH);
974 spin_unlock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
975 ClearTxIrq(pAC, 1, TX_PRIO_HIGH);
976 }
977#endif
978#endif
979
980 /* do all IO at once */
981 if (IntSrc & IS_R1_F)
982 ClearAndStartRx(pAC, 0);
983 if (IntSrc & IS_R2_F)
984 ClearAndStartRx(pAC, 1);
985#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
986 if (IntSrc & IS_XA1_F)
987 ClearTxIrq(pAC, 0, TX_PRIO_LOW);
988 if (IntSrc & IS_XA2_F)
989 ClearTxIrq(pAC, 1, TX_PRIO_LOW);
990#endif
991 SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
992 } /* while (IntSrc & IRQ_MASK != 0) */
993
994 IntSrc &= pAC->GIni.GIValIrqMask;
995 if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
996 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
997 ("SPECIAL IRQ DP-Cards => %x\n", IntSrc));
998 pAC->CheckQueue = SK_FALSE;
999 spin_lock(&pAC->SlowPathLock);
1000 if (IntSrc & SPECIAL_IRQS)
1001 SkGeSirqIsr(pAC, pAC->IoBase, IntSrc);
1002
1003 SkEventDispatcher(pAC, pAC->IoBase);
1004 spin_unlock(&pAC->SlowPathLock);
1005 }
1006 /*
1007 * do it all again is case we cleared an interrupt that
1008 * came in after handling the ring (OUTs may be delayed
1009 * in hardware buffers, but are through after IN)
1010 *
1011 * rroesler: has been commented out and shifted to
1012 * SkGeDrvEvent(), because it is timer
1013 * guarded now
1014 *
1015 ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
1016 ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE);
1017 */
1018
1019 if (pAC->CheckQueue) {
1020 pAC->CheckQueue = SK_FALSE;
1021 spin_lock(&pAC->SlowPathLock);
1022 SkEventDispatcher(pAC, pAC->IoBase);
1023 spin_unlock(&pAC->SlowPathLock);
1024 }
1025
1026 /* IRQ is processed - Enable IRQs again*/
1027 SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
1028
1029 return SkIsrRetHandled;
1030} /* SkGeIsr */
1031
1032
1033/****************************************************************************
1034 *
1035 * SkGeIsrOnePort - handle adapter interrupts for single port adapter
1036 *
1037 * Description:
1038 * The interrupt routine is called when the network adapter
1039 * generates an interrupt. It may also be called if another device
1040 * shares this interrupt vector with the driver.
1041 * This is the same as above, but handles only one port.
1042 *
1043 * Returns: N/A
1044 *
1045 */
1046static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs)
1047{
1048struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
1049DEV_NET *pNet;
1050SK_AC *pAC;
1051SK_U32 IntSrc; /* interrupts source register contents */
1052
1053 pNet = netdev_priv(dev);
1054 pAC = pNet->pAC;
1055
1056 /*
1057 * Check and process if its our interrupt
1058 */
1059 SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc);
1060 if (IntSrc == 0) {
1061 return SkIsrRetNone;
1062 }
1063
1064 while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
1065#if 0 /* software irq currently not used */
1066 if (IntSrc & IS_IRQ_SW) {
1067 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1068 SK_DBGCAT_DRV_INT_SRC,
1069 ("Software IRQ\n"));
1070 }
1071#endif
1072 if (IntSrc & IS_R1_F) {
1073 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1074 SK_DBGCAT_DRV_INT_SRC,
1075 ("EOF RX1 IRQ\n"));
1076 ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
1077 SK_PNMI_CNT_RX_INTR(pAC, 0);
1078 }
1079#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
1080 if (IntSrc & IS_XA1_F) {
1081 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1082 SK_DBGCAT_DRV_INT_SRC,
1083 ("EOF AS TX1 IRQ\n"));
1084 SK_PNMI_CNT_TX_INTR(pAC, 0);
1085 spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
1086 FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
1087 spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
1088 }
1089#if 0 /* only if sync. queues used */
1090 if (IntSrc & IS_XS1_F) {
1091 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1092 SK_DBGCAT_DRV_INT_SRC,
1093 ("EOF SY TX1 IRQ\n"));
1094 SK_PNMI_CNT_TX_INTR(pAC, 0);
1095 spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
1096 FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
1097 spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
1098 ClearTxIrq(pAC, 0, TX_PRIO_HIGH);
1099 }
1100#endif
1101#endif
1102
1103 /* do all IO at once */
1104 if (IntSrc & IS_R1_F)
1105 ClearAndStartRx(pAC, 0);
1106#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
1107 if (IntSrc & IS_XA1_F)
1108 ClearTxIrq(pAC, 0, TX_PRIO_LOW);
1109#endif
1110 SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
1111 } /* while (IntSrc & IRQ_MASK != 0) */
1112
1113 IntSrc &= pAC->GIni.GIValIrqMask;
1114 if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
1115 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
1116 ("SPECIAL IRQ SP-Cards => %x\n", IntSrc));
1117 pAC->CheckQueue = SK_FALSE;
1118 spin_lock(&pAC->SlowPathLock);
1119 if (IntSrc & SPECIAL_IRQS)
1120 SkGeSirqIsr(pAC, pAC->IoBase, IntSrc);
1121
1122 SkEventDispatcher(pAC, pAC->IoBase);
1123 spin_unlock(&pAC->SlowPathLock);
1124 }
1125 /*
1126 * do it all again is case we cleared an interrupt that
1127 * came in after handling the ring (OUTs may be delayed
1128 * in hardware buffers, but are through after IN)
1129 *
1130 * rroesler: has been commented out and shifted to
1131 * SkGeDrvEvent(), because it is timer
1132 * guarded now
1133 *
1134 ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
1135 */
1136
1137 /* IRQ is processed - Enable IRQs again*/
1138 SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
1139
1140 return SkIsrRetHandled;
1141} /* SkGeIsrOnePort */
1142
1143#ifdef CONFIG_NET_POLL_CONTROLLER
1144/****************************************************************************
1145 *
1146 * SkGePollController - polling receive, for netconsole
1147 *
1148 * Description:
1149 * Polling receive - used by netconsole and other diagnostic tools
1150 * to allow network i/o with interrupts disabled.
1151 *
1152 * Returns: N/A
1153 */
1154static void SkGePollController(struct net_device *dev)
1155{
1156 disable_irq(dev->irq);
1157 SkGeIsr(dev->irq, dev, NULL);
1158 enable_irq(dev->irq);
1159}
1160#endif
1161
1162/****************************************************************************
1163 *
1164 * SkGeOpen - handle start of initialized adapter
1165 *
1166 * Description:
1167 * This function starts the initialized adapter.
1168 * The board level variable is set and the adapter is
1169 * brought to full functionality.
1170 * The device flags are set for operation.
1171 * Do all necessary level 2 initialization, enable interrupts and
1172 * give start command to RLMT.
1173 *
1174 * Returns:
1175 * 0 on success
1176 * != 0 on error
1177 */
1178static int SkGeOpen(
1179struct SK_NET_DEVICE *dev)
1180{
1181 DEV_NET *pNet;
1182 SK_AC *pAC;
1183 unsigned long Flags; /* for spin lock */
1184 int i;
1185 SK_EVPARA EvPara; /* an event parameter union */
1186
1187 pNet = netdev_priv(dev);
1188 pAC = pNet->pAC;
1189
1190 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
1191 ("SkGeOpen: pAC=0x%lX:\n", (unsigned long)pAC));
1192
1193#ifdef SK_DIAG_SUPPORT
1194 if (pAC->DiagModeActive == DIAG_ACTIVE) {
1195 if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
1196 return (-1); /* still in use by diag; deny actions */
1197 }
1198 }
1199#endif
1200
1201 /* Set blink mode */
1202 if ((pAC->PciDev->vendor == 0x1186) || (pAC->PciDev->vendor == 0x11ab ))
1203 pAC->GIni.GILedBlinkCtrl = OEM_CONFIG_VALUE;
1204
1205 if (pAC->BoardLevel == SK_INIT_DATA) {
1206 /* level 1 init common modules here */
1207 if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
1208 printk("%s: HWInit (1) failed.\n", pAC->dev[pNet->PortNr]->name);
1209 return (-1);
1210 }
1211 SkI2cInit (pAC, pAC->IoBase, SK_INIT_IO);
1212 SkEventInit (pAC, pAC->IoBase, SK_INIT_IO);
1213 SkPnmiInit (pAC, pAC->IoBase, SK_INIT_IO);
1214 SkAddrInit (pAC, pAC->IoBase, SK_INIT_IO);
1215 SkRlmtInit (pAC, pAC->IoBase, SK_INIT_IO);
1216 SkTimerInit (pAC, pAC->IoBase, SK_INIT_IO);
1217 pAC->BoardLevel = SK_INIT_IO;
1218 }
1219
1220 if (pAC->BoardLevel != SK_INIT_RUN) {
1221 /* tschilling: Level 2 init modules here, check return value. */
1222 if (SkGeInit(pAC, pAC->IoBase, SK_INIT_RUN) != 0) {
1223 printk("%s: HWInit (2) failed.\n", pAC->dev[pNet->PortNr]->name);
1224 return (-1);
1225 }
1226 SkI2cInit (pAC, pAC->IoBase, SK_INIT_RUN);
1227 SkEventInit (pAC, pAC->IoBase, SK_INIT_RUN);
1228 SkPnmiInit (pAC, pAC->IoBase, SK_INIT_RUN);
1229 SkAddrInit (pAC, pAC->IoBase, SK_INIT_RUN);
1230 SkRlmtInit (pAC, pAC->IoBase, SK_INIT_RUN);
1231 SkTimerInit (pAC, pAC->IoBase, SK_INIT_RUN);
1232 pAC->BoardLevel = SK_INIT_RUN;
1233 }
1234
1235 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
1236 /* Enable transmit descriptor polling. */
1237 SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
1238 FillRxRing(pAC, &pAC->RxPort[i]);
1239 }
1240 SkGeYellowLED(pAC, pAC->IoBase, 1);
1241
1242 StartDrvCleanupTimer(pAC);
1243 SkDimEnableModerationIfNeeded(pAC);
1244 SkDimDisplayModerationSettings(pAC);
1245
1246 pAC->GIni.GIValIrqMask &= IRQ_MASK;
1247
1248 /* enable Interrupts */
1249 SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
1250 SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
1251
1252 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
1253
1254 if ((pAC->RlmtMode != 0) && (pAC->MaxPorts == 0)) {
1255 EvPara.Para32[0] = pAC->RlmtNets;
1256 EvPara.Para32[1] = -1;
1257 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS,
1258 EvPara);
1259 EvPara.Para32[0] = pAC->RlmtMode;
1260 EvPara.Para32[1] = 0;
1261 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_MODE_CHANGE,
1262 EvPara);
1263 }
1264
1265 EvPara.Para32[0] = pNet->NetNr;
1266 EvPara.Para32[1] = -1;
1267 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
1268 SkEventDispatcher(pAC, pAC->IoBase);
1269 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
1270
1271 pAC->MaxPorts++;
1272 pNet->Up = 1;
1273
1274
1275 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
1276 ("SkGeOpen suceeded\n"));
1277
1278 return (0);
1279} /* SkGeOpen */
1280
1281
1282/****************************************************************************
1283 *
1284 * SkGeClose - Stop initialized adapter
1285 *
1286 * Description:
1287 * Close initialized adapter.
1288 *
1289 * Returns:
1290 * 0 - on success
1291 * error code - on error
1292 */
1293static int SkGeClose(
1294struct SK_NET_DEVICE *dev)
1295{
1296 DEV_NET *pNet;
1297 DEV_NET *newPtrNet;
1298 SK_AC *pAC;
1299
1300 unsigned long Flags; /* for spin lock */
1301 int i;
1302 int PortIdx;
1303 SK_EVPARA EvPara;
1304
1305 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
1306 ("SkGeClose: pAC=0x%lX ", (unsigned long)pAC));
1307
1308 pNet = netdev_priv(dev);
1309 pAC = pNet->pAC;
1310
1311#ifdef SK_DIAG_SUPPORT
1312 if (pAC->DiagModeActive == DIAG_ACTIVE) {
1313 if (pAC->DiagFlowCtrl == SK_FALSE) {
1314 /*
1315 ** notify that the interface which has been closed
1316 ** by operator interaction must not be started up
1317 ** again when the DIAG has finished.
1318 */
1319 newPtrNet = netdev_priv(pAC->dev[0]);
1320 if (newPtrNet == pNet) {
1321 pAC->WasIfUp[0] = SK_FALSE;
1322 } else {
1323 pAC->WasIfUp[1] = SK_FALSE;
1324 }
1325 return 0; /* return to system everything is fine... */
1326 } else {
1327 pAC->DiagFlowCtrl = SK_FALSE;
1328 }
1329 }
1330#endif
1331
1332 netif_stop_queue(dev);
1333
1334 if (pAC->RlmtNets == 1)
1335 PortIdx = pAC->ActivePort;
1336 else
1337 PortIdx = pNet->NetNr;
1338
1339 StopDrvCleanupTimer(pAC);
1340
1341 /*
1342 * Clear multicast table, promiscuous mode ....
1343 */
1344 SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
1345 SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
1346 SK_PROM_MODE_NONE);
1347
1348 if (pAC->MaxPorts == 1) {
1349 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
1350 /* disable interrupts */
1351 SK_OUT32(pAC->IoBase, B0_IMSK, 0);
1352 EvPara.Para32[0] = pNet->NetNr;
1353 EvPara.Para32[1] = -1;
1354 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
1355 SkEventDispatcher(pAC, pAC->IoBase);
1356 SK_OUT32(pAC->IoBase, B0_IMSK, 0);
1357 /* stop the hardware */
1358 SkGeDeInit(pAC, pAC->IoBase);
1359 pAC->BoardLevel = SK_INIT_DATA;
1360 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
1361 } else {
1362
1363 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
1364 EvPara.Para32[0] = pNet->NetNr;
1365 EvPara.Para32[1] = -1;
1366 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
1367 SkPnmiEvent(pAC, pAC->IoBase, SK_PNMI_EVT_XMAC_RESET, EvPara);
1368 SkEventDispatcher(pAC, pAC->IoBase);
1369 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
1370
1371 /* Stop port */
1372 spin_lock_irqsave(&pAC->TxPort[pNet->PortNr]
1373 [TX_PRIO_LOW].TxDesRingLock, Flags);
1374 SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr,
1375 SK_STOP_ALL, SK_HARD_RST);
1376 spin_unlock_irqrestore(&pAC->TxPort[pNet->PortNr]
1377 [TX_PRIO_LOW].TxDesRingLock, Flags);
1378 }
1379
1380 if (pAC->RlmtNets == 1) {
1381 /* clear all descriptor rings */
1382 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
1383 ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);
1384 ClearRxRing(pAC, &pAC->RxPort[i]);
1385 ClearTxRing(pAC, &pAC->TxPort[i][TX_PRIO_LOW]);
1386 }
1387 } else {
1388 /* clear port descriptor rings */
1389 ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE);
1390 ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]);
1391 ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]);
1392 }
1393
1394 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
1395 ("SkGeClose: done "));
1396
1397 SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA));
1398 SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct),
1399 sizeof(SK_PNMI_STRUCT_DATA));
1400
1401 pAC->MaxPorts--;
1402 pNet->Up = 0;
1403
1404 return (0);
1405} /* SkGeClose */
1406
1407
1408/*****************************************************************************
1409 *
1410 * SkGeXmit - Linux frame transmit function
1411 *
1412 * Description:
1413 * The system calls this function to send frames onto the wire.
1414 * It puts the frame in the tx descriptor ring. If the ring is
1415 * full then, the 'tbusy' flag is set.
1416 *
1417 * Returns:
1418 * 0, if everything is ok
1419 * !=0, on error
1420 * WARNING: returning 1 in 'tbusy' case caused system crashes (double
1421 * allocated skb's) !!!
1422 */
1423static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev)
1424{
1425DEV_NET *pNet;
1426SK_AC *pAC;
1427int Rc; /* return code of XmitFrame */
1428
1429 pNet = netdev_priv(dev);
1430 pAC = pNet->pAC;
1431
1432 if ((!skb_shinfo(skb)->nr_frags) ||
1433 (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) {
1434 /* Don't activate scatter-gather and hardware checksum */
1435
1436 if (pAC->RlmtNets == 2)
1437 Rc = XmitFrame(
1438 pAC,
1439 &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW],
1440 skb);
1441 else
1442 Rc = XmitFrame(
1443 pAC,
1444 &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW],
1445 skb);
1446 } else {
1447 /* scatter-gather and hardware TCP checksumming anabled*/
1448 if (pAC->RlmtNets == 2)
1449 Rc = XmitFrameSG(
1450 pAC,
1451 &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW],
1452 skb);
1453 else
1454 Rc = XmitFrameSG(
1455 pAC,
1456 &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW],
1457 skb);
1458 }
1459
1460 /* Transmitter out of resources? */
1461 if (Rc <= 0) {
1462 netif_stop_queue(dev);
1463 }
1464
1465 /* If not taken, give buffer ownership back to the
1466 * queueing layer.
1467 */
1468 if (Rc < 0)
1469 return (1);
1470
1471 dev->trans_start = jiffies;
1472 return (0);
1473} /* SkGeXmit */
1474
1475
1476/*****************************************************************************
1477 *
1478 * XmitFrame - fill one socket buffer into the transmit ring
1479 *
1480 * Description:
1481 * This function puts a message into the transmit descriptor ring
1482 * if there is a descriptors left.
1483 * Linux skb's consist of only one continuous buffer.
1484 * The first step locks the ring. It is held locked
1485 * all time to avoid problems with SWITCH_../PORT_RESET.
1486 * Then the descriptoris allocated.
1487 * The second part is linking the buffer to the descriptor.
1488 * At the very last, the Control field of the descriptor
1489 * is made valid for the BMU and a start TX command is given
1490 * if necessary.
1491 *
1492 * Returns:
1493 * > 0 - on succes: the number of bytes in the message
1494 * = 0 - on resource shortage: this frame sent or dropped, now
1495 * the ring is full ( -> set tbusy)
1496 * < 0 - on failure: other problems ( -> return failure to upper layers)
1497 */
1498static int XmitFrame(
1499SK_AC *pAC, /* pointer to adapter context */
1500TX_PORT *pTxPort, /* pointer to struct of port to send to */
1501struct sk_buff *pMessage) /* pointer to send-message */
1502{
1503 TXD *pTxd; /* the rxd to fill */
1504 TXD *pOldTxd;
1505 unsigned long Flags;
1506 SK_U64 PhysAddr;
1507 int Protocol;
1508 int IpHeaderLength;
1509 int BytesSend = pMessage->len;
1510
1511 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ("X"));
1512
1513 spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
1514#ifndef USE_TX_COMPLETE
1515 FreeTxDescriptors(pAC, pTxPort);
1516#endif
1517 if (pTxPort->TxdRingFree == 0) {
1518 /*
1519 ** no enough free descriptors in ring at the moment.
1520 ** Maybe free'ing some old one help?
1521 */
1522 FreeTxDescriptors(pAC, pTxPort);
1523 if (pTxPort->TxdRingFree == 0) {
1524 spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
1525 SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex);
1526 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1527 SK_DBGCAT_DRV_TX_PROGRESS,
1528 ("XmitFrame failed\n"));
1529 /*
1530 ** the desired message can not be sent
1531 ** Because tbusy seems to be set, the message
1532 ** should not be freed here. It will be used
1533 ** by the scheduler of the ethernet handler
1534 */
1535 return (-1);
1536 }
1537 }
1538
1539 /*
1540 ** If the passed socket buffer is of smaller MTU-size than 60,
1541 ** copy everything into new buffer and fill all bytes between
1542 ** the original packet end and the new packet end of 60 with 0x00.
1543 ** This is to resolve faulty padding by the HW with 0xaa bytes.
1544 */
1545 if (BytesSend < C_LEN_ETHERNET_MINSIZE) {
1546 if ((pMessage = skb_padto(pMessage, C_LEN_ETHERNET_MINSIZE)) == NULL) {
1547 spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
1548 return 0;
1549 }
1550 pMessage->len = C_LEN_ETHERNET_MINSIZE;
1551 }
1552
1553 /*
1554 ** advance head counter behind descriptor needed for this frame,
1555 ** so that needed descriptor is reserved from that on. The next
1556 ** action will be to add the passed buffer to the TX-descriptor
1557 */
1558 pTxd = pTxPort->pTxdRingHead;
1559 pTxPort->pTxdRingHead = pTxd->pNextTxd;
1560 pTxPort->TxdRingFree--;
1561
1562#ifdef SK_DUMP_TX
1563 DumpMsg(pMessage, "XmitFrame");
1564#endif
1565
1566 /*
1567 ** First step is to map the data to be sent via the adapter onto
1568 ** the DMA memory. Kernel 2.2 uses virt_to_bus(), but kernels 2.4
1569 ** and 2.6 need to use pci_map_page() for that mapping.
1570 */
1571 PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
1572 virt_to_page(pMessage->data),
1573 ((unsigned long) pMessage->data & ~PAGE_MASK),
1574 pMessage->len,
1575 PCI_DMA_TODEVICE);
1576 pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
1577 pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
1578 pTxd->pMBuf = pMessage;
1579
1580 if (pMessage->ip_summed == CHECKSUM_HW) {
1581 Protocol = ((SK_U8)pMessage->data[C_OFFSET_IPPROTO] & 0xff);
1582 if ((Protocol == C_PROTO_ID_UDP) &&
1583 (pAC->GIni.GIChipRev == 0) &&
1584 (pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
1585 pTxd->TBControl = BMU_TCP_CHECK;
1586 } else {
1587 pTxd->TBControl = BMU_UDP_CHECK;
1588 }
1589
1590 IpHeaderLength = (SK_U8)pMessage->data[C_OFFSET_IPHEADER];
1591 IpHeaderLength = (IpHeaderLength & 0xf) * 4;
1592 pTxd->TcpSumOfs = 0; /* PH-Checksum already calculated */
1593 pTxd->TcpSumSt = C_LEN_ETHERMAC_HEADER + IpHeaderLength +
1594 (Protocol == C_PROTO_ID_UDP ?
1595 C_OFFSET_UDPHEADER_UDPCS :
1596 C_OFFSET_TCPHEADER_TCPCS);
1597 pTxd->TcpSumWr = C_LEN_ETHERMAC_HEADER + IpHeaderLength;
1598
1599 pTxd->TBControl |= BMU_OWN | BMU_STF |
1600 BMU_SW | BMU_EOF |
1601#ifdef USE_TX_COMPLETE
1602 BMU_IRQ_EOF |
1603#endif
1604 pMessage->len;
1605 } else {
1606 pTxd->TBControl = BMU_OWN | BMU_STF | BMU_CHECK |
1607 BMU_SW | BMU_EOF |
1608#ifdef USE_TX_COMPLETE
1609 BMU_IRQ_EOF |
1610#endif
1611 pMessage->len;
1612 }
1613
1614 /*
1615 ** If previous descriptor already done, give TX start cmd
1616 */
1617 pOldTxd = xchg(&pTxPort->pTxdRingPrev, pTxd);
1618 if ((pOldTxd->TBControl & BMU_OWN) == 0) {
1619 SK_OUT8(pTxPort->HwAddr, Q_CSR, CSR_START);
1620 }
1621
1622 /*
1623 ** after releasing the lock, the skb may immediately be free'd
1624 */
1625 spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
1626 if (pTxPort->TxdRingFree != 0) {
1627 return (BytesSend);
1628 } else {
1629 return (0);
1630 }
1631
1632} /* XmitFrame */
1633
1634/*****************************************************************************
1635 *
1636 * XmitFrameSG - fill one socket buffer into the transmit ring
1637 * (use SG and TCP/UDP hardware checksumming)
1638 *
1639 * Description:
1640 * This function puts a message into the transmit descriptor ring
1641 * if there is a descriptors left.
1642 *
1643 * Returns:
1644 * > 0 - on succes: the number of bytes in the message
1645 * = 0 - on resource shortage: this frame sent or dropped, now
1646 * the ring is full ( -> set tbusy)
1647 * < 0 - on failure: other problems ( -> return failure to upper layers)
1648 */
1649static int XmitFrameSG(
1650SK_AC *pAC, /* pointer to adapter context */
1651TX_PORT *pTxPort, /* pointer to struct of port to send to */
1652struct sk_buff *pMessage) /* pointer to send-message */
1653{
1654
1655 TXD *pTxd;
1656 TXD *pTxdFst;
1657 TXD *pTxdLst;
1658 int CurrFrag;
1659 int BytesSend;
1660 int IpHeaderLength;
1661 int Protocol;
1662 skb_frag_t *sk_frag;
1663 SK_U64 PhysAddr;
1664 unsigned long Flags;
1665
1666 spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
1667#ifndef USE_TX_COMPLETE
1668 FreeTxDescriptors(pAC, pTxPort);
1669#endif
1670 if ((skb_shinfo(pMessage)->nr_frags +1) > pTxPort->TxdRingFree) {
1671 FreeTxDescriptors(pAC, pTxPort);
1672 if ((skb_shinfo(pMessage)->nr_frags + 1) > pTxPort->TxdRingFree) {
1673 spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
1674 SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex);
1675 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1676 SK_DBGCAT_DRV_TX_PROGRESS,
1677 ("XmitFrameSG failed - Ring full\n"));
1678 /* this message can not be sent now */
1679 return(-1);
1680 }
1681 }
1682
1683 pTxd = pTxPort->pTxdRingHead;
1684 pTxdFst = pTxd;
1685 pTxdLst = pTxd;
1686 BytesSend = 0;
1687 Protocol = 0;
1688
1689 /*
1690 ** Map the first fragment (header) into the DMA-space
1691 */
1692 PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
1693 virt_to_page(pMessage->data),
1694 ((unsigned long) pMessage->data & ~PAGE_MASK),
1695 skb_headlen(pMessage),
1696 PCI_DMA_TODEVICE);
1697
1698 pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
1699 pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
1700
1701 /*
1702 ** Does the HW need to evaluate checksum for TCP or UDP packets?
1703 */
1704 if (pMessage->ip_summed == CHECKSUM_HW) {
1705 pTxd->TBControl = BMU_STF | BMU_STFWD | skb_headlen(pMessage);
1706 /*
1707 ** We have to use the opcode for tcp here, because the
1708 ** opcode for udp is not working in the hardware yet
1709 ** (Revision 2.0)
1710 */
1711 Protocol = ((SK_U8)pMessage->data[C_OFFSET_IPPROTO] & 0xff);
1712 if ((Protocol == C_PROTO_ID_UDP) &&
1713 (pAC->GIni.GIChipRev == 0) &&
1714 (pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
1715 pTxd->TBControl |= BMU_TCP_CHECK;
1716 } else {
1717 pTxd->TBControl |= BMU_UDP_CHECK;
1718 }
1719
1720 IpHeaderLength = ((SK_U8)pMessage->data[C_OFFSET_IPHEADER] & 0xf)*4;
1721 pTxd->TcpSumOfs = 0; /* PH-Checksum already claculated */
1722 pTxd->TcpSumSt = C_LEN_ETHERMAC_HEADER + IpHeaderLength +
1723 (Protocol == C_PROTO_ID_UDP ?
1724 C_OFFSET_UDPHEADER_UDPCS :
1725 C_OFFSET_TCPHEADER_TCPCS);
1726 pTxd->TcpSumWr = C_LEN_ETHERMAC_HEADER + IpHeaderLength;
1727 } else {
1728 pTxd->TBControl = BMU_CHECK | BMU_SW | BMU_STF |
1729 skb_headlen(pMessage);
1730 }
1731
1732 pTxd = pTxd->pNextTxd;
1733 pTxPort->TxdRingFree--;
1734 BytesSend += skb_headlen(pMessage);
1735
1736 /*
1737 ** Browse over all SG fragments and map each of them into the DMA space
1738 */
1739 for (CurrFrag = 0; CurrFrag < skb_shinfo(pMessage)->nr_frags; CurrFrag++) {
1740 sk_frag = &skb_shinfo(pMessage)->frags[CurrFrag];
1741 /*
1742 ** we already have the proper value in entry
1743 */
1744 PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
1745 sk_frag->page,
1746 sk_frag->page_offset,
1747 sk_frag->size,
1748 PCI_DMA_TODEVICE);
1749
1750 pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
1751 pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
1752 pTxd->pMBuf = pMessage;
1753
1754 /*
1755 ** Does the HW need to evaluate checksum for TCP or UDP packets?
1756 */
1757 if (pMessage->ip_summed == CHECKSUM_HW) {
1758 pTxd->TBControl = BMU_OWN | BMU_SW | BMU_STFWD;
1759 /*
1760 ** We have to use the opcode for tcp here because the
1761 ** opcode for udp is not working in the hardware yet
1762 ** (revision 2.0)
1763 */
1764 if ((Protocol == C_PROTO_ID_UDP) &&
1765 (pAC->GIni.GIChipRev == 0) &&
1766 (pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
1767 pTxd->TBControl |= BMU_TCP_CHECK;
1768 } else {
1769 pTxd->TBControl |= BMU_UDP_CHECK;
1770 }
1771 } else {
1772 pTxd->TBControl = BMU_CHECK | BMU_SW | BMU_OWN;
1773 }
1774
1775 /*
1776 ** Do we have the last fragment?
1777 */
1778 if( (CurrFrag+1) == skb_shinfo(pMessage)->nr_frags ) {
1779#ifdef USE_TX_COMPLETE
1780 pTxd->TBControl |= BMU_EOF | BMU_IRQ_EOF | sk_frag->size;
1781#else
1782 pTxd->TBControl |= BMU_EOF | sk_frag->size;
1783#endif
1784 pTxdFst->TBControl |= BMU_OWN | BMU_SW;
1785
1786 } else {
1787 pTxd->TBControl |= sk_frag->size;
1788 }
1789 pTxdLst = pTxd;
1790 pTxd = pTxd->pNextTxd;
1791 pTxPort->TxdRingFree--;
1792 BytesSend += sk_frag->size;
1793 }
1794
1795 /*
1796 ** If previous descriptor already done, give TX start cmd
1797 */
1798 if ((pTxPort->pTxdRingPrev->TBControl & BMU_OWN) == 0) {
1799 SK_OUT8(pTxPort->HwAddr, Q_CSR, CSR_START);
1800 }
1801
1802 pTxPort->pTxdRingPrev = pTxdLst;
1803 pTxPort->pTxdRingHead = pTxd;
1804
1805 spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
1806
1807 if (pTxPort->TxdRingFree > 0) {
1808 return (BytesSend);
1809 } else {
1810 return (0);
1811 }
1812}
1813
1814/*****************************************************************************
1815 *
1816 * FreeTxDescriptors - release descriptors from the descriptor ring
1817 *
1818 * Description:
1819 * This function releases descriptors from a transmit ring if they
1820 * have been sent by the BMU.
1821 * If a descriptors is sent, it can be freed and the message can
1822 * be freed, too.
1823 * The SOFTWARE controllable bit is used to prevent running around a
1824 * completely free ring for ever. If this bit is no set in the
1825 * frame (by XmitFrame), this frame has never been sent or is
1826 * already freed.
1827 * The Tx descriptor ring lock must be held while calling this function !!!
1828 *
1829 * Returns:
1830 * none
1831 */
1832static void FreeTxDescriptors(
1833SK_AC *pAC, /* pointer to the adapter context */
1834TX_PORT *pTxPort) /* pointer to destination port structure */
1835{
1836TXD *pTxd; /* pointer to the checked descriptor */
1837TXD *pNewTail; /* pointer to 'end' of the ring */
1838SK_U32 Control; /* TBControl field of descriptor */
1839SK_U64 PhysAddr; /* address of DMA mapping */
1840
1841 pNewTail = pTxPort->pTxdRingTail;
1842 pTxd = pNewTail;
1843 /*
1844 ** loop forever; exits if BMU_SW bit not set in start frame
1845 ** or BMU_OWN bit set in any frame
1846 */
1847 while (1) {
1848 Control = pTxd->TBControl;
1849 if ((Control & BMU_SW) == 0) {
1850 /*
1851 ** software controllable bit is set in first
1852 ** fragment when given to BMU. Not set means that
1853 ** this fragment was never sent or is already
1854 ** freed ( -> ring completely free now).
1855 */
1856 pTxPort->pTxdRingTail = pTxd;
1857 netif_wake_queue(pAC->dev[pTxPort->PortIndex]);
1858 return;
1859 }
1860 if (Control & BMU_OWN) {
1861 pTxPort->pTxdRingTail = pTxd;
1862 if (pTxPort->TxdRingFree > 0) {
1863 netif_wake_queue(pAC->dev[pTxPort->PortIndex]);
1864 }
1865 return;
1866 }
1867
1868 /*
1869 ** release the DMA mapping, because until not unmapped
1870 ** this buffer is considered being under control of the
1871 ** adapter card!
1872 */
1873 PhysAddr = ((SK_U64) pTxd->VDataHigh) << (SK_U64) 32;
1874 PhysAddr |= (SK_U64) pTxd->VDataLow;
1875 pci_unmap_page(pAC->PciDev, PhysAddr,
1876 pTxd->pMBuf->len,
1877 PCI_DMA_TODEVICE);
1878
1879 if (Control & BMU_EOF)
1880 DEV_KFREE_SKB_ANY(pTxd->pMBuf); /* free message */
1881
1882 pTxPort->TxdRingFree++;
1883 pTxd->TBControl &= ~BMU_SW;
1884 pTxd = pTxd->pNextTxd; /* point behind fragment with EOF */
1885 } /* while(forever) */
1886} /* FreeTxDescriptors */
1887
1888/*****************************************************************************
1889 *
1890 * FillRxRing - fill the receive ring with valid descriptors
1891 *
1892 * Description:
1893 * This function fills the receive ring descriptors with data
1894 * segments and makes them valid for the BMU.
1895 * The active ring is filled completely, if possible.
1896 * The non-active ring is filled only partial to save memory.
1897 *
1898 * Description of rx ring structure:
1899 * head - points to the descriptor which will be used next by the BMU
1900 * tail - points to the next descriptor to give to the BMU
1901 *
1902 * Returns: N/A
1903 */
1904static void FillRxRing(
1905SK_AC *pAC, /* pointer to the adapter context */
1906RX_PORT *pRxPort) /* ptr to port struct for which the ring
1907 should be filled */
1908{
1909unsigned long Flags;
1910
1911 spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags);
1912 while (pRxPort->RxdRingFree > pRxPort->RxFillLimit) {
1913 if(!FillRxDescriptor(pAC, pRxPort))
1914 break;
1915 }
1916 spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags);
1917} /* FillRxRing */
1918
1919
1920/*****************************************************************************
1921 *
1922 * FillRxDescriptor - fill one buffer into the receive ring
1923 *
1924 * Description:
1925 * The function allocates a new receive buffer and
1926 * puts it into the next descriptor.
1927 *
1928 * Returns:
1929 * SK_TRUE - a buffer was added to the ring
1930 * SK_FALSE - a buffer could not be added
1931 */
1932static SK_BOOL FillRxDescriptor(
1933SK_AC *pAC, /* pointer to the adapter context struct */
1934RX_PORT *pRxPort) /* ptr to port struct of ring to fill */
1935{
1936struct sk_buff *pMsgBlock; /* pointer to a new message block */
1937RXD *pRxd; /* the rxd to fill */
1938SK_U16 Length; /* data fragment length */
1939SK_U64 PhysAddr; /* physical address of a rx buffer */
1940
1941 pMsgBlock = alloc_skb(pAC->RxBufSize, GFP_ATOMIC);
1942 if (pMsgBlock == NULL) {
1943 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1944 SK_DBGCAT_DRV_ENTRY,
1945 ("%s: Allocation of rx buffer failed !\n",
1946 pAC->dev[pRxPort->PortIndex]->name));
1947 SK_PNMI_CNT_NO_RX_BUF(pAC, pRxPort->PortIndex);
1948 return(SK_FALSE);
1949 }
1950 skb_reserve(pMsgBlock, 2); /* to align IP frames */
1951 /* skb allocated ok, so add buffer */
1952 pRxd = pRxPort->pRxdRingTail;
1953 pRxPort->pRxdRingTail = pRxd->pNextRxd;
1954 pRxPort->RxdRingFree--;
1955 Length = pAC->RxBufSize;
1956 PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
1957 virt_to_page(pMsgBlock->data),
1958 ((unsigned long) pMsgBlock->data &
1959 ~PAGE_MASK),
1960 pAC->RxBufSize - 2,
1961 PCI_DMA_FROMDEVICE);
1962
1963 pRxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
1964 pRxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
1965 pRxd->pMBuf = pMsgBlock;
1966 pRxd->RBControl = BMU_OWN |
1967 BMU_STF |
1968 BMU_IRQ_EOF |
1969 BMU_TCP_CHECK |
1970 Length;
1971 return (SK_TRUE);
1972
1973} /* FillRxDescriptor */
1974
1975
1976/*****************************************************************************
1977 *
1978 * ReQueueRxBuffer - fill one buffer back into the receive ring
1979 *
1980 * Description:
1981 * Fill a given buffer back into the rx ring. The buffer
1982 * has been previously allocated and aligned, and its phys.
1983 * address calculated, so this is no more necessary.
1984 *
1985 * Returns: N/A
1986 */
1987static void ReQueueRxBuffer(
1988SK_AC *pAC, /* pointer to the adapter context struct */
1989RX_PORT *pRxPort, /* ptr to port struct of ring to fill */
1990struct sk_buff *pMsg, /* pointer to the buffer */
1991SK_U32 PhysHigh, /* phys address high dword */
1992SK_U32 PhysLow) /* phys address low dword */
1993{
1994RXD *pRxd; /* the rxd to fill */
1995SK_U16 Length; /* data fragment length */
1996
1997 pRxd = pRxPort->pRxdRingTail;
1998 pRxPort->pRxdRingTail = pRxd->pNextRxd;
1999 pRxPort->RxdRingFree--;
2000 Length = pAC->RxBufSize;
2001
2002 pRxd->VDataLow = PhysLow;
2003 pRxd->VDataHigh = PhysHigh;
2004 pRxd->pMBuf = pMsg;
2005 pRxd->RBControl = BMU_OWN |
2006 BMU_STF |
2007 BMU_IRQ_EOF |
2008 BMU_TCP_CHECK |
2009 Length;
2010 return;
2011} /* ReQueueRxBuffer */
2012
2013/*****************************************************************************
2014 *
2015 * ReceiveIrq - handle a receive IRQ
2016 *
2017 * Description:
2018 * This function is called when a receive IRQ is set.
2019 * It walks the receive descriptor ring and sends up all
2020 * frames that are complete.
2021 *
2022 * Returns: N/A
2023 */
2024static void ReceiveIrq(
2025 SK_AC *pAC, /* pointer to adapter context */
2026 RX_PORT *pRxPort, /* pointer to receive port struct */
2027 SK_BOOL SlowPathLock) /* indicates if SlowPathLock is needed */
2028{
2029RXD *pRxd; /* pointer to receive descriptors */
2030SK_U32 Control; /* control field of descriptor */
2031struct sk_buff *pMsg; /* pointer to message holding frame */
2032struct sk_buff *pNewMsg; /* pointer to a new message for copying frame */
2033int FrameLength; /* total length of received frame */
2034int IpFrameLength;
2035SK_MBUF *pRlmtMbuf; /* ptr to a buffer for giving a frame to rlmt */
2036SK_EVPARA EvPara; /* an event parameter union */
2037unsigned long Flags; /* for spin lock */
2038int PortIndex = pRxPort->PortIndex;
2039unsigned int Offset;
2040unsigned int NumBytes;
2041unsigned int ForRlmt;
2042SK_BOOL IsBc;
2043SK_BOOL IsMc;
2044SK_BOOL IsBadFrame; /* Bad frame */
2045
2046SK_U32 FrameStat;
2047unsigned short Csum1;
2048unsigned short Csum2;
2049unsigned short Type;
2050int Result;
2051SK_U64 PhysAddr;
2052
2053rx_start:
2054 /* do forever; exit if BMU_OWN found */
2055 for ( pRxd = pRxPort->pRxdRingHead ;
2056 pRxPort->RxdRingFree < pAC->RxDescrPerRing ;
2057 pRxd = pRxd->pNextRxd,
2058 pRxPort->pRxdRingHead = pRxd,
2059 pRxPort->RxdRingFree ++) {
2060
2061 /*
2062 * For a better understanding of this loop
2063 * Go through every descriptor beginning at the head
2064 * Please note: the ring might be completely received so the OWN bit
2065 * set is not a good crirteria to leave that loop.
2066 * Therefore the RingFree counter is used.
2067 * On entry of this loop pRxd is a pointer to the Rxd that needs
2068 * to be checked next.
2069 */
2070
2071 Control = pRxd->RBControl;
2072
2073 /* check if this descriptor is ready */
2074 if ((Control & BMU_OWN) != 0) {
2075 /* this descriptor is not yet ready */
2076 /* This is the usual end of the loop */
2077 /* We don't need to start the ring again */
2078 FillRxRing(pAC, pRxPort);
2079 return;
2080 }
2081 pAC->DynIrqModInfo.NbrProcessedDescr++;
2082
2083 /* get length of frame and check it */
2084 FrameLength = Control & BMU_BBC;
2085 if (FrameLength > pAC->RxBufSize) {
2086 goto rx_failed;
2087 }
2088
2089 /* check for STF and EOF */
2090 if ((Control & (BMU_STF | BMU_EOF)) != (BMU_STF | BMU_EOF)) {
2091 goto rx_failed;
2092 }
2093
2094 /* here we have a complete frame in the ring */
2095 pMsg = pRxd->pMBuf;
2096
2097 FrameStat = pRxd->FrameStat;
2098
2099 /* check for frame length mismatch */
2100#define XMR_FS_LEN_SHIFT 18
2101#define GMR_FS_LEN_SHIFT 16
2102 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
2103 if (FrameLength != (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)) {
2104 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2105 SK_DBGCAT_DRV_RX_PROGRESS,
2106 ("skge: Frame length mismatch (%u/%u).\n",
2107 FrameLength,
2108 (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)));
2109 goto rx_failed;
2110 }
2111 }
2112 else {
2113 if (FrameLength != (SK_U32) (FrameStat >> GMR_FS_LEN_SHIFT)) {
2114 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2115 SK_DBGCAT_DRV_RX_PROGRESS,
2116 ("skge: Frame length mismatch (%u/%u).\n",
2117 FrameLength,
2118 (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)));
2119 goto rx_failed;
2120 }
2121 }
2122
2123 /* Set Rx Status */
2124 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
2125 IsBc = (FrameStat & XMR_FS_BC) != 0;
2126 IsMc = (FrameStat & XMR_FS_MC) != 0;
2127 IsBadFrame = (FrameStat &
2128 (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0;
2129 } else {
2130 IsBc = (FrameStat & GMR_FS_BC) != 0;
2131 IsMc = (FrameStat & GMR_FS_MC) != 0;
2132 IsBadFrame = (((FrameStat & GMR_FS_ANY_ERR) != 0) ||
2133 ((FrameStat & GMR_FS_RX_OK) == 0));
2134 }
2135
2136 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
2137 ("Received frame of length %d on port %d\n",
2138 FrameLength, PortIndex));
2139 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
2140 ("Number of free rx descriptors: %d\n",
2141 pRxPort->RxdRingFree));
2142/* DumpMsg(pMsg, "Rx"); */
2143
2144 if ((Control & BMU_STAT_VAL) != BMU_STAT_VAL || (IsBadFrame)) {
2145#if 0
2146 (FrameStat & (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0) {
2147#endif
2148 /* there is a receive error in this frame */
2149 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2150 SK_DBGCAT_DRV_RX_PROGRESS,
2151 ("skge: Error in received frame, dropped!\n"
2152 "Control: %x\nRxStat: %x\n",
2153 Control, FrameStat));
2154
2155 ReQueueRxBuffer(pAC, pRxPort, pMsg,
2156 pRxd->VDataHigh, pRxd->VDataLow);
2157
2158 continue;
2159 }
2160
2161 /*
2162 * if short frame then copy data to reduce memory waste
2163 */
2164 if ((FrameLength < SK_COPY_THRESHOLD) &&
2165 ((pNewMsg = alloc_skb(FrameLength+2, GFP_ATOMIC)) != NULL)) {
2166 /*
2167 * Short frame detected and allocation successfull
2168 */
2169 /* use new skb and copy data */
2170 skb_reserve(pNewMsg, 2);
2171 skb_put(pNewMsg, FrameLength);
2172 PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
2173 PhysAddr |= (SK_U64) pRxd->VDataLow;
2174
2175 pci_dma_sync_single_for_cpu(pAC->PciDev,
2176 (dma_addr_t) PhysAddr,
2177 FrameLength,
2178 PCI_DMA_FROMDEVICE);
2179 eth_copy_and_sum(pNewMsg, pMsg->data,
2180 FrameLength, 0);
2181 pci_dma_sync_single_for_device(pAC->PciDev,
2182 (dma_addr_t) PhysAddr,
2183 FrameLength,
2184 PCI_DMA_FROMDEVICE);
2185 ReQueueRxBuffer(pAC, pRxPort, pMsg,
2186 pRxd->VDataHigh, pRxd->VDataLow);
2187
2188 pMsg = pNewMsg;
2189
2190 }
2191 else {
2192 /*
2193 * if large frame, or SKB allocation failed, pass
2194 * the SKB directly to the networking
2195 */
2196
2197 PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
2198 PhysAddr |= (SK_U64) pRxd->VDataLow;
2199
2200 /* release the DMA mapping */
2201 pci_unmap_single(pAC->PciDev,
2202 PhysAddr,
2203 pAC->RxBufSize - 2,
2204 PCI_DMA_FROMDEVICE);
2205
2206 /* set length in message */
2207 skb_put(pMsg, FrameLength);
2208 /* hardware checksum */
2209 Type = ntohs(*((short*)&pMsg->data[12]));
2210
2211#ifdef USE_SK_RX_CHECKSUM
2212 if (Type == 0x800) {
2213 Csum1=le16_to_cpu(pRxd->TcpSums & 0xffff);
2214 Csum2=le16_to_cpu((pRxd->TcpSums >> 16) & 0xffff);
2215 IpFrameLength = (int) ntohs((unsigned short)
2216 ((unsigned short *) pMsg->data)[8]);
2217
2218 /*
2219 * Test: If frame is padded, a check is not possible!
2220 * Frame not padded? Length difference must be 14 (0xe)!
2221 */
2222 if ((FrameLength - IpFrameLength) != 0xe) {
2223 /* Frame padded => TCP offload not possible! */
2224 pMsg->ip_summed = CHECKSUM_NONE;
2225 } else {
2226 /* Frame not padded => TCP offload! */
2227 if ((((Csum1 & 0xfffe) && (Csum2 & 0xfffe)) &&
2228 (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) ||
2229 (pAC->ChipsetType)) {
2230 Result = SkCsGetReceiveInfo(pAC,
2231 &pMsg->data[14],
2232 Csum1, Csum2, pRxPort->PortIndex);
2233 if (Result ==
2234 SKCS_STATUS_IP_FRAGMENT ||
2235 Result ==
2236 SKCS_STATUS_IP_CSUM_OK ||
2237 Result ==
2238 SKCS_STATUS_TCP_CSUM_OK ||
2239 Result ==
2240 SKCS_STATUS_UDP_CSUM_OK) {
2241 pMsg->ip_summed =
2242 CHECKSUM_UNNECESSARY;
2243 }
2244 else if (Result ==
2245 SKCS_STATUS_TCP_CSUM_ERROR ||
2246 Result ==
2247 SKCS_STATUS_UDP_CSUM_ERROR ||
2248 Result ==
2249 SKCS_STATUS_IP_CSUM_ERROR_UDP ||
2250 Result ==
2251 SKCS_STATUS_IP_CSUM_ERROR_TCP ||
2252 Result ==
2253 SKCS_STATUS_IP_CSUM_ERROR ) {
2254 /* HW Checksum error */
2255 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2256 SK_DBGCAT_DRV_RX_PROGRESS,
2257 ("skge: CRC error. Frame dropped!\n"));
2258 goto rx_failed;
2259 } else {
2260 pMsg->ip_summed =
2261 CHECKSUM_NONE;
2262 }
2263 }/* checksumControl calculation valid */
2264 } /* Frame length check */
2265 } /* IP frame */
2266#else
2267 pMsg->ip_summed = CHECKSUM_NONE;
2268#endif
2269 } /* frame > SK_COPY_TRESHOLD */
2270
2271 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("V"));
2272 ForRlmt = SK_RLMT_RX_PROTOCOL;
2273#if 0
2274 IsBc = (FrameStat & XMR_FS_BC)==XMR_FS_BC;
2275#endif
2276 SK_RLMT_PRE_LOOKAHEAD(pAC, PortIndex, FrameLength,
2277 IsBc, &Offset, &NumBytes);
2278 if (NumBytes != 0) {
2279#if 0
2280 IsMc = (FrameStat & XMR_FS_MC)==XMR_FS_MC;
2281#endif
2282 SK_RLMT_LOOKAHEAD(pAC, PortIndex,
2283 &pMsg->data[Offset],
2284 IsBc, IsMc, &ForRlmt);
2285 }
2286 if (ForRlmt == SK_RLMT_RX_PROTOCOL) {
2287 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("W"));
2288 /* send up only frames from active port */
2289 if ((PortIndex == pAC->ActivePort) ||
2290 (pAC->RlmtNets == 2)) {
2291 /* frame for upper layer */
2292 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("U"));
2293#ifdef xDEBUG
2294 DumpMsg(pMsg, "Rx");
2295#endif
2296 SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,
2297 FrameLength, pRxPort->PortIndex);
2298
2299 pMsg->dev = pAC->dev[pRxPort->PortIndex];
2300 pMsg->protocol = eth_type_trans(pMsg,
2301 pAC->dev[pRxPort->PortIndex]);
2302 netif_rx(pMsg);
2303 pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
2304 }
2305 else {
2306 /* drop frame */
2307 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2308 SK_DBGCAT_DRV_RX_PROGRESS,
2309 ("D"));
2310 DEV_KFREE_SKB(pMsg);
2311 }
2312
2313 } /* if not for rlmt */
2314 else {
2315 /* packet for rlmt */
2316 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2317 SK_DBGCAT_DRV_RX_PROGRESS, ("R"));
2318 pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC,
2319 pAC->IoBase, FrameLength);
2320 if (pRlmtMbuf != NULL) {
2321 pRlmtMbuf->pNext = NULL;
2322 pRlmtMbuf->Length = FrameLength;
2323 pRlmtMbuf->PortIdx = PortIndex;
2324 EvPara.pParaPtr = pRlmtMbuf;
2325 memcpy((char*)(pRlmtMbuf->pData),
2326 (char*)(pMsg->data),
2327 FrameLength);
2328
2329 /* SlowPathLock needed? */
2330 if (SlowPathLock == SK_TRUE) {
2331 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2332 SkEventQueue(pAC, SKGE_RLMT,
2333 SK_RLMT_PACKET_RECEIVED,
2334 EvPara);
2335 pAC->CheckQueue = SK_TRUE;
2336 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2337 } else {
2338 SkEventQueue(pAC, SKGE_RLMT,
2339 SK_RLMT_PACKET_RECEIVED,
2340 EvPara);
2341 pAC->CheckQueue = SK_TRUE;
2342 }
2343
2344 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2345 SK_DBGCAT_DRV_RX_PROGRESS,
2346 ("Q"));
2347 }
2348 if ((pAC->dev[pRxPort->PortIndex]->flags &
2349 (IFF_PROMISC | IFF_ALLMULTI)) != 0 ||
2350 (ForRlmt & SK_RLMT_RX_PROTOCOL) ==
2351 SK_RLMT_RX_PROTOCOL) {
2352 pMsg->dev = pAC->dev[pRxPort->PortIndex];
2353 pMsg->protocol = eth_type_trans(pMsg,
2354 pAC->dev[pRxPort->PortIndex]);
2355 netif_rx(pMsg);
2356 pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
2357 }
2358 else {
2359 DEV_KFREE_SKB(pMsg);
2360 }
2361
2362 } /* if packet for rlmt */
2363 } /* for ... scanning the RXD ring */
2364
2365 /* RXD ring is empty -> fill and restart */
2366 FillRxRing(pAC, pRxPort);
2367 /* do not start if called from Close */
2368 if (pAC->BoardLevel > SK_INIT_DATA) {
2369 ClearAndStartRx(pAC, PortIndex);
2370 }
2371 return;
2372
2373rx_failed:
2374 /* remove error frame */
2375 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR,
2376 ("Schrottdescriptor, length: 0x%x\n", FrameLength));
2377
2378 /* release the DMA mapping */
2379
2380 PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
2381 PhysAddr |= (SK_U64) pRxd->VDataLow;
2382 pci_unmap_page(pAC->PciDev,
2383 PhysAddr,
2384 pAC->RxBufSize - 2,
2385 PCI_DMA_FROMDEVICE);
2386 DEV_KFREE_SKB_IRQ(pRxd->pMBuf);
2387 pRxd->pMBuf = NULL;
2388 pRxPort->RxdRingFree++;
2389 pRxPort->pRxdRingHead = pRxd->pNextRxd;
2390 goto rx_start;
2391
2392} /* ReceiveIrq */
2393
2394
2395/*****************************************************************************
2396 *
2397 * ClearAndStartRx - give a start receive command to BMU, clear IRQ
2398 *
2399 * Description:
2400 * This function sends a start command and a clear interrupt
2401 * command for one receive queue to the BMU.
2402 *
2403 * Returns: N/A
2404 * none
2405 */
2406static void ClearAndStartRx(
2407SK_AC *pAC, /* pointer to the adapter context */
2408int PortIndex) /* index of the receive port (XMAC) */
2409{
2410 SK_OUT8(pAC->IoBase,
2411 RxQueueAddr[PortIndex]+Q_CSR,
2412 CSR_START | CSR_IRQ_CL_F);
2413} /* ClearAndStartRx */
2414
2415
2416/*****************************************************************************
2417 *
2418 * ClearTxIrq - give a clear transmit IRQ command to BMU
2419 *
2420 * Description:
2421 * This function sends a clear tx IRQ command for one
2422 * transmit queue to the BMU.
2423 *
2424 * Returns: N/A
2425 */
2426static void ClearTxIrq(
2427SK_AC *pAC, /* pointer to the adapter context */
2428int PortIndex, /* index of the transmit port (XMAC) */
2429int Prio) /* priority or normal queue */
2430{
2431 SK_OUT8(pAC->IoBase,
2432 TxQueueAddr[PortIndex][Prio]+Q_CSR,
2433 CSR_IRQ_CL_F);
2434} /* ClearTxIrq */
2435
2436
2437/*****************************************************************************
2438 *
2439 * ClearRxRing - remove all buffers from the receive ring
2440 *
2441 * Description:
2442 * This function removes all receive buffers from the ring.
2443 * The receive BMU must be stopped before calling this function.
2444 *
2445 * Returns: N/A
2446 */
2447static void ClearRxRing(
2448SK_AC *pAC, /* pointer to adapter context */
2449RX_PORT *pRxPort) /* pointer to rx port struct */
2450{
2451RXD *pRxd; /* pointer to the current descriptor */
2452unsigned long Flags;
2453SK_U64 PhysAddr;
2454
2455 if (pRxPort->RxdRingFree == pAC->RxDescrPerRing) {
2456 return;
2457 }
2458 spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags);
2459 pRxd = pRxPort->pRxdRingHead;
2460 do {
2461 if (pRxd->pMBuf != NULL) {
2462
2463 PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
2464 PhysAddr |= (SK_U64) pRxd->VDataLow;
2465 pci_unmap_page(pAC->PciDev,
2466 PhysAddr,
2467 pAC->RxBufSize - 2,
2468 PCI_DMA_FROMDEVICE);
2469 DEV_KFREE_SKB(pRxd->pMBuf);
2470 pRxd->pMBuf = NULL;
2471 }
2472 pRxd->RBControl &= BMU_OWN;
2473 pRxd = pRxd->pNextRxd;
2474 pRxPort->RxdRingFree++;
2475 } while (pRxd != pRxPort->pRxdRingTail);
2476 pRxPort->pRxdRingTail = pRxPort->pRxdRingHead;
2477 spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags);
2478} /* ClearRxRing */
2479
2480/*****************************************************************************
2481 *
2482 * ClearTxRing - remove all buffers from the transmit ring
2483 *
2484 * Description:
2485 * This function removes all transmit buffers from the ring.
2486 * The transmit BMU must be stopped before calling this function
2487 * and transmitting at the upper level must be disabled.
2488 * The BMU own bit of all descriptors is cleared, the rest is
2489 * done by calling FreeTxDescriptors.
2490 *
2491 * Returns: N/A
2492 */
2493static void ClearTxRing(
2494SK_AC *pAC, /* pointer to adapter context */
2495TX_PORT *pTxPort) /* pointer to tx prt struct */
2496{
2497TXD *pTxd; /* pointer to the current descriptor */
2498int i;
2499unsigned long Flags;
2500
2501 spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
2502 pTxd = pTxPort->pTxdRingHead;
2503 for (i=0; i<pAC->TxDescrPerRing; i++) {
2504 pTxd->TBControl &= ~BMU_OWN;
2505 pTxd = pTxd->pNextTxd;
2506 }
2507 FreeTxDescriptors(pAC, pTxPort);
2508 spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
2509} /* ClearTxRing */
2510
2511/*****************************************************************************
2512 *
2513 * SkGeSetMacAddr - Set the hardware MAC address
2514 *
2515 * Description:
2516 * This function sets the MAC address used by the adapter.
2517 *
2518 * Returns:
2519 * 0, if everything is ok
2520 * !=0, on error
2521 */
2522static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p)
2523{
2524
2525DEV_NET *pNet = netdev_priv(dev);
2526SK_AC *pAC = pNet->pAC;
2527
2528struct sockaddr *addr = p;
2529unsigned long Flags;
2530
2531 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2532 ("SkGeSetMacAddr starts now...\n"));
2533 if(netif_running(dev))
2534 return -EBUSY;
2535
2536 memcpy(dev->dev_addr, addr->sa_data,dev->addr_len);
2537
2538 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2539
2540 if (pAC->RlmtNets == 2)
2541 SkAddrOverride(pAC, pAC->IoBase, pNet->NetNr,
2542 (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
2543 else
2544 SkAddrOverride(pAC, pAC->IoBase, pAC->ActivePort,
2545 (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
2546
2547
2548
2549 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2550 return 0;
2551} /* SkGeSetMacAddr */
2552
2553
2554/*****************************************************************************
2555 *
2556 * SkGeSetRxMode - set receive mode
2557 *
2558 * Description:
2559 * This function sets the receive mode of an adapter. The adapter
2560 * supports promiscuous mode, allmulticast mode and a number of
2561 * multicast addresses. If more multicast addresses the available
2562 * are selected, a hash function in the hardware is used.
2563 *
2564 * Returns:
2565 * 0, if everything is ok
2566 * !=0, on error
2567 */
2568static void SkGeSetRxMode(struct SK_NET_DEVICE *dev)
2569{
2570
2571DEV_NET *pNet;
2572SK_AC *pAC;
2573
2574struct dev_mc_list *pMcList;
2575int i;
2576int PortIdx;
2577unsigned long Flags;
2578
2579 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2580 ("SkGeSetRxMode starts now... "));
2581
2582 pNet = netdev_priv(dev);
2583 pAC = pNet->pAC;
2584 if (pAC->RlmtNets == 1)
2585 PortIdx = pAC->ActivePort;
2586 else
2587 PortIdx = pNet->NetNr;
2588
2589 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2590 if (dev->flags & IFF_PROMISC) {
2591 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2592 ("PROMISCUOUS mode\n"));
2593 SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
2594 SK_PROM_MODE_LLC);
2595 } else if (dev->flags & IFF_ALLMULTI) {
2596 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2597 ("ALLMULTI mode\n"));
2598 SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
2599 SK_PROM_MODE_ALL_MC);
2600 } else {
2601 SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
2602 SK_PROM_MODE_NONE);
2603 SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
2604
2605 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2606 ("Number of MC entries: %d ", dev->mc_count));
2607
2608 pMcList = dev->mc_list;
2609 for (i=0; i<dev->mc_count; i++, pMcList = pMcList->next) {
2610 SkAddrMcAdd(pAC, pAC->IoBase, PortIdx,
2611 (SK_MAC_ADDR*)pMcList->dmi_addr, 0);
2612 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MCA,
2613 ("%02x:%02x:%02x:%02x:%02x:%02x\n",
2614 pMcList->dmi_addr[0],
2615 pMcList->dmi_addr[1],
2616 pMcList->dmi_addr[2],
2617 pMcList->dmi_addr[3],
2618 pMcList->dmi_addr[4],
2619 pMcList->dmi_addr[5]));
2620 }
2621 SkAddrMcUpdate(pAC, pAC->IoBase, PortIdx);
2622 }
2623 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2624
2625 return;
2626} /* SkGeSetRxMode */
2627
2628
2629/*****************************************************************************
2630 *
2631 * SkGeChangeMtu - set the MTU to another value
2632 *
2633 * Description:
2634 * This function sets is called whenever the MTU size is changed
2635 * (ifconfig mtu xxx dev ethX). If the MTU is bigger than standard
2636 * ethernet MTU size, long frame support is activated.
2637 *
2638 * Returns:
2639 * 0, if everything is ok
2640 * !=0, on error
2641 */
2642static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int NewMtu)
2643{
2644DEV_NET *pNet;
2645DEV_NET *pOtherNet;
2646SK_AC *pAC;
2647unsigned long Flags;
2648int i;
2649SK_EVPARA EvPara;
2650
2651 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2652 ("SkGeChangeMtu starts now...\n"));
2653
2654 pNet = netdev_priv(dev);
2655 pAC = pNet->pAC;
2656
2657 if ((NewMtu < 68) || (NewMtu > SK_JUMBO_MTU)) {
2658 return -EINVAL;
2659 }
2660
2661 if(pAC->BoardLevel != SK_INIT_RUN) {
2662 return -EINVAL;
2663 }
2664
2665#ifdef SK_DIAG_SUPPORT
2666 if (pAC->DiagModeActive == DIAG_ACTIVE) {
2667 if (pAC->DiagFlowCtrl == SK_FALSE) {
2668 return -1; /* still in use, deny any actions of MTU */
2669 } else {
2670 pAC->DiagFlowCtrl = SK_FALSE;
2671 }
2672 }
2673#endif
2674
2675 pNet->Mtu = NewMtu;
2676 pOtherNet = netdev_priv(pAC->dev[1 - pNet->NetNr]);
2677 if ((pOtherNet->Mtu>1500) && (NewMtu<=1500) && (pOtherNet->Up==1)) {
2678 return(0);
2679 }
2680
2681 pAC->RxBufSize = NewMtu + 32;
2682 dev->mtu = NewMtu;
2683
2684 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2685 ("New MTU: %d\n", NewMtu));
2686
2687 /*
2688 ** Prevent any reconfiguration while changing the MTU
2689 ** by disabling any interrupts
2690 */
2691 SK_OUT32(pAC->IoBase, B0_IMSK, 0);
2692 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2693
2694 /*
2695 ** Notify RLMT that any ports are to be stopped
2696 */
2697 EvPara.Para32[0] = 0;
2698 EvPara.Para32[1] = -1;
2699 if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
2700 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
2701 EvPara.Para32[0] = 1;
2702 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
2703 } else {
2704 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
2705 }
2706
2707 /*
2708 ** After calling the SkEventDispatcher(), RLMT is aware about
2709 ** the stopped ports -> configuration can take place!
2710 */
2711 SkEventDispatcher(pAC, pAC->IoBase);
2712
2713 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2714 spin_lock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
2715 netif_stop_queue(pAC->dev[i]);
2716
2717 }
2718
2719 /*
2720 ** Depending on the desired MTU size change, a different number of
2721 ** RX buffers need to be allocated
2722 */
2723 if (NewMtu > 1500) {
2724 /*
2725 ** Use less rx buffers
2726 */
2727 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2728 if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
2729 pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing -
2730 (pAC->RxDescrPerRing / 4);
2731 } else {
2732 if (i == pAC->ActivePort) {
2733 pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing -
2734 (pAC->RxDescrPerRing / 4);
2735 } else {
2736 pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing -
2737 (pAC->RxDescrPerRing / 10);
2738 }
2739 }
2740 }
2741 } else {
2742 /*
2743 ** Use the normal amount of rx buffers
2744 */
2745 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2746 if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
2747 pAC->RxPort[i].RxFillLimit = 1;
2748 } else {
2749 if (i == pAC->ActivePort) {
2750 pAC->RxPort[i].RxFillLimit = 1;
2751 } else {
2752 pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing -
2753 (pAC->RxDescrPerRing / 4);
2754 }
2755 }
2756 }
2757 }
2758
2759 SkGeDeInit(pAC, pAC->IoBase);
2760
2761 /*
2762 ** enable/disable hardware support for long frames
2763 */
2764 if (NewMtu > 1500) {
2765// pAC->JumboActivated = SK_TRUE; /* is never set back !!! */
2766 pAC->GIni.GIPortUsage = SK_JUMBO_LINK;
2767 } else {
2768 if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
2769 pAC->GIni.GIPortUsage = SK_MUL_LINK;
2770 } else {
2771 pAC->GIni.GIPortUsage = SK_RED_LINK;
2772 }
2773 }
2774
2775 SkGeInit( pAC, pAC->IoBase, SK_INIT_IO);
2776 SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO);
2777 SkEventInit(pAC, pAC->IoBase, SK_INIT_IO);
2778 SkPnmiInit( pAC, pAC->IoBase, SK_INIT_IO);
2779 SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO);
2780 SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO);
2781 SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO);
2782
2783 /*
2784 ** tschilling:
2785 ** Speed and others are set back to default in level 1 init!
2786 */
2787 GetConfiguration(pAC);
2788
2789 SkGeInit( pAC, pAC->IoBase, SK_INIT_RUN);
2790 SkI2cInit( pAC, pAC->IoBase, SK_INIT_RUN);
2791 SkEventInit(pAC, pAC->IoBase, SK_INIT_RUN);
2792 SkPnmiInit( pAC, pAC->IoBase, SK_INIT_RUN);
2793 SkAddrInit( pAC, pAC->IoBase, SK_INIT_RUN);
2794 SkRlmtInit( pAC, pAC->IoBase, SK_INIT_RUN);
2795 SkTimerInit(pAC, pAC->IoBase, SK_INIT_RUN);
2796
2797 /*
2798 ** clear and reinit the rx rings here
2799 */
2800 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2801 ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);
2802 ClearRxRing(pAC, &pAC->RxPort[i]);
2803 FillRxRing(pAC, &pAC->RxPort[i]);
2804
2805 /*
2806 ** Enable transmit descriptor polling
2807 */
2808 SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
2809 FillRxRing(pAC, &pAC->RxPort[i]);
2810 };
2811
2812 SkGeYellowLED(pAC, pAC->IoBase, 1);
2813 SkDimEnableModerationIfNeeded(pAC);
2814 SkDimDisplayModerationSettings(pAC);
2815
2816 netif_start_queue(pAC->dev[pNet->PortNr]);
2817 for (i=pAC->GIni.GIMacsFound-1; i>=0; i--) {
2818 spin_unlock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
2819 }
2820
2821 /*
2822 ** Enable Interrupts again
2823 */
2824 SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
2825 SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
2826
2827 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
2828 SkEventDispatcher(pAC, pAC->IoBase);
2829
2830 /*
2831 ** Notify RLMT about the changing and restarting one (or more) ports
2832 */
2833 if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
2834 EvPara.Para32[0] = pAC->RlmtNets;
2835 EvPara.Para32[1] = -1;
2836 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS, EvPara);
2837 EvPara.Para32[0] = pNet->PortNr;
2838 EvPara.Para32[1] = -1;
2839 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
2840
2841 if (pOtherNet->Up) {
2842 EvPara.Para32[0] = pOtherNet->PortNr;
2843 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
2844 }
2845 } else {
2846 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
2847 }
2848
2849 SkEventDispatcher(pAC, pAC->IoBase);
2850 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2851
2852 /*
2853 ** While testing this driver with latest kernel 2.5 (2.5.70), it
2854 ** seems as if upper layers have a problem to handle a successful
2855 ** return value of '0'. If such a zero is returned, the complete
2856 ** system hangs for several minutes (!), which is in acceptable.
2857 **
2858 ** Currently it is not clear, what the exact reason for this problem
2859 ** is. The implemented workaround for 2.5 is to return the desired
2860 ** new MTU size if all needed changes for the new MTU size where
2861 ** performed. In kernels 2.2 and 2.4, a zero value is returned,
2862 ** which indicates the successful change of the mtu-size.
2863 */
2864 return NewMtu;
2865
2866} /* SkGeChangeMtu */
2867
2868
2869/*****************************************************************************
2870 *
2871 * SkGeStats - return ethernet device statistics
2872 *
2873 * Description:
2874 * This function return statistic data about the ethernet device
2875 * to the operating system.
2876 *
2877 * Returns:
2878 * pointer to the statistic structure.
2879 */
2880static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev)
2881{
2882DEV_NET *pNet = netdev_priv(dev);
2883SK_AC *pAC = pNet->pAC;
2884SK_PNMI_STRUCT_DATA *pPnmiStruct; /* structure for all Pnmi-Data */
2885SK_PNMI_STAT *pPnmiStat; /* pointer to virtual XMAC stat. data */
2886SK_PNMI_CONF *pPnmiConf; /* pointer to virtual link config. */
2887unsigned int Size; /* size of pnmi struct */
2888unsigned long Flags; /* for spin lock */
2889
2890 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2891 ("SkGeStats starts now...\n"));
2892 pPnmiStruct = &pAC->PnmiStruct;
2893
2894#ifdef SK_DIAG_SUPPORT
2895 if ((pAC->DiagModeActive == DIAG_NOTACTIVE) &&
2896 (pAC->BoardLevel == SK_INIT_RUN)) {
2897#endif
2898 SK_MEMSET(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA));
2899 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2900 Size = SK_PNMI_STRUCT_SIZE;
2901 SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, pNet->NetNr);
2902 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2903#ifdef SK_DIAG_SUPPORT
2904 }
2905#endif
2906
2907 pPnmiStat = &pPnmiStruct->Stat[0];
2908 pPnmiConf = &pPnmiStruct->Conf[0];
2909
2910 pAC->stats.rx_packets = (SK_U32) pPnmiStruct->RxDeliveredCts & 0xFFFFFFFF;
2911 pAC->stats.tx_packets = (SK_U32) pPnmiStat->StatTxOkCts & 0xFFFFFFFF;
2912 pAC->stats.rx_bytes = (SK_U32) pPnmiStruct->RxOctetsDeliveredCts;
2913 pAC->stats.tx_bytes = (SK_U32) pPnmiStat->StatTxOctetsOkCts;
2914
2915 if (pNet->Mtu <= 1500) {
2916 pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF;
2917 } else {
2918 pAC->stats.rx_errors = (SK_U32) ((pPnmiStruct->InErrorsCts -
2919 pPnmiStat->StatRxTooLongCts) & 0xFFFFFFFF);
2920 }
2921
2922
2923 if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && pAC->HWRevision < 12)
2924 pAC->stats.rx_errors = pAC->stats.rx_errors - pPnmiStat->StatRxShortsCts;
2925
2926 pAC->stats.tx_errors = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF;
2927 pAC->stats.rx_dropped = (SK_U32) pPnmiStruct->RxNoBufCts & 0xFFFFFFFF;
2928 pAC->stats.tx_dropped = (SK_U32) pPnmiStruct->TxNoBufCts & 0xFFFFFFFF;
2929 pAC->stats.multicast = (SK_U32) pPnmiStat->StatRxMulticastOkCts & 0xFFFFFFFF;
2930 pAC->stats.collisions = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF;
2931
2932 /* detailed rx_errors: */
2933 pAC->stats.rx_length_errors = (SK_U32) pPnmiStat->StatRxRuntCts & 0xFFFFFFFF;
2934 pAC->stats.rx_over_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF;
2935 pAC->stats.rx_crc_errors = (SK_U32) pPnmiStat->StatRxFcsCts & 0xFFFFFFFF;
2936 pAC->stats.rx_frame_errors = (SK_U32) pPnmiStat->StatRxFramingCts & 0xFFFFFFFF;
2937 pAC->stats.rx_fifo_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF;
2938 pAC->stats.rx_missed_errors = (SK_U32) pPnmiStat->StatRxMissedCts & 0xFFFFFFFF;
2939
2940 /* detailed tx_errors */
2941 pAC->stats.tx_aborted_errors = (SK_U32) 0;
2942 pAC->stats.tx_carrier_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF;
2943 pAC->stats.tx_fifo_errors = (SK_U32) pPnmiStat->StatTxFifoUnderrunCts & 0xFFFFFFFF;
2944 pAC->stats.tx_heartbeat_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF;
2945 pAC->stats.tx_window_errors = (SK_U32) 0;
2946
2947 return(&pAC->stats);
2948} /* SkGeStats */
2949
2950
2951/*****************************************************************************
2952 *
2953 * SkGeIoctl - IO-control function
2954 *
2955 * Description:
2956 * This function is called if an ioctl is issued on the device.
2957 * There are three subfunction for reading, writing and test-writing
2958 * the private MIB data structure (usefull for SysKonnect-internal tools).
2959 *
2960 * Returns:
2961 * 0, if everything is ok
2962 * !=0, on error
2963 */
2964static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd)
2965{
2966DEV_NET *pNet;
2967SK_AC *pAC;
2968void *pMemBuf;
2969struct pci_dev *pdev = NULL;
2970SK_GE_IOCTL Ioctl;
2971unsigned int Err = 0;
2972int Size = 0;
2973int Ret = 0;
2974unsigned int Length = 0;
2975int HeaderLength = sizeof(SK_U32) + sizeof(SK_U32);
2976
2977 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2978 ("SkGeIoctl starts now...\n"));
2979
2980 pNet = netdev_priv(dev);
2981 pAC = pNet->pAC;
2982
2983 if(copy_from_user(&Ioctl, rq->ifr_data, sizeof(SK_GE_IOCTL))) {
2984 return -EFAULT;
2985 }
2986
2987 switch(cmd) {
2988 case SK_IOCTL_SETMIB:
2989 case SK_IOCTL_PRESETMIB:
2990 if (!capable(CAP_NET_ADMIN)) return -EPERM;
2991 case SK_IOCTL_GETMIB:
2992 if(copy_from_user(&pAC->PnmiStruct, Ioctl.pData,
2993 Ioctl.Len<sizeof(pAC->PnmiStruct)?
2994 Ioctl.Len : sizeof(pAC->PnmiStruct))) {
2995 return -EFAULT;
2996 }
2997 Size = SkGeIocMib(pNet, Ioctl.Len, cmd);
2998 if(copy_to_user(Ioctl.pData, &pAC->PnmiStruct,
2999 Ioctl.Len<Size? Ioctl.Len : Size)) {
3000 return -EFAULT;
3001 }
3002 Ioctl.Len = Size;
3003 if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
3004 return -EFAULT;
3005 }
3006 break;
3007 case SK_IOCTL_GEN:
3008 if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) {
3009 Length = Ioctl.Len;
3010 } else {
3011 Length = sizeof(pAC->PnmiStruct) + HeaderLength;
3012 }
3013 if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) {
3014 return -ENOMEM;
3015 }
3016 if(copy_from_user(pMemBuf, Ioctl.pData, Length)) {
3017 Err = -EFAULT;
3018 goto fault_gen;
3019 }
3020 if ((Ret = SkPnmiGenIoctl(pAC, pAC->IoBase, pMemBuf, &Length, 0)) < 0) {
3021 Err = -EFAULT;
3022 goto fault_gen;
3023 }
3024 if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) {
3025 Err = -EFAULT;
3026 goto fault_gen;
3027 }
3028 Ioctl.Len = Length;
3029 if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
3030 Err = -EFAULT;
3031 goto fault_gen;
3032 }
3033fault_gen:
3034 kfree(pMemBuf); /* cleanup everything */
3035 break;
3036#ifdef SK_DIAG_SUPPORT
3037 case SK_IOCTL_DIAG:
3038 if (!capable(CAP_NET_ADMIN)) return -EPERM;
3039 if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) {
3040 Length = Ioctl.Len;
3041 } else {
3042 Length = sizeof(pAC->PnmiStruct) + HeaderLength;
3043 }
3044 if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) {
3045 return -ENOMEM;
3046 }
3047 if(copy_from_user(pMemBuf, Ioctl.pData, Length)) {
3048 Err = -EFAULT;
3049 goto fault_diag;
3050 }
3051 pdev = pAC->PciDev;
3052 Length = 3 * sizeof(SK_U32); /* Error, Bus and Device */
3053 /*
3054 ** While coding this new IOCTL interface, only a few lines of code
3055 ** are to to be added. Therefore no dedicated function has been
3056 ** added. If more functionality is added, a separate function
3057 ** should be used...
3058 */
3059 * ((SK_U32 *)pMemBuf) = 0;
3060 * ((SK_U32 *)pMemBuf + 1) = pdev->bus->number;
3061 * ((SK_U32 *)pMemBuf + 2) = ParseDeviceNbrFromSlotName(pci_name(pdev));
3062 if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) {
3063 Err = -EFAULT;
3064 goto fault_diag;
3065 }
3066 Ioctl.Len = Length;
3067 if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
3068 Err = -EFAULT;
3069 goto fault_diag;
3070 }
3071fault_diag:
3072 kfree(pMemBuf); /* cleanup everything */
3073 break;
3074#endif
3075 default:
3076 Err = -EOPNOTSUPP;
3077 }
3078
3079 return(Err);
3080
3081} /* SkGeIoctl */
3082
3083
3084/*****************************************************************************
3085 *
3086 * SkGeIocMib - handle a GetMib, SetMib- or PresetMib-ioctl message
3087 *
3088 * Description:
3089 * This function reads/writes the MIB data using PNMI (Private Network
3090 * Management Interface).
3091 * The destination for the data must be provided with the
3092 * ioctl call and is given to the driver in the form of
3093 * a user space address.
3094 * Copying from the user-provided data area into kernel messages
3095 * and back is done by copy_from_user and copy_to_user calls in
3096 * SkGeIoctl.
3097 *
3098 * Returns:
3099 * returned size from PNMI call
3100 */
3101static int SkGeIocMib(
3102DEV_NET *pNet, /* pointer to the adapter context */
3103unsigned int Size, /* length of ioctl data */
3104int mode) /* flag for set/preset */
3105{
3106unsigned long Flags; /* for spin lock */
3107SK_AC *pAC;
3108
3109 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
3110 ("SkGeIocMib starts now...\n"));
3111 pAC = pNet->pAC;
3112 /* access MIB */
3113 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
3114 switch(mode) {
3115 case SK_IOCTL_GETMIB:
3116 SkPnmiGetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
3117 pNet->NetNr);
3118 break;
3119 case SK_IOCTL_PRESETMIB:
3120 SkPnmiPreSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
3121 pNet->NetNr);
3122 break;
3123 case SK_IOCTL_SETMIB:
3124 SkPnmiSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
3125 pNet->NetNr);
3126 break;
3127 default:
3128 break;
3129 }
3130 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
3131 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
3132 ("MIB data access succeeded\n"));
3133 return (Size);
3134} /* SkGeIocMib */
3135
3136
3137/*****************************************************************************
3138 *
3139 * GetConfiguration - read configuration information
3140 *
3141 * Description:
3142 * This function reads per-adapter configuration information from
3143 * the options provided on the command line.
3144 *
3145 * Returns:
3146 * none
3147 */
3148static void GetConfiguration(
3149SK_AC *pAC) /* pointer to the adapter context structure */
3150{
3151SK_I32 Port; /* preferred port */
3152SK_BOOL AutoSet;
3153SK_BOOL DupSet;
3154int LinkSpeed = SK_LSPEED_AUTO; /* Link speed */
3155int AutoNeg = 1; /* autoneg off (0) or on (1) */
3156int DuplexCap = 0; /* 0=both,1=full,2=half */
3157int FlowCtrl = SK_FLOW_MODE_SYM_OR_REM; /* FlowControl */
3158int MSMode = SK_MS_MODE_AUTO; /* master/slave mode */
3159
3160SK_BOOL IsConTypeDefined = SK_TRUE;
3161SK_BOOL IsLinkSpeedDefined = SK_TRUE;
3162SK_BOOL IsFlowCtrlDefined = SK_TRUE;
3163SK_BOOL IsRoleDefined = SK_TRUE;
3164SK_BOOL IsModeDefined = SK_TRUE;
3165/*
3166 * The two parameters AutoNeg. and DuplexCap. map to one configuration
3167 * parameter. The mapping is described by this table:
3168 * DuplexCap -> | both | full | half |
3169 * AutoNeg | | | |
3170 * -----------------------------------------------------------------
3171 * Off | illegal | Full | Half |
3172 * -----------------------------------------------------------------
3173 * On | AutoBoth | AutoFull | AutoHalf |
3174 * -----------------------------------------------------------------
3175 * Sense | AutoSense | AutoSense | AutoSense |
3176 */
3177int Capabilities[3][3] =
3178 { { -1, SK_LMODE_FULL , SK_LMODE_HALF },
3179 {SK_LMODE_AUTOBOTH , SK_LMODE_AUTOFULL , SK_LMODE_AUTOHALF },
3180 {SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE} };
3181
3182#define DC_BOTH 0
3183#define DC_FULL 1
3184#define DC_HALF 2
3185#define AN_OFF 0
3186#define AN_ON 1
3187#define AN_SENS 2
3188#define M_CurrPort pAC->GIni.GP[Port]
3189
3190
3191 /*
3192 ** Set the default values first for both ports!
3193 */
3194 for (Port = 0; Port < SK_MAX_MACS; Port++) {
3195 M_CurrPort.PLinkModeConf = Capabilities[AN_ON][DC_BOTH];
3196 M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
3197 M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
3198 M_CurrPort.PLinkSpeed = SK_LSPEED_AUTO;
3199 }
3200
3201 /*
3202 ** Check merged parameter ConType. If it has not been used,
3203 ** verify any other parameter (e.g. AutoNeg) and use default values.
3204 **
3205 ** Stating both ConType and other lowlevel link parameters is also
3206 ** possible. If this is the case, the passed ConType-parameter is
3207 ** overwritten by the lowlevel link parameter.
3208 **
3209 ** The following settings are used for a merged ConType-parameter:
3210 **
3211 ** ConType DupCap AutoNeg FlowCtrl Role Speed
3212 ** ------- ------ ------- -------- ---------- -----
3213 ** Auto Both On SymOrRem Auto Auto
3214 ** 100FD Full Off None <ignored> 100
3215 ** 100HD Half Off None <ignored> 100
3216 ** 10FD Full Off None <ignored> 10
3217 ** 10HD Half Off None <ignored> 10
3218 **
3219 ** This ConType parameter is used for all ports of the adapter!
3220 */
3221 if ( (ConType != NULL) &&
3222 (pAC->Index < SK_MAX_CARD_PARAM) &&
3223 (ConType[pAC->Index] != NULL) ) {
3224
3225 /* Check chipset family */
3226 if ((!pAC->ChipsetType) &&
3227 (strcmp(ConType[pAC->Index],"Auto")!=0) &&
3228 (strcmp(ConType[pAC->Index],"")!=0)) {
3229 /* Set the speed parameter back */
3230 printk("sk98lin: Illegal value \"%s\" "
3231 "for ConType."
3232 " Using Auto.\n",
3233 ConType[pAC->Index]);
3234
3235 sprintf(ConType[pAC->Index], "Auto");
3236 }
3237
3238 if (strcmp(ConType[pAC->Index],"")==0) {
3239 IsConTypeDefined = SK_FALSE; /* No ConType defined */
3240 } else if (strcmp(ConType[pAC->Index],"Auto")==0) {
3241 for (Port = 0; Port < SK_MAX_MACS; Port++) {
3242 M_CurrPort.PLinkModeConf = Capabilities[AN_ON][DC_BOTH];
3243 M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
3244 M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
3245 M_CurrPort.PLinkSpeed = SK_LSPEED_AUTO;
3246 }
3247 } else if (strcmp(ConType[pAC->Index],"100FD")==0) {
3248 for (Port = 0; Port < SK_MAX_MACS; Port++) {
3249 M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL];
3250 M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
3251 M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
3252 M_CurrPort.PLinkSpeed = SK_LSPEED_100MBPS;
3253 }
3254 } else if (strcmp(ConType[pAC->Index],"100HD")==0) {
3255 for (Port = 0; Port < SK_MAX_MACS; Port++) {
3256 M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF];
3257 M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
3258 M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
3259 M_CurrPort.PLinkSpeed = SK_LSPEED_100MBPS;
3260 }
3261 } else if (strcmp(ConType[pAC->Index],"10FD")==0) {
3262 for (Port = 0; Port < SK_MAX_MACS; Port++) {
3263 M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL];
3264 M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
3265 M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
3266 M_CurrPort.PLinkSpeed = SK_LSPEED_10MBPS;
3267 }
3268 } else if (strcmp(ConType[pAC->Index],"10HD")==0) {
3269 for (Port = 0; Port < SK_MAX_MACS; Port++) {
3270 M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF];
3271 M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
3272 M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
3273 M_CurrPort.PLinkSpeed = SK_LSPEED_10MBPS;
3274 }
3275 } else {
3276 printk("sk98lin: Illegal value \"%s\" for ConType\n",
3277 ConType[pAC->Index]);
3278 IsConTypeDefined = SK_FALSE; /* Wrong ConType defined */
3279 }
3280 } else {
3281 IsConTypeDefined = SK_FALSE; /* No ConType defined */
3282 }
3283
3284 /*
3285 ** Parse any parameter settings for port A:
3286 ** a) any LinkSpeed stated?
3287 */
3288 if (Speed_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3289 Speed_A[pAC->Index] != NULL) {
3290 if (strcmp(Speed_A[pAC->Index],"")==0) {
3291 IsLinkSpeedDefined = SK_FALSE;
3292 } else if (strcmp(Speed_A[pAC->Index],"Auto")==0) {
3293 LinkSpeed = SK_LSPEED_AUTO;
3294 } else if (strcmp(Speed_A[pAC->Index],"10")==0) {
3295 LinkSpeed = SK_LSPEED_10MBPS;
3296 } else if (strcmp(Speed_A[pAC->Index],"100")==0) {
3297 LinkSpeed = SK_LSPEED_100MBPS;
3298 } else if (strcmp(Speed_A[pAC->Index],"1000")==0) {
3299 LinkSpeed = SK_LSPEED_1000MBPS;
3300 } else {
3301 printk("sk98lin: Illegal value \"%s\" for Speed_A\n",
3302 Speed_A[pAC->Index]);
3303 IsLinkSpeedDefined = SK_FALSE;
3304 }
3305 } else {
3306 IsLinkSpeedDefined = SK_FALSE;
3307 }
3308
3309 /*
3310 ** Check speed parameter:
3311 ** Only copper type adapter and GE V2 cards
3312 */
3313 if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) &&
3314 ((LinkSpeed != SK_LSPEED_AUTO) &&
3315 (LinkSpeed != SK_LSPEED_1000MBPS))) {
3316 printk("sk98lin: Illegal value for Speed_A. "
3317 "Not a copper card or GE V2 card\n Using "
3318 "speed 1000\n");
3319 LinkSpeed = SK_LSPEED_1000MBPS;
3320 }
3321
3322 /*
3323 ** Decide whether to set new config value if somethig valid has
3324 ** been received.
3325 */
3326 if (IsLinkSpeedDefined) {
3327 pAC->GIni.GP[0].PLinkSpeed = LinkSpeed;
3328 }
3329
3330 /*
3331 ** b) Any Autonegotiation and DuplexCapabilities set?
3332 ** Please note that both belong together...
3333 */
3334 AutoNeg = AN_ON; /* tschilling: Default: Autonegotiation on! */
3335 AutoSet = SK_FALSE;
3336 if (AutoNeg_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3337 AutoNeg_A[pAC->Index] != NULL) {
3338 AutoSet = SK_TRUE;
3339 if (strcmp(AutoNeg_A[pAC->Index],"")==0) {
3340 AutoSet = SK_FALSE;
3341 } else if (strcmp(AutoNeg_A[pAC->Index],"On")==0) {
3342 AutoNeg = AN_ON;
3343 } else if (strcmp(AutoNeg_A[pAC->Index],"Off")==0) {
3344 AutoNeg = AN_OFF;
3345 } else if (strcmp(AutoNeg_A[pAC->Index],"Sense")==0) {
3346 AutoNeg = AN_SENS;
3347 } else {
3348 printk("sk98lin: Illegal value \"%s\" for AutoNeg_A\n",
3349 AutoNeg_A[pAC->Index]);
3350 }
3351 }
3352
3353 DuplexCap = DC_BOTH;
3354 DupSet = SK_FALSE;
3355 if (DupCap_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3356 DupCap_A[pAC->Index] != NULL) {
3357 DupSet = SK_TRUE;
3358 if (strcmp(DupCap_A[pAC->Index],"")==0) {
3359 DupSet = SK_FALSE;
3360 } else if (strcmp(DupCap_A[pAC->Index],"Both")==0) {
3361 DuplexCap = DC_BOTH;
3362 } else if (strcmp(DupCap_A[pAC->Index],"Full")==0) {
3363 DuplexCap = DC_FULL;
3364 } else if (strcmp(DupCap_A[pAC->Index],"Half")==0) {
3365 DuplexCap = DC_HALF;
3366 } else {
3367 printk("sk98lin: Illegal value \"%s\" for DupCap_A\n",
3368 DupCap_A[pAC->Index]);
3369 }
3370 }
3371
3372 /*
3373 ** Check for illegal combinations
3374 */
3375 if ((LinkSpeed == SK_LSPEED_1000MBPS) &&
3376 ((DuplexCap == SK_LMODE_STAT_AUTOHALF) ||
3377 (DuplexCap == SK_LMODE_STAT_HALF)) &&
3378 (pAC->ChipsetType)) {
3379 printk("sk98lin: Half Duplex not possible with Gigabit speed!\n"
3380 " Using Full Duplex.\n");
3381 DuplexCap = DC_FULL;
3382 }
3383
3384 if ( AutoSet && AutoNeg==AN_SENS && DupSet) {
3385 printk("sk98lin, Port A: DuplexCapabilities"
3386 " ignored using Sense mode\n");
3387 }
3388
3389 if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
3390 printk("sk98lin: Port A: Illegal combination"
3391 " of values AutoNeg. and DuplexCap.\n Using "
3392 "Full Duplex\n");
3393 DuplexCap = DC_FULL;
3394 }
3395
3396 if (AutoSet && AutoNeg==AN_OFF && !DupSet) {
3397 DuplexCap = DC_FULL;
3398 }
3399
3400 if (!AutoSet && DupSet) {
3401 printk("sk98lin: Port A: Duplex setting not"
3402 " possible in\n default AutoNegotiation mode"
3403 " (Sense).\n Using AutoNegotiation On\n");
3404 AutoNeg = AN_ON;
3405 }
3406
3407 /*
3408 ** set the desired mode
3409 */
3410 if (AutoSet || DupSet) {
3411 pAC->GIni.GP[0].PLinkModeConf = Capabilities[AutoNeg][DuplexCap];
3412 }
3413
3414 /*
3415 ** c) Any Flowcontrol-parameter set?
3416 */
3417 if (FlowCtrl_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3418 FlowCtrl_A[pAC->Index] != NULL) {
3419 if (strcmp(FlowCtrl_A[pAC->Index],"") == 0) {
3420 IsFlowCtrlDefined = SK_FALSE;
3421 } else if (strcmp(FlowCtrl_A[pAC->Index],"SymOrRem") == 0) {
3422 FlowCtrl = SK_FLOW_MODE_SYM_OR_REM;
3423 } else if (strcmp(FlowCtrl_A[pAC->Index],"Sym")==0) {
3424 FlowCtrl = SK_FLOW_MODE_SYMMETRIC;
3425 } else if (strcmp(FlowCtrl_A[pAC->Index],"LocSend")==0) {
3426 FlowCtrl = SK_FLOW_MODE_LOC_SEND;
3427 } else if (strcmp(FlowCtrl_A[pAC->Index],"None")==0) {
3428 FlowCtrl = SK_FLOW_MODE_NONE;
3429 } else {
3430 printk("sk98lin: Illegal value \"%s\" for FlowCtrl_A\n",
3431 FlowCtrl_A[pAC->Index]);
3432 IsFlowCtrlDefined = SK_FALSE;
3433 }
3434 } else {
3435 IsFlowCtrlDefined = SK_FALSE;
3436 }
3437
3438 if (IsFlowCtrlDefined) {
3439 if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) {
3440 printk("sk98lin: Port A: FlowControl"
3441 " impossible without AutoNegotiation,"
3442 " disabled\n");
3443 FlowCtrl = SK_FLOW_MODE_NONE;
3444 }
3445 pAC->GIni.GP[0].PFlowCtrlMode = FlowCtrl;
3446 }
3447
3448 /*
3449 ** d) What is with the RoleParameter?
3450 */
3451 if (Role_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3452 Role_A[pAC->Index] != NULL) {
3453 if (strcmp(Role_A[pAC->Index],"")==0) {
3454 IsRoleDefined = SK_FALSE;
3455 } else if (strcmp(Role_A[pAC->Index],"Auto")==0) {
3456 MSMode = SK_MS_MODE_AUTO;
3457 } else if (strcmp(Role_A[pAC->Index],"Master")==0) {
3458 MSMode = SK_MS_MODE_MASTER;
3459 } else if (strcmp(Role_A[pAC->Index],"Slave")==0) {
3460 MSMode = SK_MS_MODE_SLAVE;
3461 } else {
3462 printk("sk98lin: Illegal value \"%s\" for Role_A\n",
3463 Role_A[pAC->Index]);
3464 IsRoleDefined = SK_FALSE;
3465 }
3466 } else {
3467 IsRoleDefined = SK_FALSE;
3468 }
3469
3470 if (IsRoleDefined == SK_TRUE) {
3471 pAC->GIni.GP[0].PMSMode = MSMode;
3472 }
3473
3474
3475
3476 /*
3477 ** Parse any parameter settings for port B:
3478 ** a) any LinkSpeed stated?
3479 */
3480 IsConTypeDefined = SK_TRUE;
3481 IsLinkSpeedDefined = SK_TRUE;
3482 IsFlowCtrlDefined = SK_TRUE;
3483 IsModeDefined = SK_TRUE;
3484
3485 if (Speed_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3486 Speed_B[pAC->Index] != NULL) {
3487 if (strcmp(Speed_B[pAC->Index],"")==0) {
3488 IsLinkSpeedDefined = SK_FALSE;
3489 } else if (strcmp(Speed_B[pAC->Index],"Auto")==0) {
3490 LinkSpeed = SK_LSPEED_AUTO;
3491 } else if (strcmp(Speed_B[pAC->Index],"10")==0) {
3492 LinkSpeed = SK_LSPEED_10MBPS;
3493 } else if (strcmp(Speed_B[pAC->Index],"100")==0) {
3494 LinkSpeed = SK_LSPEED_100MBPS;
3495 } else if (strcmp(Speed_B[pAC->Index],"1000")==0) {
3496 LinkSpeed = SK_LSPEED_1000MBPS;
3497 } else {
3498 printk("sk98lin: Illegal value \"%s\" for Speed_B\n",
3499 Speed_B[pAC->Index]);
3500 IsLinkSpeedDefined = SK_FALSE;
3501 }
3502 } else {
3503 IsLinkSpeedDefined = SK_FALSE;
3504 }
3505
3506 /*
3507 ** Check speed parameter:
3508 ** Only copper type adapter and GE V2 cards
3509 */
3510 if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) &&
3511 ((LinkSpeed != SK_LSPEED_AUTO) &&
3512 (LinkSpeed != SK_LSPEED_1000MBPS))) {
3513 printk("sk98lin: Illegal value for Speed_B. "
3514 "Not a copper card or GE V2 card\n Using "
3515 "speed 1000\n");
3516 LinkSpeed = SK_LSPEED_1000MBPS;
3517 }
3518
3519 /*
3520 ** Decide whether to set new config value if somethig valid has
3521 ** been received.
3522 */
3523 if (IsLinkSpeedDefined) {
3524 pAC->GIni.GP[1].PLinkSpeed = LinkSpeed;
3525 }
3526
3527 /*
3528 ** b) Any Autonegotiation and DuplexCapabilities set?
3529 ** Please note that both belong together...
3530 */
3531 AutoNeg = AN_SENS; /* default: do auto Sense */
3532 AutoSet = SK_FALSE;
3533 if (AutoNeg_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3534 AutoNeg_B[pAC->Index] != NULL) {
3535 AutoSet = SK_TRUE;
3536 if (strcmp(AutoNeg_B[pAC->Index],"")==0) {
3537 AutoSet = SK_FALSE;
3538 } else if (strcmp(AutoNeg_B[pAC->Index],"On")==0) {
3539 AutoNeg = AN_ON;
3540 } else if (strcmp(AutoNeg_B[pAC->Index],"Off")==0) {
3541 AutoNeg = AN_OFF;
3542 } else if (strcmp(AutoNeg_B[pAC->Index],"Sense")==0) {
3543 AutoNeg = AN_SENS;
3544 } else {
3545 printk("sk98lin: Illegal value \"%s\" for AutoNeg_B\n",
3546 AutoNeg_B[pAC->Index]);
3547 }
3548 }
3549
3550 DuplexCap = DC_BOTH;
3551 DupSet = SK_FALSE;
3552 if (DupCap_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3553 DupCap_B[pAC->Index] != NULL) {
3554 DupSet = SK_TRUE;
3555 if (strcmp(DupCap_B[pAC->Index],"")==0) {
3556 DupSet = SK_FALSE;
3557 } else if (strcmp(DupCap_B[pAC->Index],"Both")==0) {
3558 DuplexCap = DC_BOTH;
3559 } else if (strcmp(DupCap_B[pAC->Index],"Full")==0) {
3560 DuplexCap = DC_FULL;
3561 } else if (strcmp(DupCap_B[pAC->Index],"Half")==0) {
3562 DuplexCap = DC_HALF;
3563 } else {
3564 printk("sk98lin: Illegal value \"%s\" for DupCap_B\n",
3565 DupCap_B[pAC->Index]);
3566 }
3567 }
3568
3569
3570 /*
3571 ** Check for illegal combinations
3572 */
3573 if ((LinkSpeed == SK_LSPEED_1000MBPS) &&
3574 ((DuplexCap == SK_LMODE_STAT_AUTOHALF) ||
3575 (DuplexCap == SK_LMODE_STAT_HALF)) &&
3576 (pAC->ChipsetType)) {
3577 printk("sk98lin: Half Duplex not possible with Gigabit speed!\n"
3578 " Using Full Duplex.\n");
3579 DuplexCap = DC_FULL;
3580 }
3581
3582 if (AutoSet && AutoNeg==AN_SENS && DupSet) {
3583 printk("sk98lin, Port B: DuplexCapabilities"
3584 " ignored using Sense mode\n");
3585 }
3586
3587 if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
3588 printk("sk98lin: Port B: Illegal combination"
3589 " of values AutoNeg. and DuplexCap.\n Using "
3590 "Full Duplex\n");
3591 DuplexCap = DC_FULL;
3592 }
3593
3594 if (AutoSet && AutoNeg==AN_OFF && !DupSet) {
3595 DuplexCap = DC_FULL;
3596 }
3597
3598 if (!AutoSet && DupSet) {
3599 printk("sk98lin: Port B: Duplex setting not"
3600 " possible in\n default AutoNegotiation mode"
3601 " (Sense).\n Using AutoNegotiation On\n");
3602 AutoNeg = AN_ON;
3603 }
3604
3605 /*
3606 ** set the desired mode
3607 */
3608 if (AutoSet || DupSet) {
3609 pAC->GIni.GP[1].PLinkModeConf = Capabilities[AutoNeg][DuplexCap];
3610 }
3611
3612 /*
3613 ** c) Any FlowCtrl parameter set?
3614 */
3615 if (FlowCtrl_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3616 FlowCtrl_B[pAC->Index] != NULL) {
3617 if (strcmp(FlowCtrl_B[pAC->Index],"") == 0) {
3618 IsFlowCtrlDefined = SK_FALSE;
3619 } else if (strcmp(FlowCtrl_B[pAC->Index],"SymOrRem") == 0) {
3620 FlowCtrl = SK_FLOW_MODE_SYM_OR_REM;
3621 } else if (strcmp(FlowCtrl_B[pAC->Index],"Sym")==0) {
3622 FlowCtrl = SK_FLOW_MODE_SYMMETRIC;
3623 } else if (strcmp(FlowCtrl_B[pAC->Index],"LocSend")==0) {
3624 FlowCtrl = SK_FLOW_MODE_LOC_SEND;
3625 } else if (strcmp(FlowCtrl_B[pAC->Index],"None")==0) {
3626 FlowCtrl = SK_FLOW_MODE_NONE;
3627 } else {
3628 printk("sk98lin: Illegal value \"%s\" for FlowCtrl_B\n",
3629 FlowCtrl_B[pAC->Index]);
3630 IsFlowCtrlDefined = SK_FALSE;
3631 }
3632 } else {
3633 IsFlowCtrlDefined = SK_FALSE;
3634 }
3635
3636 if (IsFlowCtrlDefined) {
3637 if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) {
3638 printk("sk98lin: Port B: FlowControl"
3639 " impossible without AutoNegotiation,"
3640 " disabled\n");
3641 FlowCtrl = SK_FLOW_MODE_NONE;
3642 }
3643 pAC->GIni.GP[1].PFlowCtrlMode = FlowCtrl;
3644 }
3645
3646 /*
3647 ** d) What is the RoleParameter?
3648 */
3649 if (Role_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3650 Role_B[pAC->Index] != NULL) {
3651 if (strcmp(Role_B[pAC->Index],"")==0) {
3652 IsRoleDefined = SK_FALSE;
3653 } else if (strcmp(Role_B[pAC->Index],"Auto")==0) {
3654 MSMode = SK_MS_MODE_AUTO;
3655 } else if (strcmp(Role_B[pAC->Index],"Master")==0) {
3656 MSMode = SK_MS_MODE_MASTER;
3657 } else if (strcmp(Role_B[pAC->Index],"Slave")==0) {
3658 MSMode = SK_MS_MODE_SLAVE;
3659 } else {
3660 printk("sk98lin: Illegal value \"%s\" for Role_B\n",
3661 Role_B[pAC->Index]);
3662 IsRoleDefined = SK_FALSE;
3663 }
3664 } else {
3665 IsRoleDefined = SK_FALSE;
3666 }
3667
3668 if (IsRoleDefined) {
3669 pAC->GIni.GP[1].PMSMode = MSMode;
3670 }
3671
3672 /*
3673 ** Evaluate settings for both ports
3674 */
3675 pAC->ActivePort = 0;
3676 if (PrefPort != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3677 PrefPort[pAC->Index] != NULL) {
3678 if (strcmp(PrefPort[pAC->Index],"") == 0) { /* Auto */
3679 pAC->ActivePort = 0;
3680 pAC->Rlmt.Net[0].Preference = -1; /* auto */
3681 pAC->Rlmt.Net[0].PrefPort = 0;
3682 } else if (strcmp(PrefPort[pAC->Index],"A") == 0) {
3683 /*
3684 ** do not set ActivePort here, thus a port
3685 ** switch is issued after net up.
3686 */
3687 Port = 0;
3688 pAC->Rlmt.Net[0].Preference = Port;
3689 pAC->Rlmt.Net[0].PrefPort = Port;
3690 } else if (strcmp(PrefPort[pAC->Index],"B") == 0) {
3691 /*
3692 ** do not set ActivePort here, thus a port
3693 ** switch is issued after net up.
3694 */
3695 if (pAC->GIni.GIMacsFound == 1) {
3696 printk("sk98lin: Illegal value \"B\" for PrefPort.\n"
3697 " Port B not available on single port adapters.\n");
3698
3699 pAC->ActivePort = 0;
3700 pAC->Rlmt.Net[0].Preference = -1; /* auto */
3701 pAC->Rlmt.Net[0].PrefPort = 0;
3702 } else {
3703 Port = 1;
3704 pAC->Rlmt.Net[0].Preference = Port;
3705 pAC->Rlmt.Net[0].PrefPort = Port;
3706 }
3707 } else {
3708 printk("sk98lin: Illegal value \"%s\" for PrefPort\n",
3709 PrefPort[pAC->Index]);
3710 }
3711 }
3712
3713 pAC->RlmtNets = 1;
3714
3715 if (RlmtMode != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3716 RlmtMode[pAC->Index] != NULL) {
3717 if (strcmp(RlmtMode[pAC->Index], "") == 0) {
3718 pAC->RlmtMode = 0;
3719 } else if (strcmp(RlmtMode[pAC->Index], "CheckLinkState") == 0) {
3720 pAC->RlmtMode = SK_RLMT_CHECK_LINK;
3721 } else if (strcmp(RlmtMode[pAC->Index], "CheckLocalPort") == 0) {
3722 pAC->RlmtMode = SK_RLMT_CHECK_LINK |
3723 SK_RLMT_CHECK_LOC_LINK;
3724 } else if (strcmp(RlmtMode[pAC->Index], "CheckSeg") == 0) {
3725 pAC->RlmtMode = SK_RLMT_CHECK_LINK |
3726 SK_RLMT_CHECK_LOC_LINK |
3727 SK_RLMT_CHECK_SEG;
3728 } else if ((strcmp(RlmtMode[pAC->Index], "DualNet") == 0) &&
3729 (pAC->GIni.GIMacsFound == 2)) {
3730 pAC->RlmtMode = SK_RLMT_CHECK_LINK;
3731 pAC->RlmtNets = 2;
3732 } else {
3733 printk("sk98lin: Illegal value \"%s\" for"
3734 " RlmtMode, using default\n",
3735 RlmtMode[pAC->Index]);
3736 pAC->RlmtMode = 0;
3737 }
3738 } else {
3739 pAC->RlmtMode = 0;
3740 }
3741
3742 /*
3743 ** Check the interrupt moderation parameters
3744 */
3745 if (Moderation[pAC->Index] != NULL) {
3746 if (strcmp(Moderation[pAC->Index], "") == 0) {
3747 pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
3748 } else if (strcmp(Moderation[pAC->Index], "Static") == 0) {
3749 pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_STATIC;
3750 } else if (strcmp(Moderation[pAC->Index], "Dynamic") == 0) {
3751 pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_DYNAMIC;
3752 } else if (strcmp(Moderation[pAC->Index], "None") == 0) {
3753 pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
3754 } else {
3755 printk("sk98lin: Illegal value \"%s\" for Moderation.\n"
3756 " Disable interrupt moderation.\n",
3757 Moderation[pAC->Index]);
3758 pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
3759 }
3760 } else {
3761 pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
3762 }
3763
3764 if (Stats[pAC->Index] != NULL) {
3765 if (strcmp(Stats[pAC->Index], "Yes") == 0) {
3766 pAC->DynIrqModInfo.DisplayStats = SK_TRUE;
3767 } else {
3768 pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
3769 }
3770 } else {
3771 pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
3772 }
3773
3774 if (ModerationMask[pAC->Index] != NULL) {
3775 if (strcmp(ModerationMask[pAC->Index], "Rx") == 0) {
3776 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
3777 } else if (strcmp(ModerationMask[pAC->Index], "Tx") == 0) {
3778 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_ONLY;
3779 } else if (strcmp(ModerationMask[pAC->Index], "Sp") == 0) {
3780 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_ONLY;
3781 } else if (strcmp(ModerationMask[pAC->Index], "RxSp") == 0) {
3782 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
3783 } else if (strcmp(ModerationMask[pAC->Index], "SpRx") == 0) {
3784 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
3785 } else if (strcmp(ModerationMask[pAC->Index], "RxTx") == 0) {
3786 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
3787 } else if (strcmp(ModerationMask[pAC->Index], "TxRx") == 0) {
3788 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
3789 } else if (strcmp(ModerationMask[pAC->Index], "TxSp") == 0) {
3790 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
3791 } else if (strcmp(ModerationMask[pAC->Index], "SpTx") == 0) {
3792 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
3793 } else if (strcmp(ModerationMask[pAC->Index], "RxTxSp") == 0) {
3794 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3795 } else if (strcmp(ModerationMask[pAC->Index], "RxSpTx") == 0) {
3796 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3797 } else if (strcmp(ModerationMask[pAC->Index], "TxRxSp") == 0) {
3798 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3799 } else if (strcmp(ModerationMask[pAC->Index], "TxSpRx") == 0) {
3800 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3801 } else if (strcmp(ModerationMask[pAC->Index], "SpTxRx") == 0) {
3802 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3803 } else if (strcmp(ModerationMask[pAC->Index], "SpRxTx") == 0) {
3804 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3805 } else { /* some rubbish */
3806 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
3807 }
3808 } else { /* operator has stated nothing */
3809 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
3810 }
3811
3812 if (AutoSizing[pAC->Index] != NULL) {
3813 if (strcmp(AutoSizing[pAC->Index], "On") == 0) {
3814 pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
3815 } else {
3816 pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
3817 }
3818 } else { /* operator has stated nothing */
3819 pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
3820 }
3821
3822 if (IntsPerSec[pAC->Index] != 0) {
3823 if ((IntsPerSec[pAC->Index]< C_INT_MOD_IPS_LOWER_RANGE) ||
3824 (IntsPerSec[pAC->Index] > C_INT_MOD_IPS_UPPER_RANGE)) {
3825 printk("sk98lin: Illegal value \"%d\" for IntsPerSec. (Range: %d - %d)\n"
3826 " Using default value of %i.\n",
3827 IntsPerSec[pAC->Index],
3828 C_INT_MOD_IPS_LOWER_RANGE,
3829 C_INT_MOD_IPS_UPPER_RANGE,
3830 C_INTS_PER_SEC_DEFAULT);
3831 pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
3832 } else {
3833 pAC->DynIrqModInfo.MaxModIntsPerSec = IntsPerSec[pAC->Index];
3834 }
3835 } else {
3836 pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
3837 }
3838
3839 /*
3840 ** Evaluate upper and lower moderation threshold
3841 */
3842 pAC->DynIrqModInfo.MaxModIntsPerSecUpperLimit =
3843 pAC->DynIrqModInfo.MaxModIntsPerSec +
3844 (pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
3845
3846 pAC->DynIrqModInfo.MaxModIntsPerSecLowerLimit =
3847 pAC->DynIrqModInfo.MaxModIntsPerSec -
3848 (pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
3849
3850 pAC->DynIrqModInfo.PrevTimeVal = jiffies; /* initial value */
3851
3852
3853} /* GetConfiguration */
3854
3855
3856/*****************************************************************************
3857 *
3858 * ProductStr - return a adapter identification string from vpd
3859 *
3860 * Description:
3861 * This function reads the product name string from the vpd area
3862 * and puts it the field pAC->DeviceString.
3863 *
3864 * Returns: N/A
3865 */
3866static void ProductStr(
3867SK_AC *pAC /* pointer to adapter context */
3868)
3869{
3870int StrLen = 80; /* length of the string, defined in SK_AC */
3871char Keyword[] = VPD_NAME; /* vpd productname identifier */
3872int ReturnCode; /* return code from vpd_read */
3873unsigned long Flags;
3874
3875 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
3876 ReturnCode = VpdRead(pAC, pAC->IoBase, Keyword, pAC->DeviceStr,
3877 &StrLen);
3878 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
3879 if (ReturnCode != 0) {
3880 /* there was an error reading the vpd data */
3881 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR,
3882 ("Error reading VPD data: %d\n", ReturnCode));
3883 pAC->DeviceStr[0] = '\0';
3884 }
3885} /* ProductStr */
3886
3887/*****************************************************************************
3888 *
3889 * StartDrvCleanupTimer - Start timer to check for descriptors which
3890 * might be placed in descriptor ring, but
3891 * havent been handled up to now
3892 *
3893 * Description:
3894 * This function requests a HW-timer fo the Yukon card. The actions to
3895 * perform when this timer expires, are located in the SkDrvEvent().
3896 *
3897 * Returns: N/A
3898 */
3899static void
3900StartDrvCleanupTimer(SK_AC *pAC) {
3901 SK_EVPARA EventParam; /* Event struct for timer event */
3902
3903 SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
3904 EventParam.Para32[0] = SK_DRV_RX_CLEANUP_TIMER;
3905 SkTimerStart(pAC, pAC->IoBase, &pAC->DrvCleanupTimer,
3906 SK_DRV_RX_CLEANUP_TIMER_LENGTH,
3907 SKGE_DRV, SK_DRV_TIMER, EventParam);
3908}
3909
3910/*****************************************************************************
3911 *
3912 * StopDrvCleanupTimer - Stop timer to check for descriptors
3913 *
3914 * Description:
3915 * This function requests a HW-timer fo the Yukon card. The actions to
3916 * perform when this timer expires, are located in the SkDrvEvent().
3917 *
3918 * Returns: N/A
3919 */
3920static void
3921StopDrvCleanupTimer(SK_AC *pAC) {
3922 SkTimerStop(pAC, pAC->IoBase, &pAC->DrvCleanupTimer);
3923 SK_MEMSET((char *) &pAC->DrvCleanupTimer, 0, sizeof(SK_TIMER));
3924}
3925
3926/****************************************************************************/
3927/* functions for common modules *********************************************/
3928/****************************************************************************/
3929
3930
3931/*****************************************************************************
3932 *
3933 * SkDrvAllocRlmtMbuf - allocate an RLMT mbuf
3934 *
3935 * Description:
3936 * This routine returns an RLMT mbuf or NULL. The RLMT Mbuf structure
3937 * is embedded into a socket buff data area.
3938 *
3939 * Context:
3940 * runtime
3941 *
3942 * Returns:
3943 * NULL or pointer to Mbuf.
3944 */
3945SK_MBUF *SkDrvAllocRlmtMbuf(
3946SK_AC *pAC, /* pointer to adapter context */
3947SK_IOC IoC, /* the IO-context */
3948unsigned BufferSize) /* size of the requested buffer */
3949{
3950SK_MBUF *pRlmtMbuf; /* pointer to a new rlmt-mbuf structure */
3951struct sk_buff *pMsgBlock; /* pointer to a new message block */
3952
3953 pMsgBlock = alloc_skb(BufferSize + sizeof(SK_MBUF), GFP_ATOMIC);
3954 if (pMsgBlock == NULL) {
3955 return (NULL);
3956 }
3957 pRlmtMbuf = (SK_MBUF*) pMsgBlock->data;
3958 skb_reserve(pMsgBlock, sizeof(SK_MBUF));
3959 pRlmtMbuf->pNext = NULL;
3960 pRlmtMbuf->pOs = pMsgBlock;
3961 pRlmtMbuf->pData = pMsgBlock->data; /* Data buffer. */
3962 pRlmtMbuf->Size = BufferSize; /* Data buffer size. */
3963 pRlmtMbuf->Length = 0; /* Length of packet (<= Size). */
3964 return (pRlmtMbuf);
3965
3966} /* SkDrvAllocRlmtMbuf */
3967
3968
3969/*****************************************************************************
3970 *
3971 * SkDrvFreeRlmtMbuf - free an RLMT mbuf
3972 *
3973 * Description:
3974 * This routine frees one or more RLMT mbuf(s).
3975 *
3976 * Context:
3977 * runtime
3978 *
3979 * Returns:
3980 * Nothing
3981 */
3982void SkDrvFreeRlmtMbuf(
3983SK_AC *pAC, /* pointer to adapter context */
3984SK_IOC IoC, /* the IO-context */
3985SK_MBUF *pMbuf) /* size of the requested buffer */
3986{
3987SK_MBUF *pFreeMbuf;
3988SK_MBUF *pNextMbuf;
3989
3990 pFreeMbuf = pMbuf;
3991 do {
3992 pNextMbuf = pFreeMbuf->pNext;
3993 DEV_KFREE_SKB_ANY(pFreeMbuf->pOs);
3994 pFreeMbuf = pNextMbuf;
3995 } while ( pFreeMbuf != NULL );
3996} /* SkDrvFreeRlmtMbuf */
3997
3998
3999/*****************************************************************************
4000 *
4001 * SkOsGetTime - provide a time value
4002 *
4003 * Description:
4004 * This routine provides a time value. The unit is 1/HZ (defined by Linux).
4005 * It is not used for absolute time, but only for time differences.
4006 *
4007 *
4008 * Returns:
4009 * Time value
4010 */
4011SK_U64 SkOsGetTime(SK_AC *pAC)
4012{
4013 SK_U64 PrivateJiffies;
4014 SkOsGetTimeCurrent(pAC, &PrivateJiffies);
4015 return PrivateJiffies;
4016} /* SkOsGetTime */
4017
4018
4019/*****************************************************************************
4020 *
4021 * SkPciReadCfgDWord - read a 32 bit value from pci config space
4022 *
4023 * Description:
4024 * This routine reads a 32 bit value from the pci configuration
4025 * space.
4026 *
4027 * Returns:
4028 * 0 - indicate everything worked ok.
4029 * != 0 - error indication
4030 */
4031int SkPciReadCfgDWord(
4032SK_AC *pAC, /* Adapter Control structure pointer */
4033int PciAddr, /* PCI register address */
4034SK_U32 *pVal) /* pointer to store the read value */
4035{
4036 pci_read_config_dword(pAC->PciDev, PciAddr, pVal);
4037 return(0);
4038} /* SkPciReadCfgDWord */
4039
4040
4041/*****************************************************************************
4042 *
4043 * SkPciReadCfgWord - read a 16 bit value from pci config space
4044 *
4045 * Description:
4046 * This routine reads a 16 bit value from the pci configuration
4047 * space.
4048 *
4049 * Returns:
4050 * 0 - indicate everything worked ok.
4051 * != 0 - error indication
4052 */
4053int SkPciReadCfgWord(
4054SK_AC *pAC, /* Adapter Control structure pointer */
4055int PciAddr, /* PCI register address */
4056SK_U16 *pVal) /* pointer to store the read value */
4057{
4058 pci_read_config_word(pAC->PciDev, PciAddr, pVal);
4059 return(0);
4060} /* SkPciReadCfgWord */
4061
4062
4063/*****************************************************************************
4064 *
4065 * SkPciReadCfgByte - read a 8 bit value from pci config space
4066 *
4067 * Description:
4068 * This routine reads a 8 bit value from the pci configuration
4069 * space.
4070 *
4071 * Returns:
4072 * 0 - indicate everything worked ok.
4073 * != 0 - error indication
4074 */
4075int SkPciReadCfgByte(
4076SK_AC *pAC, /* Adapter Control structure pointer */
4077int PciAddr, /* PCI register address */
4078SK_U8 *pVal) /* pointer to store the read value */
4079{
4080 pci_read_config_byte(pAC->PciDev, PciAddr, pVal);
4081 return(0);
4082} /* SkPciReadCfgByte */
4083
4084
4085/*****************************************************************************
4086 *
4087 * SkPciWriteCfgDWord - write a 32 bit value to pci config space
4088 *
4089 * Description:
4090 * This routine writes a 32 bit value to the pci configuration
4091 * space.
4092 *
4093 * Returns:
4094 * 0 - indicate everything worked ok.
4095 * != 0 - error indication
4096 */
4097int SkPciWriteCfgDWord(
4098SK_AC *pAC, /* Adapter Control structure pointer */
4099int PciAddr, /* PCI register address */
4100SK_U32 Val) /* pointer to store the read value */
4101{
4102 pci_write_config_dword(pAC->PciDev, PciAddr, Val);
4103 return(0);
4104} /* SkPciWriteCfgDWord */
4105
4106
4107/*****************************************************************************
4108 *
4109 * SkPciWriteCfgWord - write a 16 bit value to pci config space
4110 *
4111 * Description:
4112 * This routine writes a 16 bit value to the pci configuration
4113 * space. The flag PciConfigUp indicates whether the config space
4114 * is accesible or must be set up first.
4115 *
4116 * Returns:
4117 * 0 - indicate everything worked ok.
4118 * != 0 - error indication
4119 */
4120int SkPciWriteCfgWord(
4121SK_AC *pAC, /* Adapter Control structure pointer */
4122int PciAddr, /* PCI register address */
4123SK_U16 Val) /* pointer to store the read value */
4124{
4125 pci_write_config_word(pAC->PciDev, PciAddr, Val);
4126 return(0);
4127} /* SkPciWriteCfgWord */
4128
4129
4130/*****************************************************************************
4131 *
4132 * SkPciWriteCfgWord - write a 8 bit value to pci config space
4133 *
4134 * Description:
4135 * This routine writes a 8 bit value to the pci configuration
4136 * space. The flag PciConfigUp indicates whether the config space
4137 * is accesible or must be set up first.
4138 *
4139 * Returns:
4140 * 0 - indicate everything worked ok.
4141 * != 0 - error indication
4142 */
4143int SkPciWriteCfgByte(
4144SK_AC *pAC, /* Adapter Control structure pointer */
4145int PciAddr, /* PCI register address */
4146SK_U8 Val) /* pointer to store the read value */
4147{
4148 pci_write_config_byte(pAC->PciDev, PciAddr, Val);
4149 return(0);
4150} /* SkPciWriteCfgByte */
4151
4152
4153/*****************************************************************************
4154 *
4155 * SkDrvEvent - handle driver events
4156 *
4157 * Description:
4158 * This function handles events from all modules directed to the driver
4159 *
4160 * Context:
4161 * Is called under protection of slow path lock.
4162 *
4163 * Returns:
4164 * 0 if everything ok
4165 * < 0 on error
4166 *
4167 */
4168int SkDrvEvent(
4169SK_AC *pAC, /* pointer to adapter context */
4170SK_IOC IoC, /* io-context */
4171SK_U32 Event, /* event-id */
4172SK_EVPARA Param) /* event-parameter */
4173{
4174SK_MBUF *pRlmtMbuf; /* pointer to a rlmt-mbuf structure */
4175struct sk_buff *pMsg; /* pointer to a message block */
4176int FromPort; /* the port from which we switch away */
4177int ToPort; /* the port we switch to */
4178SK_EVPARA NewPara; /* parameter for further events */
4179int Stat;
4180unsigned long Flags;
4181SK_BOOL DualNet;
4182
4183 switch (Event) {
4184 case SK_DRV_ADAP_FAIL:
4185 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4186 ("ADAPTER FAIL EVENT\n"));
4187 printk("%s: Adapter failed.\n", pAC->dev[0]->name);
4188 /* disable interrupts */
4189 SK_OUT32(pAC->IoBase, B0_IMSK, 0);
4190 /* cgoos */
4191 break;
4192 case SK_DRV_PORT_FAIL:
4193 FromPort = Param.Para32[0];
4194 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4195 ("PORT FAIL EVENT, Port: %d\n", FromPort));
4196 if (FromPort == 0) {
4197 printk("%s: Port A failed.\n", pAC->dev[0]->name);
4198 } else {
4199 printk("%s: Port B failed.\n", pAC->dev[1]->name);
4200 }
4201 /* cgoos */
4202 break;
4203 case SK_DRV_PORT_RESET: /* SK_U32 PortIdx */
4204 /* action list 4 */
4205 FromPort = Param.Para32[0];
4206 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4207 ("PORT RESET EVENT, Port: %d ", FromPort));
4208 NewPara.Para64 = FromPort;
4209 SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
4210 spin_lock_irqsave(
4211 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4212 Flags);
4213
4214 SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST);
4215 pAC->dev[Param.Para32[0]]->flags &= ~IFF_RUNNING;
4216 spin_unlock_irqrestore(
4217 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4218 Flags);
4219
4220 /* clear rx ring from received frames */
4221 ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE);
4222
4223 ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
4224 spin_lock_irqsave(
4225 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4226 Flags);
4227
4228 /* tschilling: Handling of return value inserted. */
4229 if (SkGeInitPort(pAC, IoC, FromPort)) {
4230 if (FromPort == 0) {
4231 printk("%s: SkGeInitPort A failed.\n", pAC->dev[0]->name);
4232 } else {
4233 printk("%s: SkGeInitPort B failed.\n", pAC->dev[1]->name);
4234 }
4235 }
4236 SkAddrMcUpdate(pAC,IoC, FromPort);
4237 PortReInitBmu(pAC, FromPort);
4238 SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
4239 ClearAndStartRx(pAC, FromPort);
4240 spin_unlock_irqrestore(
4241 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4242 Flags);
4243 break;
4244 case SK_DRV_NET_UP: /* SK_U32 PortIdx */
4245 /* action list 5 */
4246 FromPort = Param.Para32[0];
4247 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4248 ("NET UP EVENT, Port: %d ", Param.Para32[0]));
4249 /* Mac update */
4250 SkAddrMcUpdate(pAC,IoC, FromPort);
4251
4252 if (DoPrintInterfaceChange) {
4253 printk("%s: network connection up using"
4254 " port %c\n", pAC->dev[Param.Para32[0]]->name, 'A'+Param.Para32[0]);
4255
4256 /* tschilling: Values changed according to LinkSpeedUsed. */
4257 Stat = pAC->GIni.GP[FromPort].PLinkSpeedUsed;
4258 if (Stat == SK_LSPEED_STAT_10MBPS) {
4259 printk(" speed: 10\n");
4260 } else if (Stat == SK_LSPEED_STAT_100MBPS) {
4261 printk(" speed: 100\n");
4262 } else if (Stat == SK_LSPEED_STAT_1000MBPS) {
4263 printk(" speed: 1000\n");
4264 } else {
4265 printk(" speed: unknown\n");
4266 }
4267
4268
4269 Stat = pAC->GIni.GP[FromPort].PLinkModeStatus;
4270 if (Stat == SK_LMODE_STAT_AUTOHALF ||
4271 Stat == SK_LMODE_STAT_AUTOFULL) {
4272 printk(" autonegotiation: yes\n");
4273 }
4274 else {
4275 printk(" autonegotiation: no\n");
4276 }
4277 if (Stat == SK_LMODE_STAT_AUTOHALF ||
4278 Stat == SK_LMODE_STAT_HALF) {
4279 printk(" duplex mode: half\n");
4280 }
4281 else {
4282 printk(" duplex mode: full\n");
4283 }
4284 Stat = pAC->GIni.GP[FromPort].PFlowCtrlStatus;
4285 if (Stat == SK_FLOW_STAT_REM_SEND ) {
4286 printk(" flowctrl: remote send\n");
4287 }
4288 else if (Stat == SK_FLOW_STAT_LOC_SEND ){
4289 printk(" flowctrl: local send\n");
4290 }
4291 else if (Stat == SK_FLOW_STAT_SYMMETRIC ){
4292 printk(" flowctrl: symmetric\n");
4293 }
4294 else {
4295 printk(" flowctrl: none\n");
4296 }
4297
4298 /* tschilling: Check against CopperType now. */
4299 if ((pAC->GIni.GICopperType == SK_TRUE) &&
4300 (pAC->GIni.GP[FromPort].PLinkSpeedUsed ==
4301 SK_LSPEED_STAT_1000MBPS)) {
4302 Stat = pAC->GIni.GP[FromPort].PMSStatus;
4303 if (Stat == SK_MS_STAT_MASTER ) {
4304 printk(" role: master\n");
4305 }
4306 else if (Stat == SK_MS_STAT_SLAVE ) {
4307 printk(" role: slave\n");
4308 }
4309 else {
4310 printk(" role: ???\n");
4311 }
4312 }
4313
4314 /*
4315 Display dim (dynamic interrupt moderation)
4316 informations
4317 */
4318 if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC)
4319 printk(" irq moderation: static (%d ints/sec)\n",
4320 pAC->DynIrqModInfo.MaxModIntsPerSec);
4321 else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC)
4322 printk(" irq moderation: dynamic (%d ints/sec)\n",
4323 pAC->DynIrqModInfo.MaxModIntsPerSec);
4324 else
4325 printk(" irq moderation: disabled\n");
4326
4327
4328#ifdef SK_ZEROCOPY
4329 if (pAC->ChipsetType)
4330#ifdef USE_SK_TX_CHECKSUM
4331 printk(" scatter-gather: enabled\n");
4332#else
4333 printk(" tx-checksum: disabled\n");
4334#endif
4335 else
4336 printk(" scatter-gather: disabled\n");
4337#else
4338 printk(" scatter-gather: disabled\n");
4339#endif
4340
4341#ifndef USE_SK_RX_CHECKSUM
4342 printk(" rx-checksum: disabled\n");
4343#endif
4344
4345 } else {
4346 DoPrintInterfaceChange = SK_TRUE;
4347 }
4348
4349 if ((Param.Para32[0] != pAC->ActivePort) &&
4350 (pAC->RlmtNets == 1)) {
4351 NewPara.Para32[0] = pAC->ActivePort;
4352 NewPara.Para32[1] = Param.Para32[0];
4353 SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_INTERN,
4354 NewPara);
4355 }
4356
4357 /* Inform the world that link protocol is up. */
4358 pAC->dev[Param.Para32[0]]->flags |= IFF_RUNNING;
4359
4360 break;
4361 case SK_DRV_NET_DOWN: /* SK_U32 Reason */
4362 /* action list 7 */
4363 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4364 ("NET DOWN EVENT "));
4365 if (DoPrintInterfaceChange) {
4366 printk("%s: network connection down\n",
4367 pAC->dev[Param.Para32[1]]->name);
4368 } else {
4369 DoPrintInterfaceChange = SK_TRUE;
4370 }
4371 pAC->dev[Param.Para32[1]]->flags &= ~IFF_RUNNING;
4372 break;
4373 case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
4374 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4375 ("PORT SWITCH HARD "));
4376 case SK_DRV_SWITCH_SOFT: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
4377 /* action list 6 */
4378 printk("%s: switching to port %c\n", pAC->dev[0]->name,
4379 'A'+Param.Para32[1]);
4380 case SK_DRV_SWITCH_INTERN: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
4381 FromPort = Param.Para32[0];
4382 ToPort = Param.Para32[1];
4383 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4384 ("PORT SWITCH EVENT, From: %d To: %d (Pref %d) ",
4385 FromPort, ToPort, pAC->Rlmt.Net[0].PrefPort));
4386 NewPara.Para64 = FromPort;
4387 SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
4388 NewPara.Para64 = ToPort;
4389 SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
4390 spin_lock_irqsave(
4391 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4392 Flags);
4393 spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
4394 SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST);
4395 SkGeStopPort(pAC, IoC, ToPort, SK_STOP_ALL, SK_SOFT_RST);
4396 spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
4397 spin_unlock_irqrestore(
4398 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4399 Flags);
4400
4401 ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); /* clears rx ring */
4402 ReceiveIrq(pAC, &pAC->RxPort[ToPort], SK_FALSE); /* clears rx ring */
4403
4404 ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
4405 ClearTxRing(pAC, &pAC->TxPort[ToPort][TX_PRIO_LOW]);
4406 spin_lock_irqsave(
4407 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4408 Flags);
4409 spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
4410 pAC->ActivePort = ToPort;
4411#if 0
4412 SetQueueSizes(pAC);
4413#else
4414 /* tschilling: New common function with minimum size check. */
4415 DualNet = SK_FALSE;
4416 if (pAC->RlmtNets == 2) {
4417 DualNet = SK_TRUE;
4418 }
4419
4420 if (SkGeInitAssignRamToQueues(
4421 pAC,
4422 pAC->ActivePort,
4423 DualNet)) {
4424 spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
4425 spin_unlock_irqrestore(
4426 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4427 Flags);
4428 printk("SkGeInitAssignRamToQueues failed.\n");
4429 break;
4430 }
4431#endif
4432 /* tschilling: Handling of return values inserted. */
4433 if (SkGeInitPort(pAC, IoC, FromPort) ||
4434 SkGeInitPort(pAC, IoC, ToPort)) {
4435 printk("%s: SkGeInitPort failed.\n", pAC->dev[0]->name);
4436 }
4437 if (Event == SK_DRV_SWITCH_SOFT) {
4438 SkMacRxTxEnable(pAC, IoC, FromPort);
4439 }
4440 SkMacRxTxEnable(pAC, IoC, ToPort);
4441 SkAddrSwap(pAC, IoC, FromPort, ToPort);
4442 SkAddrMcUpdate(pAC, IoC, FromPort);
4443 SkAddrMcUpdate(pAC, IoC, ToPort);
4444 PortReInitBmu(pAC, FromPort);
4445 PortReInitBmu(pAC, ToPort);
4446 SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
4447 SkGePollTxD(pAC, IoC, ToPort, SK_TRUE);
4448 ClearAndStartRx(pAC, FromPort);
4449 ClearAndStartRx(pAC, ToPort);
4450 spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
4451 spin_unlock_irqrestore(
4452 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4453 Flags);
4454 break;
4455 case SK_DRV_RLMT_SEND: /* SK_MBUF *pMb */
4456 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4457 ("RLS "));
4458 pRlmtMbuf = (SK_MBUF*) Param.pParaPtr;
4459 pMsg = (struct sk_buff*) pRlmtMbuf->pOs;
4460 skb_put(pMsg, pRlmtMbuf->Length);
4461 if (XmitFrame(pAC, &pAC->TxPort[pRlmtMbuf->PortIdx][TX_PRIO_LOW],
4462 pMsg) < 0)
4463
4464 DEV_KFREE_SKB_ANY(pMsg);
4465 break;
4466 case SK_DRV_TIMER:
4467 if (Param.Para32[0] == SK_DRV_MODERATION_TIMER) {
4468 /*
4469 ** expiration of the moderation timer implies that
4470 ** dynamic moderation is to be applied
4471 */
4472 SkDimStartModerationTimer(pAC);
4473 SkDimModerate(pAC);
4474 if (pAC->DynIrqModInfo.DisplayStats) {
4475 SkDimDisplayModerationSettings(pAC);
4476 }
4477 } else if (Param.Para32[0] == SK_DRV_RX_CLEANUP_TIMER) {
4478 /*
4479 ** check if we need to check for descriptors which
4480 ** haven't been handled the last millisecs
4481 */
4482 StartDrvCleanupTimer(pAC);
4483 if (pAC->GIni.GIMacsFound == 2) {
4484 ReceiveIrq(pAC, &pAC->RxPort[1], SK_FALSE);
4485 }
4486 ReceiveIrq(pAC, &pAC->RxPort[0], SK_FALSE);
4487 } else {
4488 printk("Expiration of unknown timer\n");
4489 }
4490 break;
4491 default:
4492 break;
4493 }
4494 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4495 ("END EVENT "));
4496
4497 return (0);
4498} /* SkDrvEvent */
4499
4500
4501/*****************************************************************************
4502 *
4503 * SkErrorLog - log errors
4504 *
4505 * Description:
4506 * This function logs errors to the system buffer and to the console
4507 *
4508 * Returns:
4509 * 0 if everything ok
4510 * < 0 on error
4511 *
4512 */
4513void SkErrorLog(
4514SK_AC *pAC,
4515int ErrClass,
4516int ErrNum,
4517char *pErrorMsg)
4518{
4519char ClassStr[80];
4520
4521 switch (ErrClass) {
4522 case SK_ERRCL_OTHER:
4523 strcpy(ClassStr, "Other error");
4524 break;
4525 case SK_ERRCL_CONFIG:
4526 strcpy(ClassStr, "Configuration error");
4527 break;
4528 case SK_ERRCL_INIT:
4529 strcpy(ClassStr, "Initialization error");
4530 break;
4531 case SK_ERRCL_NORES:
4532 strcpy(ClassStr, "Out of resources error");
4533 break;
4534 case SK_ERRCL_SW:
4535 strcpy(ClassStr, "internal Software error");
4536 break;
4537 case SK_ERRCL_HW:
4538 strcpy(ClassStr, "Hardware failure");
4539 break;
4540 case SK_ERRCL_COMM:
4541 strcpy(ClassStr, "Communication error");
4542 break;
4543 }
4544 printk(KERN_INFO "%s: -- ERROR --\n Class: %s\n"
4545 " Nr: 0x%x\n Msg: %s\n", pAC->dev[0]->name,
4546 ClassStr, ErrNum, pErrorMsg);
4547
4548} /* SkErrorLog */
4549
4550#ifdef SK_DIAG_SUPPORT
4551
4552/*****************************************************************************
4553 *
4554 * SkDrvEnterDiagMode - handles DIAG attach request
4555 *
4556 * Description:
4557 * Notify the kernel to NOT access the card any longer due to DIAG
4558 * Deinitialize the Card
4559 *
4560 * Returns:
4561 * int
4562 */
4563int SkDrvEnterDiagMode(
4564SK_AC *pAc) /* pointer to adapter context */
4565{
4566 DEV_NET *pNet = netdev_priv(pAc->dev[0]);
4567 SK_AC *pAC = pNet->pAC;
4568
4569 SK_MEMCPY(&(pAc->PnmiBackup), &(pAc->PnmiStruct),
4570 sizeof(SK_PNMI_STRUCT_DATA));
4571
4572 pAC->DiagModeActive = DIAG_ACTIVE;
4573 if (pAC->BoardLevel > SK_INIT_DATA) {
4574 if (pNet->Up) {
4575 pAC->WasIfUp[0] = SK_TRUE;
4576 pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
4577 DoPrintInterfaceChange = SK_FALSE;
4578 SkDrvDeInitAdapter(pAC, 0); /* performs SkGeClose */
4579 } else {
4580 pAC->WasIfUp[0] = SK_FALSE;
4581 }
4582 if (pNet != netdev_priv(pAC->dev[1])) {
4583 pNet = netdev_priv(pAC->dev[1]);
4584 if (pNet->Up) {
4585 pAC->WasIfUp[1] = SK_TRUE;
4586 pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
4587 DoPrintInterfaceChange = SK_FALSE;
4588 SkDrvDeInitAdapter(pAC, 1); /* do SkGeClose */
4589 } else {
4590 pAC->WasIfUp[1] = SK_FALSE;
4591 }
4592 }
4593 pAC->BoardLevel = SK_INIT_DATA;
4594 }
4595 return(0);
4596}
4597
4598/*****************************************************************************
4599 *
4600 * SkDrvLeaveDiagMode - handles DIAG detach request
4601 *
4602 * Description:
4603 * Notify the kernel to may access the card again after use by DIAG
4604 * Initialize the Card
4605 *
4606 * Returns:
4607 * int
4608 */
4609int SkDrvLeaveDiagMode(
4610SK_AC *pAc) /* pointer to adapter control context */
4611{
4612 SK_MEMCPY(&(pAc->PnmiStruct), &(pAc->PnmiBackup),
4613 sizeof(SK_PNMI_STRUCT_DATA));
4614 pAc->DiagModeActive = DIAG_NOTACTIVE;
4615 pAc->Pnmi.DiagAttached = SK_DIAG_IDLE;
4616 if (pAc->WasIfUp[0] == SK_TRUE) {
4617 pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
4618 DoPrintInterfaceChange = SK_FALSE;
4619 SkDrvInitAdapter(pAc, 0); /* first device */
4620 }
4621 if (pAc->WasIfUp[1] == SK_TRUE) {
4622 pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
4623 DoPrintInterfaceChange = SK_FALSE;
4624 SkDrvInitAdapter(pAc, 1); /* second device */
4625 }
4626 return(0);
4627}
4628
4629/*****************************************************************************
4630 *
4631 * ParseDeviceNbrFromSlotName - Evaluate PCI device number
4632 *
4633 * Description:
4634 * This function parses the PCI slot name information string and will
4635 * retrieve the devcie number out of it. The slot_name maintianed by
4636 * linux is in the form of '02:0a.0', whereas the first two characters
4637 * represent the bus number in hex (in the sample above this is
4638 * pci bus 0x02) and the next two characters the device number (0x0a).
4639 *
4640 * Returns:
4641 * SK_U32: The device number from the PCI slot name
4642 */
4643
4644static SK_U32 ParseDeviceNbrFromSlotName(
4645const char *SlotName) /* pointer to pci slot name eg. '02:0a.0' */
4646{
4647 char *CurrCharPos = (char *) SlotName;
4648 int FirstNibble = -1;
4649 int SecondNibble = -1;
4650 SK_U32 Result = 0;
4651
4652 while (*CurrCharPos != '\0') {
4653 if (*CurrCharPos == ':') {
4654 while (*CurrCharPos != '.') {
4655 CurrCharPos++;
4656 if ( (*CurrCharPos >= '0') &&
4657 (*CurrCharPos <= '9')) {
4658 if (FirstNibble == -1) {
4659 /* dec. value for '0' */
4660 FirstNibble = *CurrCharPos - 48;
4661 } else {
4662 SecondNibble = *CurrCharPos - 48;
4663 }
4664 } else if ( (*CurrCharPos >= 'a') &&
4665 (*CurrCharPos <= 'f') ) {
4666 if (FirstNibble == -1) {
4667 FirstNibble = *CurrCharPos - 87;
4668 } else {
4669 SecondNibble = *CurrCharPos - 87;
4670 }
4671 } else {
4672 Result = 0;
4673 }
4674 }
4675
4676 Result = FirstNibble;
4677 Result = Result << 4; /* first nibble is higher one */
4678 Result = Result | SecondNibble;
4679 }
4680 CurrCharPos++; /* next character */
4681 }
4682 return (Result);
4683}
4684
4685/****************************************************************************
4686 *
4687 * SkDrvDeInitAdapter - deinitialize adapter (this function is only
4688 * called if Diag attaches to that card)
4689 *
4690 * Description:
4691 * Close initialized adapter.
4692 *
4693 * Returns:
4694 * 0 - on success
4695 * error code - on error
4696 */
4697static int SkDrvDeInitAdapter(
4698SK_AC *pAC, /* pointer to adapter context */
4699int devNbr) /* what device is to be handled */
4700{
4701 struct SK_NET_DEVICE *dev;
4702
4703 dev = pAC->dev[devNbr];
4704
4705 /* On Linux 2.6 the network driver does NOT mess with reference
4706 ** counts. The driver MUST be able to be unloaded at any time
4707 ** due to the possibility of hotplug.
4708 */
4709 if (SkGeClose(dev) != 0) {
4710 return (-1);
4711 }
4712 return (0);
4713
4714} /* SkDrvDeInitAdapter() */
4715
4716/****************************************************************************
4717 *
4718 * SkDrvInitAdapter - Initialize adapter (this function is only
4719 * called if Diag deattaches from that card)
4720 *
4721 * Description:
4722 * Close initialized adapter.
4723 *
4724 * Returns:
4725 * 0 - on success
4726 * error code - on error
4727 */
4728static int SkDrvInitAdapter(
4729SK_AC *pAC, /* pointer to adapter context */
4730int devNbr) /* what device is to be handled */
4731{
4732 struct SK_NET_DEVICE *dev;
4733
4734 dev = pAC->dev[devNbr];
4735
4736 if (SkGeOpen(dev) != 0) {
4737 return (-1);
4738 }
4739
4740 /*
4741 ** Use correct MTU size and indicate to kernel TX queue can be started
4742 */
4743 if (SkGeChangeMtu(dev, dev->mtu) != 0) {
4744 return (-1);
4745 }
4746 return (0);
4747
4748} /* SkDrvInitAdapter */
4749
4750#endif
4751
4752#ifdef DEBUG
4753/****************************************************************************/
4754/* "debug only" section *****************************************************/
4755/****************************************************************************/
4756
4757
4758/*****************************************************************************
4759 *
4760 * DumpMsg - print a frame
4761 *
4762 * Description:
4763 * This function prints frames to the system logfile/to the console.
4764 *
4765 * Returns: N/A
4766 *
4767 */
4768static void DumpMsg(struct sk_buff *skb, char *str)
4769{
4770 int msglen;
4771
4772 if (skb == NULL) {
4773 printk("DumpMsg(): NULL-Message\n");
4774 return;
4775 }
4776
4777 if (skb->data == NULL) {
4778 printk("DumpMsg(): Message empty\n");
4779 return;
4780 }
4781
4782 msglen = skb->len;
4783 if (msglen > 64)
4784 msglen = 64;
4785
4786 printk("--- Begin of message from %s , len %d (from %d) ----\n", str, msglen, skb->len);
4787
4788 DumpData((char *)skb->data, msglen);
4789
4790 printk("------- End of message ---------\n");
4791} /* DumpMsg */
4792
4793
4794
4795/*****************************************************************************
4796 *
4797 * DumpData - print a data area
4798 *
4799 * Description:
4800 * This function prints a area of data to the system logfile/to the
4801 * console.
4802 *
4803 * Returns: N/A
4804 *
4805 */
4806static void DumpData(char *p, int size)
4807{
4808register int i;
4809int haddr, addr;
4810char hex_buffer[180];
4811char asc_buffer[180];
4812char HEXCHAR[] = "0123456789ABCDEF";
4813
4814 addr = 0;
4815 haddr = 0;
4816 hex_buffer[0] = 0;
4817 asc_buffer[0] = 0;
4818 for (i=0; i < size; ) {
4819 if (*p >= '0' && *p <='z')
4820 asc_buffer[addr] = *p;
4821 else
4822 asc_buffer[addr] = '.';
4823 addr++;
4824 asc_buffer[addr] = 0;
4825 hex_buffer[haddr] = HEXCHAR[(*p & 0xf0) >> 4];
4826 haddr++;
4827 hex_buffer[haddr] = HEXCHAR[*p & 0x0f];
4828 haddr++;
4829 hex_buffer[haddr] = ' ';
4830 haddr++;
4831 hex_buffer[haddr] = 0;
4832 p++;
4833 i++;
4834 if (i%16 == 0) {
4835 printk("%s %s\n", hex_buffer, asc_buffer);
4836 addr = 0;
4837 haddr = 0;
4838 }
4839 }
4840} /* DumpData */
4841
4842
4843/*****************************************************************************
4844 *
4845 * DumpLong - print a data area as long values
4846 *
4847 * Description:
4848 * This function prints a area of data to the system logfile/to the
4849 * console.
4850 *
4851 * Returns: N/A
4852 *
4853 */
4854static void DumpLong(char *pc, int size)
4855{
4856register int i;
4857int haddr, addr;
4858char hex_buffer[180];
4859char asc_buffer[180];
4860char HEXCHAR[] = "0123456789ABCDEF";
4861long *p;
4862int l;
4863
4864 addr = 0;
4865 haddr = 0;
4866 hex_buffer[0] = 0;
4867 asc_buffer[0] = 0;
4868 p = (long*) pc;
4869 for (i=0; i < size; ) {
4870 l = (long) *p;
4871 hex_buffer[haddr] = HEXCHAR[(l >> 28) & 0xf];
4872 haddr++;
4873 hex_buffer[haddr] = HEXCHAR[(l >> 24) & 0xf];
4874 haddr++;
4875 hex_buffer[haddr] = HEXCHAR[(l >> 20) & 0xf];
4876 haddr++;
4877 hex_buffer[haddr] = HEXCHAR[(l >> 16) & 0xf];
4878 haddr++;
4879 hex_buffer[haddr] = HEXCHAR[(l >> 12) & 0xf];
4880 haddr++;
4881 hex_buffer[haddr] = HEXCHAR[(l >> 8) & 0xf];
4882 haddr++;
4883 hex_buffer[haddr] = HEXCHAR[(l >> 4) & 0xf];
4884 haddr++;
4885 hex_buffer[haddr] = HEXCHAR[l & 0x0f];
4886 haddr++;
4887 hex_buffer[haddr] = ' ';
4888 haddr++;
4889 hex_buffer[haddr] = 0;
4890 p++;
4891 i++;
4892 if (i%8 == 0) {
4893 printk("%4x %s\n", (i-8)*4, hex_buffer);
4894 haddr = 0;
4895 }
4896 }
4897 printk("------------------------\n");
4898} /* DumpLong */
4899
4900#endif
4901
4902static int __devinit skge_probe_one(struct pci_dev *pdev,
4903 const struct pci_device_id *ent)
4904{
4905 SK_AC *pAC;
4906 DEV_NET *pNet = NULL;
4907 struct net_device *dev = NULL;
4908 static int boards_found = 0;
4909 int error = -ENODEV;
4910
4911 if (pci_enable_device(pdev))
4912 goto out;
4913
4914 /* Configure DMA attributes. */
4915 if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL) &&
4916 pci_set_dma_mask(pdev, (u64) 0xffffffff))
4917 goto out_disable_device;
4918
4919
4920 if ((dev = alloc_etherdev(sizeof(DEV_NET))) == NULL) {
4921 printk(KERN_ERR "Unable to allocate etherdev "
4922 "structure!\n");
4923 goto out_disable_device;
4924 }
4925
4926 pNet = netdev_priv(dev);
4927 pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL);
4928 if (!pNet->pAC) {
4929 printk(KERN_ERR "Unable to allocate adapter "
4930 "structure!\n");
4931 goto out_free_netdev;
4932 }
4933
4934 memset(pNet->pAC, 0, sizeof(SK_AC));
4935 pAC = pNet->pAC;
4936 pAC->PciDev = pdev;
4937 pAC->PciDevId = pdev->device;
4938 pAC->dev[0] = dev;
4939 pAC->dev[1] = dev;
4940 sprintf(pAC->Name, "SysKonnect SK-98xx");
4941 pAC->CheckQueue = SK_FALSE;
4942
4943 pNet->Mtu = 1500;
4944 pNet->Up = 0;
4945 dev->irq = pdev->irq;
4946 error = SkGeInitPCI(pAC);
4947 if (error) {
4948 printk("SKGE: PCI setup failed: %i\n", error);
4949 goto out_free_netdev;
4950 }
4951
4952 SET_MODULE_OWNER(dev);
4953 dev->open = &SkGeOpen;
4954 dev->stop = &SkGeClose;
4955 dev->hard_start_xmit = &SkGeXmit;
4956 dev->get_stats = &SkGeStats;
4957 dev->set_multicast_list = &SkGeSetRxMode;
4958 dev->set_mac_address = &SkGeSetMacAddr;
4959 dev->do_ioctl = &SkGeIoctl;
4960 dev->change_mtu = &SkGeChangeMtu;
4961#ifdef CONFIG_NET_POLL_CONTROLLER
4962 dev->poll_controller = &SkGePollController;
4963#endif
4964 dev->flags &= ~IFF_RUNNING;
4965 SET_NETDEV_DEV(dev, &pdev->dev);
4966 SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
4967
4968#ifdef SK_ZEROCOPY
4969#ifdef USE_SK_TX_CHECKSUM
4970 if (pAC->ChipsetType) {
4971 /* Use only if yukon hardware */
4972 /* SK and ZEROCOPY - fly baby... */
4973 dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
4974 }
4975#endif
4976#endif
4977
4978 pAC->Index = boards_found++;
4979
4980 if (SkGeBoardInit(dev, pAC))
4981 goto out_free_netdev;
4982
4983 /* Register net device */
4984 if (register_netdev(dev)) {
4985 printk(KERN_ERR "SKGE: Could not register device.\n");
4986 goto out_free_resources;
4987 }
4988
4989 /* Print adapter specific string from vpd */
4990 ProductStr(pAC);
4991 printk("%s: %s\n", dev->name, pAC->DeviceStr);
4992
4993 /* Print configuration settings */
4994 printk(" PrefPort:%c RlmtMode:%s\n",
4995 'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber,
4996 (pAC->RlmtMode==0) ? "Check Link State" :
4997 ((pAC->RlmtMode==1) ? "Check Link State" :
4998 ((pAC->RlmtMode==3) ? "Check Local Port" :
4999 ((pAC->RlmtMode==7) ? "Check Segmentation" :
5000 ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error")))));
5001
5002 SkGeYellowLED(pAC, pAC->IoBase, 1);
5003
5004
5005 memcpy(&dev->dev_addr, &pAC->Addr.Net[0].CurrentMacAddress, 6);
5006
5007 SkGeProcCreate(dev);
5008
5009 pNet->PortNr = 0;
5010 pNet->NetNr = 0;
5011
5012 boards_found++;
5013
5014 /* More then one port found */
5015 if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
5016 if ((dev = alloc_etherdev(sizeof(DEV_NET))) == 0) {
5017 printk(KERN_ERR "Unable to allocate etherdev "
5018 "structure!\n");
5019 goto out;
5020 }
5021
5022 pAC->dev[1] = dev;
5023 pNet = netdev_priv(dev);
5024 pNet->PortNr = 1;
5025 pNet->NetNr = 1;
5026 pNet->pAC = pAC;
5027 pNet->Mtu = 1500;
5028 pNet->Up = 0;
5029
5030 dev->open = &SkGeOpen;
5031 dev->stop = &SkGeClose;
5032 dev->hard_start_xmit = &SkGeXmit;
5033 dev->get_stats = &SkGeStats;
5034 dev->set_multicast_list = &SkGeSetRxMode;
5035 dev->set_mac_address = &SkGeSetMacAddr;
5036 dev->do_ioctl = &SkGeIoctl;
5037 dev->change_mtu = &SkGeChangeMtu;
5038 dev->flags &= ~IFF_RUNNING;
5039 SET_NETDEV_DEV(dev, &pdev->dev);
5040 SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
5041
5042#ifdef SK_ZEROCOPY
5043#ifdef USE_SK_TX_CHECKSUM
5044 if (pAC->ChipsetType) {
5045 /* SG and ZEROCOPY - fly baby... */
5046 dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
5047 }
5048#endif
5049#endif
5050
5051 if (register_netdev(dev)) {
5052 printk(KERN_ERR "SKGE: Could not register device.\n");
5053 free_netdev(dev);
5054 pAC->dev[1] = pAC->dev[0];
5055 } else {
5056 SkGeProcCreate(dev);
5057 memcpy(&dev->dev_addr,
5058 &pAC->Addr.Net[1].CurrentMacAddress, 6);
5059
5060 printk("%s: %s\n", dev->name, pAC->DeviceStr);
5061 printk(" PrefPort:B RlmtMode:Dual Check Link State\n");
5062 }
5063 }
5064
5065 /* Save the hardware revision */
5066 pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) +
5067 (pAC->GIni.GIPciHwRev & 0x0F);
5068
5069 /* Set driver globals */
5070 pAC->Pnmi.pDriverFileName = DRIVER_FILE_NAME;
5071 pAC->Pnmi.pDriverReleaseDate = DRIVER_REL_DATE;
5072
5073 memset(&pAC->PnmiBackup, 0, sizeof(SK_PNMI_STRUCT_DATA));
5074 memcpy(&pAC->PnmiBackup, &pAC->PnmiStruct, sizeof(SK_PNMI_STRUCT_DATA));
5075
5076 pci_set_drvdata(pdev, dev);
5077 return 0;
5078
5079 out_free_resources:
5080 FreeResources(dev);
5081 out_free_netdev:
5082 free_netdev(dev);
5083 out_disable_device:
5084 pci_disable_device(pdev);
5085 out:
5086 return error;
5087}
5088
5089static void __devexit skge_remove_one(struct pci_dev *pdev)
5090{
5091 struct net_device *dev = pci_get_drvdata(pdev);
5092 DEV_NET *pNet = netdev_priv(dev);
5093 SK_AC *pAC = pNet->pAC;
5094 struct net_device *otherdev = pAC->dev[1];
5095
5096 SkGeProcRemove(dev);
5097 unregister_netdev(dev);
5098 if (otherdev != dev)
5099 SkGeProcRemove(otherdev);
5100
5101 SkGeYellowLED(pAC, pAC->IoBase, 0);
5102
5103 if (pAC->BoardLevel == SK_INIT_RUN) {
5104 SK_EVPARA EvPara;
5105 unsigned long Flags;
5106
5107 /* board is still alive */
5108 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
5109 EvPara.Para32[0] = 0;
5110 EvPara.Para32[1] = -1;
5111 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
5112 EvPara.Para32[0] = 1;
5113 EvPara.Para32[1] = -1;
5114 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
5115 SkEventDispatcher(pAC, pAC->IoBase);
5116 /* disable interrupts */
5117 SK_OUT32(pAC->IoBase, B0_IMSK, 0);
5118 SkGeDeInit(pAC, pAC->IoBase);
5119 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
5120 pAC->BoardLevel = SK_INIT_DATA;
5121 /* We do NOT check here, if IRQ was pending, of course*/
5122 }
5123
5124 if (pAC->BoardLevel == SK_INIT_IO) {
5125 /* board is still alive */
5126 SkGeDeInit(pAC, pAC->IoBase);
5127 pAC->BoardLevel = SK_INIT_DATA;
5128 }
5129
5130 FreeResources(dev);
5131 free_netdev(dev);
5132 if (otherdev != dev)
5133 free_netdev(otherdev);
5134 kfree(pAC);
5135}
5136
5137static struct pci_device_id skge_pci_tbl[] = {
5138 { PCI_VENDOR_ID_3COM, 0x1700, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5139 { PCI_VENDOR_ID_3COM, 0x80eb, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5140 { PCI_VENDOR_ID_SYSKONNECT, 0x4300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5141 { PCI_VENDOR_ID_SYSKONNECT, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5142 { PCI_VENDOR_ID_DLINK, 0x4c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5143 { PCI_VENDOR_ID_MARVELL, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5144#if 0 /* don't handle Yukon2 cards at the moment -- mlindner@syskonnect.de */
5145 { PCI_VENDOR_ID_MARVELL, 0x4360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5146 { PCI_VENDOR_ID_MARVELL, 0x4361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5147#endif
5148 { PCI_VENDOR_ID_MARVELL, 0x5005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5149 { PCI_VENDOR_ID_CNET, 0x434e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5150 { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5151 { PCI_VENDOR_ID_LINKSYS, 0x1064, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5152 { 0, }
5153};
5154
5155MODULE_DEVICE_TABLE(pci, skge_pci_tbl);
5156
5157static struct pci_driver skge_driver = {
5158 .name = "sk98lin",
5159 .id_table = skge_pci_tbl,
5160 .probe = skge_probe_one,
5161 .remove = __devexit_p(skge_remove_one),
5162};
5163
5164static int __init skge_init(void)
5165{
5166 int error;
5167
5168 pSkRootDir = proc_mkdir(SKRootName, proc_net);
5169 if (pSkRootDir)
5170 pSkRootDir->owner = THIS_MODULE;
5171
5172 error = pci_register_driver(&skge_driver);
5173 if (error)
5174 proc_net_remove(SKRootName);
5175 return error;
5176}
5177
5178static void __exit skge_exit(void)
5179{
5180 pci_unregister_driver(&skge_driver);
5181 proc_net_remove(SKRootName);
5182
5183}
5184
5185module_init(skge_init);
5186module_exit(skge_exit);
diff --git a/drivers/net/sk98lin/skgehwt.c b/drivers/net/sk98lin/skgehwt.c
new file mode 100644
index 000000000000..db670993c2df
--- /dev/null
+++ b/drivers/net/sk98lin/skgehwt.c
@@ -0,0 +1,171 @@
1/******************************************************************************
2 *
3 * Name: skgehwt.c
4 * Project: Gigabit Ethernet Adapters, Event Scheduler Module
5 * Version: $Revision: 1.15 $
6 * Date: $Date: 2003/09/16 13:41:23 $
7 * Purpose: Hardware Timer
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * Event queue and dispatcher
27 */
28#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
29static const char SysKonnectFileId[] =
30 "@(#) $Id: skgehwt.c,v 1.15 2003/09/16 13:41:23 rschmidt Exp $ (C) Marvell.";
31#endif
32
33#include "h/skdrv1st.h" /* Driver Specific Definitions */
34#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
35
36#ifdef __C2MAN__
37/*
38 * Hardware Timer function queue management.
39 */
40intro()
41{}
42#endif
43
44/*
45 * Prototypes of local functions.
46 */
47#define SK_HWT_MAX (65000)
48
49/* correction factor */
50#define SK_HWT_FAC (1000 * (SK_U32)pAC->GIni.GIHstClkFact / 100)
51
52/*
53 * Initialize hardware timer.
54 *
55 * Must be called during init level 1.
56 */
57void SkHwtInit(
58SK_AC *pAC, /* Adapters context */
59SK_IOC Ioc) /* IoContext */
60{
61 pAC->Hwt.TStart = 0 ;
62 pAC->Hwt.TStop = 0 ;
63 pAC->Hwt.TActive = SK_FALSE;
64
65 SkHwtStop(pAC, Ioc);
66}
67
68/*
69 *
70 * Start hardware timer (clock ticks are 16us).
71 *
72 */
73void SkHwtStart(
74SK_AC *pAC, /* Adapters context */
75SK_IOC Ioc, /* IoContext */
76SK_U32 Time) /* Time in units of 16us to load the timer with. */
77{
78 SK_U32 Cnt;
79
80 if (Time > SK_HWT_MAX)
81 Time = SK_HWT_MAX;
82
83 pAC->Hwt.TStart = Time;
84 pAC->Hwt.TStop = 0L;
85
86 Cnt = Time;
87
88 /*
89 * if time < 16 us
90 * time = 16 us
91 */
92 if (!Cnt) {
93 Cnt++;
94 }
95
96 SK_OUT32(Ioc, B2_TI_INI, Cnt * SK_HWT_FAC);
97
98 SK_OUT16(Ioc, B2_TI_CTRL, TIM_START); /* Start timer. */
99
100 pAC->Hwt.TActive = SK_TRUE;
101}
102
103/*
104 * Stop hardware timer.
105 * and clear the timer IRQ
106 */
107void SkHwtStop(
108SK_AC *pAC, /* Adapters context */
109SK_IOC Ioc) /* IoContext */
110{
111 SK_OUT16(Ioc, B2_TI_CTRL, TIM_STOP);
112
113 SK_OUT16(Ioc, B2_TI_CTRL, TIM_CLR_IRQ);
114
115 pAC->Hwt.TActive = SK_FALSE;
116}
117
118
119/*
120 * Stop hardware timer and read time elapsed since last start.
121 *
122 * returns
123 * The elapsed time since last start in units of 16us.
124 *
125 */
126SK_U32 SkHwtRead(
127SK_AC *pAC, /* Adapters context */
128SK_IOC Ioc) /* IoContext */
129{
130 SK_U32 TRead;
131 SK_U32 IStatus;
132
133 if (pAC->Hwt.TActive) {
134
135 SkHwtStop(pAC, Ioc);
136
137 SK_IN32(Ioc, B2_TI_VAL, &TRead);
138 TRead /= SK_HWT_FAC;
139
140 SK_IN32(Ioc, B0_ISRC, &IStatus);
141
142 /* Check if timer expired (or wraped around) */
143 if ((TRead > pAC->Hwt.TStart) || (IStatus & IS_TIMINT)) {
144
145 SkHwtStop(pAC, Ioc);
146
147 pAC->Hwt.TStop = pAC->Hwt.TStart;
148 }
149 else {
150
151 pAC->Hwt.TStop = pAC->Hwt.TStart - TRead;
152 }
153 }
154 return(pAC->Hwt.TStop);
155}
156
157/*
158 * interrupt source= timer
159 */
160void SkHwtIsr(
161SK_AC *pAC, /* Adapters context */
162SK_IOC Ioc) /* IoContext */
163{
164 SkHwtStop(pAC, Ioc);
165
166 pAC->Hwt.TStop = pAC->Hwt.TStart;
167
168 SkTimerDone(pAC, Ioc);
169}
170
171/* End of file */
diff --git a/drivers/net/sk98lin/skgeinit.c b/drivers/net/sk98lin/skgeinit.c
new file mode 100644
index 000000000000..df4483429a77
--- /dev/null
+++ b/drivers/net/sk98lin/skgeinit.c
@@ -0,0 +1,2151 @@
1/******************************************************************************
2 *
3 * Name: skgeinit.c
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.97 $
6 * Date: $Date: 2003/10/02 16:45:31 $
7 * Purpose: Contains functions to initialize the adapter
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#include "h/skdrv1st.h"
26#include "h/skdrv2nd.h"
27
28/* global variables ***********************************************************/
29
30/* local variables ************************************************************/
31
32#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
33static const char SysKonnectFileId[] =
34 "@(#) $Id: skgeinit.c,v 1.97 2003/10/02 16:45:31 rschmidt Exp $ (C) Marvell.";
35#endif
36
37struct s_QOffTab {
38 int RxQOff; /* Receive Queue Address Offset */
39 int XsQOff; /* Sync Tx Queue Address Offset */
40 int XaQOff; /* Async Tx Queue Address Offset */
41};
42static struct s_QOffTab QOffTab[] = {
43 {Q_R1, Q_XS1, Q_XA1}, {Q_R2, Q_XS2, Q_XA2}
44};
45
46struct s_Config {
47 char ScanString[8];
48 SK_U32 Value;
49};
50
51static struct s_Config OemConfig = {
52 {'O','E','M','_','C','o','n','f'},
53#ifdef SK_OEM_CONFIG
54 OEM_CONFIG_VALUE,
55#else
56 0,
57#endif
58};
59
60/******************************************************************************
61 *
62 * SkGePollRxD() - Enable / Disable Descriptor Polling of RxD Ring
63 *
64 * Description:
65 * Enable or disable the descriptor polling of the receive descriptor
66 * ring (RxD) for port 'Port'.
67 * The new configuration is *not* saved over any SkGeStopPort() and
68 * SkGeInitPort() calls.
69 *
70 * Returns:
71 * nothing
72 */
73void SkGePollRxD(
74SK_AC *pAC, /* adapter context */
75SK_IOC IoC, /* IO context */
76int Port, /* Port Index (MAC_1 + n) */
77SK_BOOL PollRxD) /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */
78{
79 SK_GEPORT *pPrt;
80
81 pPrt = &pAC->GIni.GP[Port];
82
83 SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), (PollRxD) ?
84 CSR_ENA_POL : CSR_DIS_POL);
85} /* SkGePollRxD */
86
87
88/******************************************************************************
89 *
90 * SkGePollTxD() - Enable / Disable Descriptor Polling of TxD Rings
91 *
92 * Description:
93 * Enable or disable the descriptor polling of the transmit descriptor
94 * ring(s) (TxD) for port 'Port'.
95 * The new configuration is *not* saved over any SkGeStopPort() and
96 * SkGeInitPort() calls.
97 *
98 * Returns:
99 * nothing
100 */
101void SkGePollTxD(
102SK_AC *pAC, /* adapter context */
103SK_IOC IoC, /* IO context */
104int Port, /* Port Index (MAC_1 + n) */
105SK_BOOL PollTxD) /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */
106{
107 SK_GEPORT *pPrt;
108 SK_U32 DWord;
109
110 pPrt = &pAC->GIni.GP[Port];
111
112 DWord = (SK_U32)(PollTxD ? CSR_ENA_POL : CSR_DIS_POL);
113
114 if (pPrt->PXSQSize != 0) {
115 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), DWord);
116 }
117
118 if (pPrt->PXAQSize != 0) {
119 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), DWord);
120 }
121} /* SkGePollTxD */
122
123
124/******************************************************************************
125 *
126 * SkGeYellowLED() - Switch the yellow LED on or off.
127 *
128 * Description:
129 * Switch the yellow LED on or off.
130 *
131 * Note:
132 * This function may be called any time after SkGeInit(Level 1).
133 *
134 * Returns:
135 * nothing
136 */
137void SkGeYellowLED(
138SK_AC *pAC, /* adapter context */
139SK_IOC IoC, /* IO context */
140int State) /* yellow LED state, 0 = OFF, 0 != ON */
141{
142 if (State == 0) {
143 /* Switch yellow LED OFF */
144 SK_OUT8(IoC, B0_LED, LED_STAT_OFF);
145 }
146 else {
147 /* Switch yellow LED ON */
148 SK_OUT8(IoC, B0_LED, LED_STAT_ON);
149 }
150} /* SkGeYellowLED */
151
152
153#if (!defined(SK_SLIM) || defined(GENESIS))
154/******************************************************************************
155 *
156 * SkGeXmitLED() - Modify the Operational Mode of a transmission LED.
157 *
158 * Description:
159 * The Rx or Tx LED which is specified by 'Led' will be
160 * enabled, disabled or switched on in test mode.
161 *
162 * Note:
163 * 'Led' must contain the address offset of the LEDs INI register.
164 *
165 * Usage:
166 * SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA);
167 *
168 * Returns:
169 * nothing
170 */
171void SkGeXmitLED(
172SK_AC *pAC, /* adapter context */
173SK_IOC IoC, /* IO context */
174int Led, /* offset to the LED Init Value register */
175int Mode) /* Mode may be SK_LED_DIS, SK_LED_ENA, SK_LED_TST */
176{
177 SK_U32 LedIni;
178
179 switch (Mode) {
180 case SK_LED_ENA:
181 LedIni = SK_XMIT_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100;
182 SK_OUT32(IoC, Led + XMIT_LED_INI, LedIni);
183 SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START);
184 break;
185 case SK_LED_TST:
186 SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_ON);
187 SK_OUT32(IoC, Led + XMIT_LED_CNT, 100);
188 SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START);
189 break;
190 case SK_LED_DIS:
191 default:
192 /*
193 * Do NOT stop the LED Timer here. The LED might be
194 * in on state. But it needs to go off.
195 */
196 SK_OUT32(IoC, Led + XMIT_LED_CNT, 0);
197 SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_OFF);
198 break;
199 }
200
201 /*
202 * 1000BT: The Transmit LED is driven by the PHY.
203 * But the default LED configuration is used for
204 * Level One and Broadcom PHYs.
205 * (Broadcom: It may be that PHY_B_PEC_EN_LTR has to be set.)
206 * (In this case it has to be added here. But we will see. XXX)
207 */
208} /* SkGeXmitLED */
209#endif /* !SK_SLIM || GENESIS */
210
211
212/******************************************************************************
213 *
214 * DoCalcAddr() - Calculates the start and the end address of a queue.
215 *
216 * Description:
217 * This function calculates the start and the end address of a queue.
218 * Afterwards the 'StartVal' is incremented to the next start position.
219 * If the port is already initialized the calculated values
220 * will be checked against the configured values and an
221 * error will be returned, if they are not equal.
222 * If the port is not initialized the values will be written to
223 * *StartAdr and *EndAddr.
224 *
225 * Returns:
226 * 0: success
227 * 1: configuration error
228 */
229static int DoCalcAddr(
230SK_AC *pAC, /* adapter context */
231SK_GEPORT SK_FAR *pPrt, /* port index */
232int QuSize, /* size of the queue to configure in kB */
233SK_U32 SK_FAR *StartVal, /* start value for address calculation */
234SK_U32 SK_FAR *QuStartAddr,/* start addr to calculate */
235SK_U32 SK_FAR *QuEndAddr) /* end address to calculate */
236{
237 SK_U32 EndVal;
238 SK_U32 NextStart;
239 int Rtv;
240
241 Rtv = 0;
242 if (QuSize == 0) {
243 EndVal = *StartVal;
244 NextStart = EndVal;
245 }
246 else {
247 EndVal = *StartVal + ((SK_U32)QuSize * 1024) - 1;
248 NextStart = EndVal + 1;
249 }
250
251 if (pPrt->PState >= SK_PRT_INIT) {
252 if (*StartVal != *QuStartAddr || EndVal != *QuEndAddr) {
253 Rtv = 1;
254 }
255 }
256 else {
257 *QuStartAddr = *StartVal;
258 *QuEndAddr = EndVal;
259 }
260
261 *StartVal = NextStart;
262 return(Rtv);
263} /* DoCalcAddr */
264
265/******************************************************************************
266 *
267 * SkGeInitAssignRamToQueues() - allocate default queue sizes
268 *
269 * Description:
270 * This function assigns the memory to the different queues and ports.
271 * When DualNet is set to SK_TRUE all ports get the same amount of memory.
272 * Otherwise the first port gets most of the memory and all the
273 * other ports just the required minimum.
274 * This function can only be called when pAC->GIni.GIRamSize and
275 * pAC->GIni.GIMacsFound have been initialized, usually this happens
276 * at init level 1
277 *
278 * Returns:
279 * 0 - ok
280 * 1 - invalid input values
281 * 2 - not enough memory
282 */
283
284int SkGeInitAssignRamToQueues(
285SK_AC *pAC, /* Adapter context */
286int ActivePort, /* Active Port in RLMT mode */
287SK_BOOL DualNet) /* adapter context */
288{
289 int i;
290 int UsedKilobytes; /* memory already assigned */
291 int ActivePortKilobytes; /* memory available for active port */
292 SK_GEPORT *pGePort;
293
294 UsedKilobytes = 0;
295
296 if (ActivePort >= pAC->GIni.GIMacsFound) {
297 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
298 ("SkGeInitAssignRamToQueues: ActivePort (%d) invalid\n",
299 ActivePort));
300 return(1);
301 }
302 if (((pAC->GIni.GIMacsFound * (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE)) +
303 ((RAM_QUOTA_SYNC == 0) ? 0 : SK_MIN_TXQ_SIZE)) > pAC->GIni.GIRamSize) {
304 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
305 ("SkGeInitAssignRamToQueues: Not enough memory (%d)\n",
306 pAC->GIni.GIRamSize));
307 return(2);
308 }
309
310 if (DualNet) {
311 /* every port gets the same amount of memory */
312 ActivePortKilobytes = pAC->GIni.GIRamSize / pAC->GIni.GIMacsFound;
313 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
314
315 pGePort = &pAC->GIni.GP[i];
316
317 /* take away the minimum memory for active queues */
318 ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE);
319
320 /* receive queue gets the minimum + 80% of the rest */
321 pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((
322 ActivePortKilobytes * (unsigned long) RAM_QUOTA_RX) / 100))
323 + SK_MIN_RXQ_SIZE;
324
325 ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE);
326
327 /* synchronous transmit queue */
328 pGePort->PXSQSize = 0;
329
330 /* asynchronous transmit queue */
331 pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes +
332 SK_MIN_TXQ_SIZE);
333 }
334 }
335 else {
336 /* Rlmt Mode or single link adapter */
337
338 /* Set standby queue size defaults for all standby ports */
339 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
340
341 if (i != ActivePort) {
342 pGePort = &pAC->GIni.GP[i];
343
344 pGePort->PRxQSize = SK_MIN_RXQ_SIZE;
345 pGePort->PXAQSize = SK_MIN_TXQ_SIZE;
346 pGePort->PXSQSize = 0;
347
348 /* Count used RAM */
349 UsedKilobytes += pGePort->PRxQSize + pGePort->PXAQSize;
350 }
351 }
352 /* what's left? */
353 ActivePortKilobytes = pAC->GIni.GIRamSize - UsedKilobytes;
354
355 /* assign it to the active port */
356 /* first take away the minimum memory */
357 ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE);
358 pGePort = &pAC->GIni.GP[ActivePort];
359
360 /* receive queue get's the minimum + 80% of the rest */
361 pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((ActivePortKilobytes *
362 (unsigned long) RAM_QUOTA_RX) / 100)) + SK_MIN_RXQ_SIZE;
363
364 ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE);
365
366 /* synchronous transmit queue */
367 pGePort->PXSQSize = 0;
368
369 /* asynchronous transmit queue */
370 pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes) +
371 SK_MIN_TXQ_SIZE;
372 }
373#ifdef VCPU
374 VCPUprintf(0, "PRxQSize=%u, PXSQSize=%u, PXAQSize=%u\n",
375 pGePort->PRxQSize, pGePort->PXSQSize, pGePort->PXAQSize);
376#endif /* VCPU */
377
378 return(0);
379} /* SkGeInitAssignRamToQueues */
380
381/******************************************************************************
382 *
383 * SkGeCheckQSize() - Checks the Adapters Queue Size Configuration
384 *
385 * Description:
386 * This function verifies the Queue Size Configuration specified
387 * in the variables PRxQSize, PXSQSize, and PXAQSize of all
388 * used ports.
389 * This requirements must be fullfilled to have a valid configuration:
390 * - The size of all queues must not exceed GIRamSize.
391 * - The queue sizes must be specified in units of 8 kB.
392 * - The size of Rx queues of available ports must not be
393 * smaller than 16 kB.
394 * - The size of at least one Tx queue (synch. or asynch.)
395 * of available ports must not be smaller than 16 kB
396 * when Jumbo Frames are used.
397 * - The RAM start and end addresses must not be changed
398 * for ports which are already initialized.
399 * Furthermore SkGeCheckQSize() defines the Start and End Addresses
400 * of all ports and stores them into the HWAC port structure.
401 *
402 * Returns:
403 * 0: Queue Size Configuration valid
404 * 1: Queue Size Configuration invalid
405 */
406static int SkGeCheckQSize(
407SK_AC *pAC, /* adapter context */
408int Port) /* port index */
409{
410 SK_GEPORT *pPrt;
411 int i;
412 int Rtv;
413 int Rtv2;
414 SK_U32 StartAddr;
415#ifndef SK_SLIM
416 int UsedMem; /* total memory used (max. found ports) */
417#endif
418
419 Rtv = 0;
420
421#ifndef SK_SLIM
422
423 UsedMem = 0;
424 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
425 pPrt = &pAC->GIni.GP[i];
426
427 if ((pPrt->PRxQSize & QZ_UNITS) != 0 ||
428 (pPrt->PXSQSize & QZ_UNITS) != 0 ||
429 (pPrt->PXAQSize & QZ_UNITS) != 0) {
430
431 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG);
432 return(1);
433 }
434
435 if (i == Port && pPrt->PRxQSize < SK_MIN_RXQ_SIZE) {
436 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E011, SKERR_HWI_E011MSG);
437 return(1);
438 }
439
440 /*
441 * the size of at least one Tx queue (synch. or asynch.) has to be > 0.
442 * if Jumbo Frames are used, this size has to be >= 16 kB.
443 */
444 if ((i == Port && pPrt->PXSQSize == 0 && pPrt->PXAQSize == 0) ||
445 (pAC->GIni.GIPortUsage == SK_JUMBO_LINK &&
446 ((pPrt->PXSQSize > 0 && pPrt->PXSQSize < SK_MIN_TXQ_SIZE) ||
447 (pPrt->PXAQSize > 0 && pPrt->PXAQSize < SK_MIN_TXQ_SIZE)))) {
448 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E023, SKERR_HWI_E023MSG);
449 return(1);
450 }
451
452 UsedMem += pPrt->PRxQSize + pPrt->PXSQSize + pPrt->PXAQSize;
453 }
454
455 if (UsedMem > pAC->GIni.GIRamSize) {
456 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG);
457 return(1);
458 }
459#endif /* !SK_SLIM */
460
461 /* Now start address calculation */
462 StartAddr = pAC->GIni.GIRamOffs;
463 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
464 pPrt = &pAC->GIni.GP[i];
465
466 /* Calculate/Check values for the receive queue */
467 Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PRxQSize, &StartAddr,
468 &pPrt->PRxQRamStart, &pPrt->PRxQRamEnd);
469 Rtv |= Rtv2;
470
471 /* Calculate/Check values for the synchronous Tx queue */
472 Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXSQSize, &StartAddr,
473 &pPrt->PXsQRamStart, &pPrt->PXsQRamEnd);
474 Rtv |= Rtv2;
475
476 /* Calculate/Check values for the asynchronous Tx queue */
477 Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXAQSize, &StartAddr,
478 &pPrt->PXaQRamStart, &pPrt->PXaQRamEnd);
479 Rtv |= Rtv2;
480
481 if (Rtv) {
482 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E013, SKERR_HWI_E013MSG);
483 return(1);
484 }
485 }
486
487 return(0);
488} /* SkGeCheckQSize */
489
490
491#ifdef GENESIS
492/******************************************************************************
493 *
494 * SkGeInitMacArb() - Initialize the MAC Arbiter
495 *
496 * Description:
497 * This function initializes the MAC Arbiter.
498 * It must not be called if there is still an
499 * initialized or active port.
500 *
501 * Returns:
502 * nothing
503 */
504static void SkGeInitMacArb(
505SK_AC *pAC, /* adapter context */
506SK_IOC IoC) /* IO context */
507{
508 /* release local reset */
509 SK_OUT16(IoC, B3_MA_TO_CTRL, MA_RST_CLR);
510
511 /* configure timeout values */
512 SK_OUT8(IoC, B3_MA_TOINI_RX1, SK_MAC_TO_53);
513 SK_OUT8(IoC, B3_MA_TOINI_RX2, SK_MAC_TO_53);
514 SK_OUT8(IoC, B3_MA_TOINI_TX1, SK_MAC_TO_53);
515 SK_OUT8(IoC, B3_MA_TOINI_TX2, SK_MAC_TO_53);
516
517 SK_OUT8(IoC, B3_MA_RCINI_RX1, 0);
518 SK_OUT8(IoC, B3_MA_RCINI_RX2, 0);
519 SK_OUT8(IoC, B3_MA_RCINI_TX1, 0);
520 SK_OUT8(IoC, B3_MA_RCINI_TX2, 0);
521
522 /* recovery values are needed for XMAC II Rev. B2 only */
523 /* Fast Output Enable Mode was intended to use with Rev. B2, but now? */
524
525 /*
526 * There is no start or enable button to push, therefore
527 * the MAC arbiter is configured and enabled now.
528 */
529} /* SkGeInitMacArb */
530
531
532/******************************************************************************
533 *
534 * SkGeInitPktArb() - Initialize the Packet Arbiter
535 *
536 * Description:
537 * This function initializes the Packet Arbiter.
538 * It must not be called if there is still an
539 * initialized or active port.
540 *
541 * Returns:
542 * nothing
543 */
544static void SkGeInitPktArb(
545SK_AC *pAC, /* adapter context */
546SK_IOC IoC) /* IO context */
547{
548 /* release local reset */
549 SK_OUT16(IoC, B3_PA_CTRL, PA_RST_CLR);
550
551 /* configure timeout values */
552 SK_OUT16(IoC, B3_PA_TOINI_RX1, SK_PKT_TO_MAX);
553 SK_OUT16(IoC, B3_PA_TOINI_RX2, SK_PKT_TO_MAX);
554 SK_OUT16(IoC, B3_PA_TOINI_TX1, SK_PKT_TO_MAX);
555 SK_OUT16(IoC, B3_PA_TOINI_TX2, SK_PKT_TO_MAX);
556
557 /*
558 * enable timeout timers if jumbo frames not used
559 * NOTE: the packet arbiter timeout interrupt is needed for
560 * half duplex hangup workaround
561 */
562 if (pAC->GIni.GIPortUsage != SK_JUMBO_LINK) {
563 if (pAC->GIni.GIMacsFound == 1) {
564 SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1);
565 }
566 else {
567 SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1 | PA_ENA_TO_TX2);
568 }
569 }
570} /* SkGeInitPktArb */
571#endif /* GENESIS */
572
573
574/******************************************************************************
575 *
576 * SkGeInitMacFifo() - Initialize the MAC FIFOs
577 *
578 * Description:
579 * Initialize all MAC FIFOs of the specified port
580 *
581 * Returns:
582 * nothing
583 */
584static void SkGeInitMacFifo(
585SK_AC *pAC, /* adapter context */
586SK_IOC IoC, /* IO context */
587int Port) /* Port Index (MAC_1 + n) */
588{
589 SK_U16 Word;
590#ifdef VCPU
591 SK_U32 DWord;
592#endif /* VCPU */
593 /*
594 * For each FIFO:
595 * - release local reset
596 * - use default value for MAC FIFO size
597 * - setup defaults for the control register
598 * - enable the FIFO
599 */
600
601#ifdef GENESIS
602 if (pAC->GIni.GIGenesis) {
603 /* Configure Rx MAC FIFO */
604 SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_CLR);
605 SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_RX_CTRL_DEF);
606 SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_ENA_OP_MD);
607
608 /* Configure Tx MAC FIFO */
609 SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_CLR);
610 SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF);
611 SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_ENA_OP_MD);
612
613 /* Enable frame flushing if jumbo frames used */
614 if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
615 SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_FLUSH);
616 }
617 }
618#endif /* GENESIS */
619
620#ifdef YUKON
621 if (pAC->GIni.GIYukon) {
622 /* set Rx GMAC FIFO Flush Mask */
623 SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), (SK_U16)RX_FF_FL_DEF_MSK);
624
625 Word = (SK_U16)GMF_RX_CTRL_DEF;
626
627 /* disable Rx GMAC FIFO Flush for YUKON-Lite Rev. A0 only */
628 if (pAC->GIni.GIYukonLite && pAC->GIni.GIChipId == CHIP_ID_YUKON) {
629
630 Word &= ~GMF_RX_F_FL_ON;
631 }
632
633 /* Configure Rx MAC FIFO */
634 SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR);
635 SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), Word);
636
637 /* set Rx GMAC FIFO Flush Threshold (default: 0x0a -> 56 bytes) */
638 SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF);
639
640 /* Configure Tx MAC FIFO */
641 SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR);
642 SK_OUT16(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U16)GMF_TX_CTRL_DEF);
643
644#ifdef VCPU
645 SK_IN32(IoC, MR_ADDR(Port, RX_GMF_AF_THR), &DWord);
646 SK_IN32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), &DWord);
647#endif /* VCPU */
648
649 /* set Tx GMAC FIFO Almost Empty Threshold */
650/* SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), 0); */
651 }
652#endif /* YUKON */
653
654} /* SkGeInitMacFifo */
655
656#ifdef SK_LNK_SYNC_CNT
657/******************************************************************************
658 *
659 * SkGeLoadLnkSyncCnt() - Load the Link Sync Counter and starts counting
660 *
661 * Description:
662 * This function starts the Link Sync Counter of the specified
663 * port and enables the generation of an Link Sync IRQ.
664 * The Link Sync Counter may be used to detect an active link,
665 * if autonegotiation is not used.
666 *
667 * Note:
668 * o To ensure receiving the Link Sync Event the LinkSyncCounter
669 * should be initialized BEFORE clearing the XMAC's reset!
670 * o Enable IS_LNK_SYNC_M1 and IS_LNK_SYNC_M2 after calling this
671 * function.
672 *
673 * Returns:
674 * nothing
675 */
676void SkGeLoadLnkSyncCnt(
677SK_AC *pAC, /* adapter context */
678SK_IOC IoC, /* IO context */
679int Port, /* Port Index (MAC_1 + n) */
680SK_U32 CntVal) /* Counter value */
681{
682 SK_U32 OrgIMsk;
683 SK_U32 NewIMsk;
684 SK_U32 ISrc;
685 SK_BOOL IrqPend;
686
687 /* stop counter */
688 SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_STOP);
689
690 /*
691 * ASIC problem:
692 * Each time starting the Link Sync Counter an IRQ is generated
693 * by the adapter. See problem report entry from 21.07.98
694 *
695 * Workaround: Disable Link Sync IRQ and clear the unexpeced IRQ
696 * if no IRQ is already pending.
697 */
698 IrqPend = SK_FALSE;
699 SK_IN32(IoC, B0_ISRC, &ISrc);
700 SK_IN32(IoC, B0_IMSK, &OrgIMsk);
701 if (Port == MAC_1) {
702 NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M1;
703 if ((ISrc & IS_LNK_SYNC_M1) != 0) {
704 IrqPend = SK_TRUE;
705 }
706 }
707 else {
708 NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M2;
709 if ((ISrc & IS_LNK_SYNC_M2) != 0) {
710 IrqPend = SK_TRUE;
711 }
712 }
713 if (!IrqPend) {
714 SK_OUT32(IoC, B0_IMSK, NewIMsk);
715 }
716
717 /* load counter */
718 SK_OUT32(IoC, MR_ADDR(Port, LNK_SYNC_INI), CntVal);
719
720 /* start counter */
721 SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_START);
722
723 if (!IrqPend) {
724 /* clear the unexpected IRQ, and restore the interrupt mask */
725 SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_CLR_IRQ);
726 SK_OUT32(IoC, B0_IMSK, OrgIMsk);
727 }
728} /* SkGeLoadLnkSyncCnt*/
729#endif /* SK_LNK_SYNC_CNT */
730
731#if defined(SK_DIAG) || defined(SK_CFG_SYNC)
732/******************************************************************************
733 *
734 * SkGeCfgSync() - Configure synchronous bandwidth for this port.
735 *
736 * Description:
737 * This function may be used to configure synchronous bandwidth
738 * to the specified port. This may be done any time after
739 * initializing the port. The configuration values are NOT saved
740 * in the HWAC port structure and will be overwritten any
741 * time when stopping and starting the port.
742 * Any values for the synchronous configuration will be ignored
743 * if the size of the synchronous queue is zero!
744 *
745 * The default configuration for the synchronous service is
746 * TXA_ENA_FSYNC. This means if the size of
747 * the synchronous queue is unequal zero but no specific
748 * synchronous bandwidth is configured, the synchronous queue
749 * will always have the 'unlimited' transmit priority!
750 *
751 * This mode will be restored if the synchronous bandwidth is
752 * deallocated ('IntTime' = 0 and 'LimCount' = 0).
753 *
754 * Returns:
755 * 0: success
756 * 1: parameter configuration error
757 * 2: try to configure quality of service although no
758 * synchronous queue is configured
759 */
760int SkGeCfgSync(
761SK_AC *pAC, /* adapter context */
762SK_IOC IoC, /* IO context */
763int Port, /* Port Index (MAC_1 + n) */
764SK_U32 IntTime, /* Interval Timer Value in units of 8ns */
765SK_U32 LimCount, /* Number of bytes to transfer during IntTime */
766int SyncMode) /* Sync Mode: TXA_ENA_ALLOC | TXA_DIS_ALLOC | 0 */
767{
768 int Rtv;
769
770 Rtv = 0;
771
772 /* check the parameters */
773 if (LimCount > IntTime ||
774 (LimCount == 0 && IntTime != 0) ||
775 (LimCount != 0 && IntTime == 0)) {
776
777 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG);
778 return(1);
779 }
780
781 if (pAC->GIni.GP[Port].PXSQSize == 0) {
782 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E009, SKERR_HWI_E009MSG);
783 return(2);
784 }
785
786 /* calculate register values */
787 IntTime = (IntTime / 2) * pAC->GIni.GIHstClkFact / 100;
788 LimCount = LimCount / 8;
789
790 if (IntTime > TXA_MAX_VAL || LimCount > TXA_MAX_VAL) {
791 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG);
792 return(1);
793 }
794
795 /*
796 * - Enable 'Force Sync' to ensure the synchronous queue
797 * has the priority while configuring the new values.
798 * - Also 'disable alloc' to ensure the settings complies
799 * to the SyncMode parameter.
800 * - Disable 'Rate Control' to configure the new values.
801 * - write IntTime and LimCount
802 * - start 'Rate Control' and disable 'Force Sync'
803 * if Interval Timer or Limit Counter not zero.
804 */
805 SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
806 TXA_ENA_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
807
808 SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), IntTime);
809 SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), LimCount);
810
811 SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
812 (SK_U8)(SyncMode & (TXA_ENA_ALLOC | TXA_DIS_ALLOC)));
813
814 if (IntTime != 0 || LimCount != 0) {
815 SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_DIS_FSYNC | TXA_START_RC);
816 }
817
818 return(0);
819} /* SkGeCfgSync */
820#endif /* SK_DIAG || SK_CFG_SYNC*/
821
822
823/******************************************************************************
824 *
825 * DoInitRamQueue() - Initialize the RAM Buffer Address of a single Queue
826 *
827 * Desccription:
828 * If the queue is used, enable and initialize it.
829 * Make sure the queue is still reset, if it is not used.
830 *
831 * Returns:
832 * nothing
833 */
834static void DoInitRamQueue(
835SK_AC *pAC, /* adapter context */
836SK_IOC IoC, /* IO context */
837int QuIoOffs, /* Queue IO Address Offset */
838SK_U32 QuStartAddr, /* Queue Start Address */
839SK_U32 QuEndAddr, /* Queue End Address */
840int QuType) /* Queue Type (SK_RX_SRAM_Q|SK_RX_BRAM_Q|SK_TX_RAM_Q) */
841{
842 SK_U32 RxUpThresVal;
843 SK_U32 RxLoThresVal;
844
845 if (QuStartAddr != QuEndAddr) {
846 /* calculate thresholds, assume we have a big Rx queue */
847 RxUpThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_ULPP) / 8;
848 RxLoThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_LLPP_B)/8;
849
850 /* build HW address format */
851 QuStartAddr = QuStartAddr / 8;
852 QuEndAddr = QuEndAddr / 8;
853
854 /* release local reset */
855 SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_CLR);
856
857 /* configure addresses */
858 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_START), QuStartAddr);
859 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_END), QuEndAddr);
860 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_WP), QuStartAddr);
861 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RP), QuStartAddr);
862
863 switch (QuType) {
864 case SK_RX_SRAM_Q:
865 /* configure threshold for small Rx Queue */
866 RxLoThresVal += (SK_RB_LLPP_B - SK_RB_LLPP_S) / 8;
867
868 /* continue with SK_RX_BRAM_Q */
869 case SK_RX_BRAM_Q:
870 /* write threshold for Rx Queue */
871
872 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_UTPP), RxUpThresVal);
873 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_LTPP), RxLoThresVal);
874
875 /* the high priority threshold not used */
876 break;
877 case SK_TX_RAM_Q:
878 /*
879 * Do NOT use Store & Forward under normal operation due to
880 * performance optimization (GENESIS only).
881 * But if Jumbo Frames are configured (XMAC Tx FIFO is only 4 kB)
882 * or YUKON is used ((GMAC Tx FIFO is only 1 kB)
883 * we NEED Store & Forward of the RAM buffer.
884 */
885 if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK ||
886 pAC->GIni.GIYukon) {
887 /* enable Store & Forward Mode for the Tx Side */
888 SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_STFWD);
889 }
890 break;
891 }
892
893 /* set queue operational */
894 SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_OP_MD);
895 }
896 else {
897 /* ensure the queue is still disabled */
898 SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_SET);
899 }
900} /* DoInitRamQueue */
901
902
903/******************************************************************************
904 *
905 * SkGeInitRamBufs() - Initialize the RAM Buffer Queues
906 *
907 * Description:
908 * Initialize all RAM Buffer Queues of the specified port
909 *
910 * Returns:
911 * nothing
912 */
913static void SkGeInitRamBufs(
914SK_AC *pAC, /* adapter context */
915SK_IOC IoC, /* IO context */
916int Port) /* Port Index (MAC_1 + n) */
917{
918 SK_GEPORT *pPrt;
919 int RxQType;
920
921 pPrt = &pAC->GIni.GP[Port];
922
923 if (pPrt->PRxQSize == SK_MIN_RXQ_SIZE) {
924 RxQType = SK_RX_SRAM_Q; /* small Rx Queue */
925 }
926 else {
927 RxQType = SK_RX_BRAM_Q; /* big Rx Queue */
928 }
929
930 DoInitRamQueue(pAC, IoC, pPrt->PRxQOff, pPrt->PRxQRamStart,
931 pPrt->PRxQRamEnd, RxQType);
932
933 DoInitRamQueue(pAC, IoC, pPrt->PXsQOff, pPrt->PXsQRamStart,
934 pPrt->PXsQRamEnd, SK_TX_RAM_Q);
935
936 DoInitRamQueue(pAC, IoC, pPrt->PXaQOff, pPrt->PXaQRamStart,
937 pPrt->PXaQRamEnd, SK_TX_RAM_Q);
938
939} /* SkGeInitRamBufs */
940
941
942/******************************************************************************
943 *
944 * SkGeInitRamIface() - Initialize the RAM Interface
945 *
946 * Description:
947 * This function initializes the Adapters RAM Interface.
948 *
949 * Note:
950 * This function is used in the diagnostics.
951 *
952 * Returns:
953 * nothing
954 */
955void SkGeInitRamIface(
956SK_AC *pAC, /* adapter context */
957SK_IOC IoC) /* IO context */
958{
959 /* release local reset */
960 SK_OUT16(IoC, B3_RI_CTRL, RI_RST_CLR);
961
962 /* configure timeout values */
963 SK_OUT8(IoC, B3_RI_WTO_R1, SK_RI_TO_53);
964 SK_OUT8(IoC, B3_RI_WTO_XA1, SK_RI_TO_53);
965 SK_OUT8(IoC, B3_RI_WTO_XS1, SK_RI_TO_53);
966 SK_OUT8(IoC, B3_RI_RTO_R1, SK_RI_TO_53);
967 SK_OUT8(IoC, B3_RI_RTO_XA1, SK_RI_TO_53);
968 SK_OUT8(IoC, B3_RI_RTO_XS1, SK_RI_TO_53);
969 SK_OUT8(IoC, B3_RI_WTO_R2, SK_RI_TO_53);
970 SK_OUT8(IoC, B3_RI_WTO_XA2, SK_RI_TO_53);
971 SK_OUT8(IoC, B3_RI_WTO_XS2, SK_RI_TO_53);
972 SK_OUT8(IoC, B3_RI_RTO_R2, SK_RI_TO_53);
973 SK_OUT8(IoC, B3_RI_RTO_XA2, SK_RI_TO_53);
974 SK_OUT8(IoC, B3_RI_RTO_XS2, SK_RI_TO_53);
975
976} /* SkGeInitRamIface */
977
978
979/******************************************************************************
980 *
981 * SkGeInitBmu() - Initialize the BMU state machines
982 *
983 * Description:
984 * Initialize all BMU state machines of the specified port
985 *
986 * Returns:
987 * nothing
988 */
989static void SkGeInitBmu(
990SK_AC *pAC, /* adapter context */
991SK_IOC IoC, /* IO context */
992int Port) /* Port Index (MAC_1 + n) */
993{
994 SK_GEPORT *pPrt;
995 SK_U32 RxWm;
996 SK_U32 TxWm;
997
998 pPrt = &pAC->GIni.GP[Port];
999
1000 RxWm = SK_BMU_RX_WM;
1001 TxWm = SK_BMU_TX_WM;
1002
1003 if (!pAC->GIni.GIPciSlot64 && !pAC->GIni.GIPciClock66) {
1004 /* for better performance */
1005 RxWm /= 2;
1006 TxWm /= 2;
1007 }
1008
1009 /* Rx Queue: Release all local resets and set the watermark */
1010 SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_CLR_RESET);
1011 SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), RxWm);
1012
1013 /*
1014 * Tx Queue: Release all local resets if the queue is used !
1015 * set watermark
1016 */
1017 if (pPrt->PXSQSize != 0) {
1018 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_CLR_RESET);
1019 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_F), TxWm);
1020 }
1021
1022 if (pPrt->PXAQSize != 0) {
1023 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_CLR_RESET);
1024 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_F), TxWm);
1025 }
1026 /*
1027 * Do NOT enable the descriptor poll timers here, because
1028 * the descriptor addresses are not specified yet.
1029 */
1030} /* SkGeInitBmu */
1031
1032
1033/******************************************************************************
1034 *
1035 * TestStopBit() - Test the stop bit of the queue
1036 *
1037 * Description:
1038 * Stopping a queue is not as simple as it seems to be.
1039 * If descriptor polling is enabled, it may happen
1040 * that RX/TX stop is done and SV idle is NOT set.
1041 * In this case we have to issue another stop command.
1042 *
1043 * Returns:
1044 * The queues control status register
1045 */
1046static SK_U32 TestStopBit(
1047SK_AC *pAC, /* Adapter Context */
1048SK_IOC IoC, /* IO Context */
1049int QuIoOffs) /* Queue IO Address Offset */
1050{
1051 SK_U32 QuCsr; /* CSR contents */
1052
1053 SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
1054
1055 if ((QuCsr & (CSR_STOP | CSR_SV_IDLE)) == 0) {
1056 /* Stop Descriptor overridden by start command */
1057 SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), CSR_STOP);
1058
1059 SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
1060 }
1061
1062 return(QuCsr);
1063} /* TestStopBit */
1064
1065
1066/******************************************************************************
1067 *
1068 * SkGeStopPort() - Stop the Rx/Tx activity of the port 'Port'.
1069 *
1070 * Description:
1071 * After calling this function the descriptor rings and Rx and Tx
1072 * queues of this port may be reconfigured.
1073 *
1074 * It is possible to stop the receive and transmit path separate or
1075 * both together.
1076 *
1077 * Dir = SK_STOP_TX Stops the transmit path only and resets the MAC.
1078 * The receive queue is still active and
1079 * the pending Rx frames may be still transferred
1080 * into the RxD.
1081 * SK_STOP_RX Stop the receive path. The tansmit path
1082 * has to be stopped once before.
1083 * SK_STOP_ALL SK_STOP_TX + SK_STOP_RX
1084 *
1085 * RstMode = SK_SOFT_RST Resets the MAC. The PHY is still alive.
1086 * SK_HARD_RST Resets the MAC and the PHY.
1087 *
1088 * Example:
1089 * 1) A Link Down event was signaled for a port. Therefore the activity
1090 * of this port should be stopped and a hardware reset should be issued
1091 * to enable the workaround of XMAC Errata #2. But the received frames
1092 * should not be discarded.
1093 * ...
1094 * SkGeStopPort(pAC, IoC, Port, SK_STOP_TX, SK_HARD_RST);
1095 * (transfer all pending Rx frames)
1096 * SkGeStopPort(pAC, IoC, Port, SK_STOP_RX, SK_HARD_RST);
1097 * ...
1098 *
1099 * 2) An event was issued which request the driver to switch
1100 * the 'virtual active' link to an other already active port
1101 * as soon as possible. The frames in the receive queue of this
1102 * port may be lost. But the PHY must not be reset during this
1103 * event.
1104 * ...
1105 * SkGeStopPort(pAC, IoC, Port, SK_STOP_ALL, SK_SOFT_RST);
1106 * ...
1107 *
1108 * Extended Description:
1109 * If SK_STOP_TX is set,
1110 * o disable the MAC's receive and transmitter to prevent
1111 * from sending incomplete frames
1112 * o stop the port's transmit queues before terminating the
1113 * BMUs to prevent from performing incomplete PCI cycles
1114 * on the PCI bus
1115 * - The network Rx and Tx activity and PCI Tx transfer is
1116 * disabled now.
1117 * o reset the MAC depending on the RstMode
1118 * o Stop Interval Timer and Limit Counter of Tx Arbiter,
1119 * also disable Force Sync bit and Enable Alloc bit.
1120 * o perform a local reset of the port's Tx path
1121 * - reset the PCI FIFO of the async Tx queue
1122 * - reset the PCI FIFO of the sync Tx queue
1123 * - reset the RAM Buffer async Tx queue
1124 * - reset the RAM Buffer sync Tx queue
1125 * - reset the MAC Tx FIFO
1126 * o switch Link and Tx LED off, stop the LED counters
1127 *
1128 * If SK_STOP_RX is set,
1129 * o stop the port's receive queue
1130 * - The path data transfer activity is fully stopped now.
1131 * o perform a local reset of the port's Rx path
1132 * - reset the PCI FIFO of the Rx queue
1133 * - reset the RAM Buffer receive queue
1134 * - reset the MAC Rx FIFO
1135 * o switch Rx LED off, stop the LED counter
1136 *
1137 * If all ports are stopped,
1138 * o reset the RAM Interface.
1139 *
1140 * Notes:
1141 * o This function may be called during the driver states RESET_PORT and
1142 * SWITCH_PORT.
1143 */
1144void SkGeStopPort(
1145SK_AC *pAC, /* adapter context */
1146SK_IOC IoC, /* I/O context */
1147int Port, /* port to stop (MAC_1 + n) */
1148int Dir, /* Direction to Stop (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */
1149int RstMode)/* Reset Mode (SK_SOFT_RST, SK_HARD_RST) */
1150{
1151#ifndef SK_DIAG
1152 SK_EVPARA Para;
1153#endif /* !SK_DIAG */
1154 SK_GEPORT *pPrt;
1155 SK_U32 DWord;
1156 SK_U32 XsCsr;
1157 SK_U32 XaCsr;
1158 SK_U64 ToutStart;
1159 int i;
1160 int ToutCnt;
1161
1162 pPrt = &pAC->GIni.GP[Port];
1163
1164 if ((Dir & SK_STOP_TX) != 0) {
1165 /* disable receiver and transmitter */
1166 SkMacRxTxDisable(pAC, IoC, Port);
1167
1168 /* stop both transmit queues */
1169 /*
1170 * If the BMU is in the reset state CSR_STOP will terminate
1171 * immediately.
1172 */
1173 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_STOP);
1174 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_STOP);
1175
1176 ToutStart = SkOsGetTime(pAC);
1177 ToutCnt = 0;
1178 do {
1179 /*
1180 * Clear packet arbiter timeout to make sure
1181 * this loop will terminate.
1182 */
1183 SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ?
1184 PA_CLR_TO_TX1 : PA_CLR_TO_TX2));
1185
1186 /*
1187 * If the transfer stucks at the MAC the STOP command will not
1188 * terminate if we don't flush the XMAC's transmit FIFO !
1189 */
1190 SkMacFlushTxFifo(pAC, IoC, Port);
1191
1192 XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff);
1193 XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff);
1194
1195 if (SkOsGetTime(pAC) - ToutStart > (SK_TICKS_PER_SEC / 18)) {
1196 /*
1197 * Timeout of 1/18 second reached.
1198 * This needs to be checked at 1/18 sec only.
1199 */
1200 ToutCnt++;
1201 if (ToutCnt > 1) {
1202 /* Might be a problem when the driver event handler
1203 * calls StopPort again. XXX.
1204 */
1205
1206 /* Fatal Error, Loop aborted */
1207 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E018,
1208 SKERR_HWI_E018MSG);
1209#ifndef SK_DIAG
1210 Para.Para64 = Port;
1211 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
1212#endif /* !SK_DIAG */
1213 return;
1214 }
1215 /*
1216 * Cache incoherency workaround: Assume a start command
1217 * has been lost while sending the frame.
1218 */
1219 ToutStart = SkOsGetTime(pAC);
1220
1221 if ((XsCsr & CSR_STOP) != 0) {
1222 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_START);
1223 }
1224 if ((XaCsr & CSR_STOP) != 0) {
1225 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_START);
1226 }
1227 }
1228
1229 /*
1230 * Because of the ASIC problem report entry from 21.08.1998 it is
1231 * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set.
1232 */
1233 } while ((XsCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE ||
1234 (XaCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE);
1235
1236 /* Reset the MAC depending on the RstMode */
1237 if (RstMode == SK_SOFT_RST) {
1238 SkMacSoftRst(pAC, IoC, Port);
1239 }
1240 else {
1241 SkMacHardRst(pAC, IoC, Port);
1242 }
1243
1244 /* Disable Force Sync bit and Enable Alloc bit */
1245 SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
1246 TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
1247
1248 /* Stop Interval Timer and Limit Counter of Tx Arbiter */
1249 SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), 0L);
1250 SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), 0L);
1251
1252 /* Perform a local reset of the port's Tx path */
1253
1254 /* Reset the PCI FIFO of the async Tx queue */
1255 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_SET_RESET);
1256 /* Reset the PCI FIFO of the sync Tx queue */
1257 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_SET_RESET);
1258 /* Reset the RAM Buffer async Tx queue */
1259 SK_OUT8(IoC, RB_ADDR(pPrt->PXaQOff, RB_CTRL), RB_RST_SET);
1260 /* Reset the RAM Buffer sync Tx queue */
1261 SK_OUT8(IoC, RB_ADDR(pPrt->PXsQOff, RB_CTRL), RB_RST_SET);
1262
1263 /* Reset Tx MAC FIFO */
1264#ifdef GENESIS
1265 if (pAC->GIni.GIGenesis) {
1266 /* Note: MFF_RST_SET does NOT reset the XMAC ! */
1267 SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_SET);
1268
1269 /* switch Link and Tx LED off, stop the LED counters */
1270 /* Link LED is switched off by the RLMT and the Diag itself */
1271 SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_DIS);
1272 }
1273#endif /* GENESIS */
1274
1275#ifdef YUKON
1276 if (pAC->GIni.GIYukon) {
1277 /* Reset TX MAC FIFO */
1278 SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_SET);
1279 }
1280#endif /* YUKON */
1281 }
1282
1283 if ((Dir & SK_STOP_RX) != 0) {
1284 /*
1285 * The RX Stop Command will not terminate if no buffers
1286 * are queued in the RxD ring. But it will always reach
1287 * the Idle state. Therefore we can use this feature to
1288 * stop the transfer of received packets.
1289 */
1290 /* stop the port's receive queue */
1291 SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_STOP);
1292
1293 i = 100;
1294 do {
1295 /*
1296 * Clear packet arbiter timeout to make sure
1297 * this loop will terminate
1298 */
1299 SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ?
1300 PA_CLR_TO_RX1 : PA_CLR_TO_RX2));
1301
1302 DWord = TestStopBit(pAC, IoC, pPrt->PRxQOff);
1303
1304 /* timeout if i==0 (bug fix for #10748) */
1305 if (--i == 0) {
1306 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E024,
1307 SKERR_HWI_E024MSG);
1308 break;
1309 }
1310 /*
1311 * because of the ASIC problem report entry from 21.08.98
1312 * it is required to wait until CSR_STOP is reset and
1313 * CSR_SV_IDLE is set.
1314 */
1315 } while ((DWord & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE);
1316
1317 /* The path data transfer activity is fully stopped now */
1318
1319 /* Perform a local reset of the port's Rx path */
1320
1321 /* Reset the PCI FIFO of the Rx queue */
1322 SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_SET_RESET);
1323 /* Reset the RAM Buffer receive queue */
1324 SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff, RB_CTRL), RB_RST_SET);
1325
1326 /* Reset Rx MAC FIFO */
1327#ifdef GENESIS
1328 if (pAC->GIni.GIGenesis) {
1329
1330 SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_SET);
1331
1332 /* switch Rx LED off, stop the LED counter */
1333 SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_DIS);
1334 }
1335#endif /* GENESIS */
1336
1337#ifdef YUKON
1338 if (pAC->GIni.GIYukon) {
1339 /* Reset Rx MAC FIFO */
1340 SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_SET);
1341 }
1342#endif /* YUKON */
1343 }
1344} /* SkGeStopPort */
1345
1346
1347/******************************************************************************
1348 *
1349 * SkGeInit0() - Level 0 Initialization
1350 *
1351 * Description:
1352 * - Initialize the BMU address offsets
1353 *
1354 * Returns:
1355 * nothing
1356 */
1357static void SkGeInit0(
1358SK_AC *pAC, /* adapter context */
1359SK_IOC IoC) /* IO context */
1360{
1361 int i;
1362 SK_GEPORT *pPrt;
1363
1364 for (i = 0; i < SK_MAX_MACS; i++) {
1365 pPrt = &pAC->GIni.GP[i];
1366
1367 pPrt->PState = SK_PRT_RESET;
1368 pPrt->PRxQOff = QOffTab[i].RxQOff;
1369 pPrt->PXsQOff = QOffTab[i].XsQOff;
1370 pPrt->PXaQOff = QOffTab[i].XaQOff;
1371 pPrt->PCheckPar = SK_FALSE;
1372 pPrt->PIsave = 0;
1373 pPrt->PPrevShorts = 0;
1374 pPrt->PLinkResCt = 0;
1375 pPrt->PAutoNegTOCt = 0;
1376 pPrt->PPrevRx = 0;
1377 pPrt->PPrevFcs = 0;
1378 pPrt->PRxLim = SK_DEF_RX_WA_LIM;
1379 pPrt->PLinkMode = (SK_U8)SK_LMODE_AUTOFULL;
1380 pPrt->PLinkSpeedCap = (SK_U8)SK_LSPEED_CAP_1000MBPS;
1381 pPrt->PLinkSpeed = (SK_U8)SK_LSPEED_1000MBPS;
1382 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_UNKNOWN;
1383 pPrt->PLinkModeConf = (SK_U8)SK_LMODE_AUTOSENSE;
1384 pPrt->PFlowCtrlMode = (SK_U8)SK_FLOW_MODE_SYM_OR_REM;
1385 pPrt->PLinkCap = (SK_U8)(SK_LMODE_CAP_HALF | SK_LMODE_CAP_FULL |
1386 SK_LMODE_CAP_AUTOHALF | SK_LMODE_CAP_AUTOFULL);
1387 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
1388 pPrt->PFlowCtrlCap = (SK_U8)SK_FLOW_MODE_SYM_OR_REM;
1389 pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
1390 pPrt->PMSCap = 0;
1391 pPrt->PMSMode = (SK_U8)SK_MS_MODE_AUTO;
1392 pPrt->PMSStatus = (SK_U8)SK_MS_STAT_UNSET;
1393 pPrt->PLipaAutoNeg = (SK_U8)SK_LIPA_UNKNOWN;
1394 pPrt->PAutoNegFail = SK_FALSE;
1395 pPrt->PHWLinkUp = SK_FALSE;
1396 pPrt->PLinkBroken = SK_TRUE; /* See WA code */
1397 pPrt->PPhyPowerState = PHY_PM_OPERATIONAL_MODE;
1398 pPrt->PMacColThres = TX_COL_DEF;
1399 pPrt->PMacJamLen = TX_JAM_LEN_DEF;
1400 pPrt->PMacJamIpgVal = TX_JAM_IPG_DEF;
1401 pPrt->PMacJamIpgData = TX_IPG_JAM_DEF;
1402 pPrt->PMacIpgData = IPG_DATA_DEF;
1403 pPrt->PMacLimit4 = SK_FALSE;
1404 }
1405
1406 pAC->GIni.GIPortUsage = SK_RED_LINK;
1407 pAC->GIni.GILedBlinkCtrl = (SK_U16)OemConfig.Value;
1408 pAC->GIni.GIValIrqMask = IS_ALL_MSK;
1409
1410} /* SkGeInit0*/
1411
1412#ifdef SK_PCI_RESET
1413
1414/******************************************************************************
1415 *
1416 * SkGePciReset() - Reset PCI interface
1417 *
1418 * Description:
1419 * o Read PCI configuration.
1420 * o Change power state to 3.
1421 * o Change power state to 0.
1422 * o Restore PCI configuration.
1423 *
1424 * Returns:
1425 * 0: Success.
1426 * 1: Power state could not be changed to 3.
1427 */
1428static int SkGePciReset(
1429SK_AC *pAC, /* adapter context */
1430SK_IOC IoC) /* IO context */
1431{
1432 int i;
1433 SK_U16 PmCtlSts;
1434 SK_U32 Bp1;
1435 SK_U32 Bp2;
1436 SK_U16 PciCmd;
1437 SK_U8 Cls;
1438 SK_U8 Lat;
1439 SK_U8 ConfigSpace[PCI_CFG_SIZE];
1440
1441 /*
1442 * Note: Switching to D3 state is like a software reset.
1443 * Switching from D3 to D0 is a hardware reset.
1444 * We have to save and restore the configuration space.
1445 */
1446 for (i = 0; i < PCI_CFG_SIZE; i++) {
1447 SkPciReadCfgDWord(pAC, i*4, &ConfigSpace[i]);
1448 }
1449
1450 /* We know the RAM Interface Arbiter is enabled. */
1451 SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D3);
1452 SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts);
1453
1454 if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D3) {
1455 return(1);
1456 }
1457
1458 /* Return to D0 state. */
1459 SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D0);
1460
1461 /* Check for D0 state. */
1462 SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts);
1463
1464 if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D0) {
1465 return(1);
1466 }
1467
1468 /* Check PCI Config Registers. */
1469 SkPciReadCfgWord(pAC, PCI_COMMAND, &PciCmd);
1470 SkPciReadCfgByte(pAC, PCI_CACHE_LSZ, &Cls);
1471 SkPciReadCfgDWord(pAC, PCI_BASE_1ST, &Bp1);
1472 SkPciReadCfgDWord(pAC, PCI_BASE_2ND, &Bp2);
1473 SkPciReadCfgByte(pAC, PCI_LAT_TIM, &Lat);
1474
1475 if (PciCmd != 0 || Cls != (SK_U8)0 || Lat != (SK_U8)0 ||
1476 (Bp1 & 0xfffffff0L) != 0 || Bp2 != 1) {
1477 return(1);
1478 }
1479
1480 /* Restore PCI Config Space. */
1481 for (i = 0; i < PCI_CFG_SIZE; i++) {
1482 SkPciWriteCfgDWord(pAC, i*4, ConfigSpace[i]);
1483 }
1484
1485 return(0);
1486} /* SkGePciReset */
1487
1488#endif /* SK_PCI_RESET */
1489
1490/******************************************************************************
1491 *
1492 * SkGeInit1() - Level 1 Initialization
1493 *
1494 * Description:
1495 * o Do a software reset.
1496 * o Clear all reset bits.
1497 * o Verify that the detected hardware is present.
1498 * Return an error if not.
1499 * o Get the hardware configuration
1500 * + Read the number of MACs/Ports.
1501 * + Read the RAM size.
1502 * + Read the PCI Revision Id.
1503 * + Find out the adapters host clock speed
1504 * + Read and check the PHY type
1505 *
1506 * Returns:
1507 * 0: success
1508 * 5: Unexpected PHY type detected
1509 * 6: HW self test failed
1510 */
1511static int SkGeInit1(
1512SK_AC *pAC, /* adapter context */
1513SK_IOC IoC) /* IO context */
1514{
1515 SK_U8 Byte;
1516 SK_U16 Word;
1517 SK_U16 CtrlStat;
1518 SK_U32 DWord;
1519 int RetVal;
1520 int i;
1521
1522 RetVal = 0;
1523
1524 /* save CLK_RUN bits (YUKON-Lite) */
1525 SK_IN16(IoC, B0_CTST, &CtrlStat);
1526
1527#ifdef SK_PCI_RESET
1528 (void)SkGePciReset(pAC, IoC);
1529#endif /* SK_PCI_RESET */
1530
1531 /* do the SW-reset */
1532 SK_OUT8(IoC, B0_CTST, CS_RST_SET);
1533
1534 /* release the SW-reset */
1535 SK_OUT8(IoC, B0_CTST, CS_RST_CLR);
1536
1537 /* reset all error bits in the PCI STATUS register */
1538 /*
1539 * Note: PCI Cfg cycles cannot be used, because they are not
1540 * available on some platforms after 'boot time'.
1541 */
1542 SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
1543
1544 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
1545 SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
1546 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
1547
1548 /* release Master Reset */
1549 SK_OUT8(IoC, B0_CTST, CS_MRST_CLR);
1550
1551#ifdef CLK_RUN
1552 CtrlStat |= CS_CLK_RUN_ENA;
1553#endif /* CLK_RUN */
1554
1555 /* restore CLK_RUN bits */
1556 SK_OUT16(IoC, B0_CTST, (SK_U16)(CtrlStat &
1557 (CS_CLK_RUN_HOT | CS_CLK_RUN_RST | CS_CLK_RUN_ENA)));
1558
1559 /* read Chip Identification Number */
1560 SK_IN8(IoC, B2_CHIP_ID, &Byte);
1561 pAC->GIni.GIChipId = Byte;
1562
1563 /* read number of MACs */
1564 SK_IN8(IoC, B2_MAC_CFG, &Byte);
1565 pAC->GIni.GIMacsFound = (Byte & CFG_SNG_MAC) ? 1 : 2;
1566
1567 /* get Chip Revision Number */
1568 pAC->GIni.GIChipRev = (SK_U8)((Byte & CFG_CHIP_R_MSK) >> 4);
1569
1570 /* get diff. PCI parameters */
1571 SK_IN16(IoC, B0_CTST, &CtrlStat);
1572
1573 /* read the adapters RAM size */
1574 SK_IN8(IoC, B2_E_0, &Byte);
1575
1576 pAC->GIni.GIGenesis = SK_FALSE;
1577 pAC->GIni.GIYukon = SK_FALSE;
1578 pAC->GIni.GIYukonLite = SK_FALSE;
1579
1580#ifdef GENESIS
1581 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
1582
1583 pAC->GIni.GIGenesis = SK_TRUE;
1584
1585 if (Byte == (SK_U8)3) {
1586 /* special case: 4 x 64k x 36, offset = 0x80000 */
1587 pAC->GIni.GIRamSize = 1024;
1588 pAC->GIni.GIRamOffs = (SK_U32)512 * 1024;
1589 }
1590 else {
1591 pAC->GIni.GIRamSize = (int)Byte * 512;
1592 pAC->GIni.GIRamOffs = 0;
1593 }
1594 /* all GE adapters work with 53.125 MHz host clock */
1595 pAC->GIni.GIHstClkFact = SK_FACT_53;
1596
1597 /* set Descr. Poll Timer Init Value to 250 ms */
1598 pAC->GIni.GIPollTimerVal =
1599 SK_DPOLL_DEF * (SK_U32)pAC->GIni.GIHstClkFact / 100;
1600 }
1601#endif /* GENESIS */
1602
1603#ifdef YUKON
1604 if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) {
1605
1606 pAC->GIni.GIYukon = SK_TRUE;
1607
1608 pAC->GIni.GIRamSize = (Byte == (SK_U8)0) ? 128 : (int)Byte * 4;
1609
1610 pAC->GIni.GIRamOffs = 0;
1611
1612 /* WA for chip Rev. A */
1613 pAC->GIni.GIWolOffs = (pAC->GIni.GIChipId == CHIP_ID_YUKON &&
1614 pAC->GIni.GIChipRev == 0) ? WOL_REG_OFFS : 0;
1615
1616 /* get PM Capabilities of PCI config space */
1617 SK_IN16(IoC, PCI_C(PCI_PM_CAP_REG), &Word);
1618
1619 /* check if VAUX is available */
1620 if (((CtrlStat & CS_VAUX_AVAIL) != 0) &&
1621 /* check also if PME from D3cold is set */
1622 ((Word & PCI_PME_D3C_SUP) != 0)) {
1623 /* set entry in GE init struct */
1624 pAC->GIni.GIVauxAvail = SK_TRUE;
1625 }
1626
1627 if (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) {
1628 /* this is Rev. A1 */
1629 pAC->GIni.GIYukonLite = SK_TRUE;
1630 }
1631 else {
1632 /* save Flash-Address Register */
1633 SK_IN32(IoC, B2_FAR, &DWord);
1634
1635 /* test Flash-Address Register */
1636 SK_OUT8(IoC, B2_FAR + 3, 0xff);
1637 SK_IN8(IoC, B2_FAR + 3, &Byte);
1638
1639 if (Byte != 0) {
1640 /* this is Rev. A0 */
1641 pAC->GIni.GIYukonLite = SK_TRUE;
1642
1643 /* restore Flash-Address Register */
1644 SK_OUT32(IoC, B2_FAR, DWord);
1645 }
1646 }
1647
1648 /* switch power to VCC (WA for VAUX problem) */
1649 SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA |
1650 PC_VAUX_OFF | PC_VCC_ON));
1651
1652 /* read the Interrupt source */
1653 SK_IN32(IoC, B0_ISRC, &DWord);
1654
1655 if ((DWord & IS_HW_ERR) != 0) {
1656 /* read the HW Error Interrupt source */
1657 SK_IN32(IoC, B0_HWE_ISRC, &DWord);
1658
1659 if ((DWord & IS_IRQ_SENSOR) != 0) {
1660 /* disable HW Error IRQ */
1661 pAC->GIni.GIValIrqMask &= ~IS_HW_ERR;
1662 }
1663 }
1664
1665 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
1666 /* set GMAC Link Control reset */
1667 SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_SET);
1668
1669 /* clear GMAC Link Control reset */
1670 SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
1671 }
1672 /* all YU chips work with 78.125 MHz host clock */
1673 pAC->GIni.GIHstClkFact = SK_FACT_78;
1674
1675 pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX; /* 215 ms */
1676 }
1677#endif /* YUKON */
1678
1679 /* check if 64-bit PCI Slot is present */
1680 pAC->GIni.GIPciSlot64 = (SK_BOOL)((CtrlStat & CS_BUS_SLOT_SZ) != 0);
1681
1682 /* check if 66 MHz PCI Clock is active */
1683 pAC->GIni.GIPciClock66 = (SK_BOOL)((CtrlStat & CS_BUS_CLOCK) != 0);
1684
1685 /* read PCI HW Revision Id. */
1686 SK_IN8(IoC, PCI_C(PCI_REV_ID), &Byte);
1687 pAC->GIni.GIPciHwRev = Byte;
1688
1689 /* read the PMD type */
1690 SK_IN8(IoC, B2_PMD_TYP, &Byte);
1691 pAC->GIni.GICopperType = (SK_U8)(Byte == 'T');
1692
1693 /* read the PHY type */
1694 SK_IN8(IoC, B2_E_1, &Byte);
1695
1696 Byte &= 0x0f; /* the PHY type is stored in the lower nibble */
1697 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
1698
1699#ifdef GENESIS
1700 if (pAC->GIni.GIGenesis) {
1701 switch (Byte) {
1702 case SK_PHY_XMAC:
1703 pAC->GIni.GP[i].PhyAddr = PHY_ADDR_XMAC;
1704 break;
1705 case SK_PHY_BCOM:
1706 pAC->GIni.GP[i].PhyAddr = PHY_ADDR_BCOM;
1707 pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO |
1708 SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE);
1709 break;
1710#ifdef OTHER_PHY
1711 case SK_PHY_LONE:
1712 pAC->GIni.GP[i].PhyAddr = PHY_ADDR_LONE;
1713 break;
1714 case SK_PHY_NAT:
1715 pAC->GIni.GP[i].PhyAddr = PHY_ADDR_NAT;
1716 break;
1717#endif /* OTHER_PHY */
1718 default:
1719 /* ERROR: unexpected PHY type detected */
1720 RetVal = 5;
1721 break;
1722 }
1723 }
1724#endif /* GENESIS */
1725
1726#ifdef YUKON
1727 if (pAC->GIni.GIYukon) {
1728
1729 if (Byte < (SK_U8)SK_PHY_MARV_COPPER) {
1730 /* if this field is not initialized */
1731 Byte = (SK_U8)SK_PHY_MARV_COPPER;
1732
1733 pAC->GIni.GICopperType = SK_TRUE;
1734 }
1735
1736 pAC->GIni.GP[i].PhyAddr = PHY_ADDR_MARV;
1737
1738 if (pAC->GIni.GICopperType) {
1739
1740 pAC->GIni.GP[i].PLinkSpeedCap = (SK_U8)(SK_LSPEED_CAP_AUTO |
1741 SK_LSPEED_CAP_10MBPS | SK_LSPEED_CAP_100MBPS |
1742 SK_LSPEED_CAP_1000MBPS);
1743
1744 pAC->GIni.GP[i].PLinkSpeed = (SK_U8)SK_LSPEED_AUTO;
1745
1746 pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO |
1747 SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE);
1748 }
1749 else {
1750 Byte = (SK_U8)SK_PHY_MARV_FIBER;
1751 }
1752 }
1753#endif /* YUKON */
1754
1755 pAC->GIni.GP[i].PhyType = (int)Byte;
1756
1757 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
1758 ("PHY type: %d PHY addr: %04x\n", Byte,
1759 pAC->GIni.GP[i].PhyAddr));
1760 }
1761
1762 /* get MAC Type & set function pointers dependent on */
1763#ifdef GENESIS
1764 if (pAC->GIni.GIGenesis) {
1765
1766 pAC->GIni.GIMacType = SK_MAC_XMAC;
1767
1768 pAC->GIni.GIFunc.pFnMacUpdateStats = SkXmUpdateStats;
1769 pAC->GIni.GIFunc.pFnMacStatistic = SkXmMacStatistic;
1770 pAC->GIni.GIFunc.pFnMacResetCounter = SkXmResetCounter;
1771 pAC->GIni.GIFunc.pFnMacOverflow = SkXmOverflowStatus;
1772 }
1773#endif /* GENESIS */
1774
1775#ifdef YUKON
1776 if (pAC->GIni.GIYukon) {
1777
1778 pAC->GIni.GIMacType = SK_MAC_GMAC;
1779
1780 pAC->GIni.GIFunc.pFnMacUpdateStats = SkGmUpdateStats;
1781 pAC->GIni.GIFunc.pFnMacStatistic = SkGmMacStatistic;
1782 pAC->GIni.GIFunc.pFnMacResetCounter = SkGmResetCounter;
1783 pAC->GIni.GIFunc.pFnMacOverflow = SkGmOverflowStatus;
1784
1785#ifdef SPECIAL_HANDLING
1786 if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
1787 /* check HW self test result */
1788 SK_IN8(IoC, B2_E_3, &Byte);
1789 if (Byte & B2_E3_RES_MASK) {
1790 RetVal = 6;
1791 }
1792 }
1793#endif
1794 }
1795#endif /* YUKON */
1796
1797 return(RetVal);
1798} /* SkGeInit1 */
1799
1800
1801/******************************************************************************
1802 *
1803 * SkGeInit2() - Level 2 Initialization
1804 *
1805 * Description:
1806 * - start the Blink Source Counter
1807 * - start the Descriptor Poll Timer
1808 * - configure the MAC-Arbiter
1809 * - configure the Packet-Arbiter
1810 * - enable the Tx Arbiters
1811 * - enable the RAM Interface Arbiter
1812 *
1813 * Returns:
1814 * nothing
1815 */
1816static void SkGeInit2(
1817SK_AC *pAC, /* adapter context */
1818SK_IOC IoC) /* IO context */
1819{
1820#ifdef GENESIS
1821 SK_U32 DWord;
1822#endif /* GENESIS */
1823 int i;
1824
1825 /* start the Descriptor Poll Timer */
1826 if (pAC->GIni.GIPollTimerVal != 0) {
1827 if (pAC->GIni.GIPollTimerVal > SK_DPOLL_MAX) {
1828 pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX;
1829
1830 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E017, SKERR_HWI_E017MSG);
1831 }
1832 SK_OUT32(IoC, B28_DPT_INI, pAC->GIni.GIPollTimerVal);
1833 SK_OUT8(IoC, B28_DPT_CTRL, DPT_START);
1834 }
1835
1836#ifdef GENESIS
1837 if (pAC->GIni.GIGenesis) {
1838 /* start the Blink Source Counter */
1839 DWord = SK_BLK_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100;
1840
1841 SK_OUT32(IoC, B2_BSC_INI, DWord);
1842 SK_OUT8(IoC, B2_BSC_CTRL, BSC_START);
1843
1844 /*
1845 * Configure the MAC Arbiter and the Packet Arbiter.
1846 * They will be started once and never be stopped.
1847 */
1848 SkGeInitMacArb(pAC, IoC);
1849
1850 SkGeInitPktArb(pAC, IoC);
1851 }
1852#endif /* GENESIS */
1853
1854#ifdef YUKON
1855 if (pAC->GIni.GIYukon) {
1856 /* start Time Stamp Timer */
1857 SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_START);
1858 }
1859#endif /* YUKON */
1860
1861 /* enable the Tx Arbiters */
1862 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
1863 SK_OUT8(IoC, MR_ADDR(i, TXA_CTRL), TXA_ENA_ARB);
1864 }
1865
1866 /* enable the RAM Interface Arbiter */
1867 SkGeInitRamIface(pAC, IoC);
1868
1869} /* SkGeInit2 */
1870
1871/******************************************************************************
1872 *
1873 * SkGeInit() - Initialize the GE Adapter with the specified level.
1874 *
1875 * Description:
1876 * Level 0: Initialize the Module structures.
1877 * Level 1: Generic Hardware Initialization. The IOP/MemBase pointer has
1878 * to be set before calling this level.
1879 *
1880 * o Do a software reset.
1881 * o Clear all reset bits.
1882 * o Verify that the detected hardware is present.
1883 * Return an error if not.
1884 * o Get the hardware configuration
1885 * + Set GIMacsFound with the number of MACs.
1886 * + Store the RAM size in GIRamSize.
1887 * + Save the PCI Revision ID in GIPciHwRev.
1888 * o return an error
1889 * if Number of MACs > SK_MAX_MACS
1890 *
1891 * After returning from Level 0 the adapter
1892 * may be accessed with IO operations.
1893 *
1894 * Level 2: start the Blink Source Counter
1895 *
1896 * Returns:
1897 * 0: success
1898 * 1: Number of MACs exceeds SK_MAX_MACS (after level 1)
1899 * 2: Adapter not present or not accessible
1900 * 3: Illegal initialization level
1901 * 4: Initialization Level 1 Call missing
1902 * 5: Unexpected PHY type detected
1903 * 6: HW self test failed
1904 */
1905int SkGeInit(
1906SK_AC *pAC, /* adapter context */
1907SK_IOC IoC, /* IO context */
1908int Level) /* initialization level */
1909{
1910 int RetVal; /* return value */
1911 SK_U32 DWord;
1912
1913 RetVal = 0;
1914 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
1915 ("SkGeInit(Level %d)\n", Level));
1916
1917 switch (Level) {
1918 case SK_INIT_DATA:
1919 /* Initialization Level 0 */
1920 SkGeInit0(pAC, IoC);
1921 pAC->GIni.GILevel = SK_INIT_DATA;
1922 break;
1923
1924 case SK_INIT_IO:
1925 /* Initialization Level 1 */
1926 RetVal = SkGeInit1(pAC, IoC);
1927 if (RetVal != 0) {
1928 break;
1929 }
1930
1931 /* check if the adapter seems to be accessible */
1932 SK_OUT32(IoC, B2_IRQM_INI, SK_TEST_VAL);
1933 SK_IN32(IoC, B2_IRQM_INI, &DWord);
1934 SK_OUT32(IoC, B2_IRQM_INI, 0L);
1935
1936 if (DWord != SK_TEST_VAL) {
1937 RetVal = 2;
1938 break;
1939 }
1940
1941 /* check if the number of GIMacsFound matches SK_MAX_MACS */
1942 if (pAC->GIni.GIMacsFound > SK_MAX_MACS) {
1943 RetVal = 1;
1944 break;
1945 }
1946
1947 /* Level 1 successfully passed */
1948 pAC->GIni.GILevel = SK_INIT_IO;
1949 break;
1950
1951 case SK_INIT_RUN:
1952 /* Initialization Level 2 */
1953 if (pAC->GIni.GILevel != SK_INIT_IO) {
1954#ifndef SK_DIAG
1955 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E002, SKERR_HWI_E002MSG);
1956#endif /* !SK_DIAG */
1957 RetVal = 4;
1958 break;
1959 }
1960 SkGeInit2(pAC, IoC);
1961
1962 /* Level 2 successfully passed */
1963 pAC->GIni.GILevel = SK_INIT_RUN;
1964 break;
1965
1966 default:
1967 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E003, SKERR_HWI_E003MSG);
1968 RetVal = 3;
1969 break;
1970 }
1971
1972 return(RetVal);
1973} /* SkGeInit */
1974
1975
1976/******************************************************************************
1977 *
1978 * SkGeDeInit() - Deinitialize the adapter
1979 *
1980 * Description:
1981 * All ports of the adapter will be stopped if not already done.
1982 * Do a software reset and switch off all LEDs.
1983 *
1984 * Returns:
1985 * nothing
1986 */
1987void SkGeDeInit(
1988SK_AC *pAC, /* adapter context */
1989SK_IOC IoC) /* IO context */
1990{
1991 int i;
1992 SK_U16 Word;
1993
1994#ifdef SK_PHY_LP_MODE
1995 SK_U8 Byte;
1996 SK_U16 PmCtlSts;
1997#endif /* SK_PHY_LP_MODE */
1998
1999#if (!defined(SK_SLIM) && !defined(VCPU))
2000 /* ensure I2C is ready */
2001 SkI2cWaitIrq(pAC, IoC);
2002#endif
2003
2004 /* stop all current transfer activity */
2005 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
2006 if (pAC->GIni.GP[i].PState != SK_PRT_STOP &&
2007 pAC->GIni.GP[i].PState != SK_PRT_RESET) {
2008
2009 SkGeStopPort(pAC, IoC, i, SK_STOP_ALL, SK_HARD_RST);
2010 }
2011 }
2012
2013#ifdef SK_PHY_LP_MODE
2014 /*
2015 * for power saving purposes within mobile environments
2016 * we set the PHY to coma mode and switch to D3 power state.
2017 */
2018 if (pAC->GIni.GIYukonLite &&
2019 pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
2020
2021 /* for all ports switch PHY to coma mode */
2022 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
2023
2024 SkGmEnterLowPowerMode(pAC, IoC, i, PHY_PM_DEEP_SLEEP);
2025 }
2026
2027 if (pAC->GIni.GIVauxAvail) {
2028 /* switch power to VAUX */
2029 Byte = PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_ON | PC_VCC_OFF;
2030
2031 SK_OUT8(IoC, B0_POWER_CTRL, Byte);
2032 }
2033
2034 /* switch to D3 state */
2035 SK_IN16(IoC, PCI_C(PCI_PM_CTL_STS), &PmCtlSts);
2036
2037 PmCtlSts |= PCI_PM_STATE_D3;
2038
2039 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
2040
2041 SK_OUT16(IoC, PCI_C(PCI_PM_CTL_STS), PmCtlSts);
2042 }
2043#endif /* SK_PHY_LP_MODE */
2044
2045 /* Reset all bits in the PCI STATUS register */
2046 /*
2047 * Note: PCI Cfg cycles cannot be used, because they are not
2048 * available on some platforms after 'boot time'.
2049 */
2050 SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
2051
2052 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
2053 SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
2054 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
2055
2056 /* do the reset, all LEDs are switched off now */
2057 SK_OUT8(IoC, B0_CTST, CS_RST_SET);
2058
2059 pAC->GIni.GILevel = SK_INIT_DATA;
2060} /* SkGeDeInit */
2061
2062
2063/******************************************************************************
2064 *
2065 * SkGeInitPort() Initialize the specified port.
2066 *
2067 * Description:
2068 * PRxQSize, PXSQSize, and PXAQSize has to be
2069 * configured for the specified port before calling this function.
2070 * The descriptor rings has to be initialized too.
2071 *
2072 * o (Re)configure queues of the specified port.
2073 * o configure the MAC of the specified port.
2074 * o put ASIC and MAC(s) in operational mode.
2075 * o initialize Rx/Tx and Sync LED
2076 * o initialize RAM Buffers and MAC FIFOs
2077 *
2078 * The port is ready to connect when returning.
2079 *
2080 * Note:
2081 * The MAC's Rx and Tx state machine is still disabled when returning.
2082 *
2083 * Returns:
2084 * 0: success
2085 * 1: Queue size initialization error. The configured values
2086 * for PRxQSize, PXSQSize, or PXAQSize are invalid for one
2087 * or more queues. The specified port was NOT initialized.
2088 * An error log entry was generated.
2089 * 2: The port has to be stopped before it can be initialized again.
2090 */
2091int SkGeInitPort(
2092SK_AC *pAC, /* adapter context */
2093SK_IOC IoC, /* IO context */
2094int Port) /* Port to configure */
2095{
2096 SK_GEPORT *pPrt;
2097
2098 pPrt = &pAC->GIni.GP[Port];
2099
2100 if (SkGeCheckQSize(pAC, Port) != 0) {
2101 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E004, SKERR_HWI_E004MSG);
2102 return(1);
2103 }
2104
2105 if (pPrt->PState == SK_PRT_INIT || pPrt->PState == SK_PRT_RUN) {
2106 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E005, SKERR_HWI_E005MSG);
2107 return(2);
2108 }
2109
2110 /* configuration ok, initialize the Port now */
2111
2112#ifdef GENESIS
2113 if (pAC->GIni.GIGenesis) {
2114 /* initialize Rx, Tx and Link LED */
2115 /*
2116 * If 1000BT Phy needs LED initialization than swap
2117 * LED and XMAC initialization order
2118 */
2119 SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA);
2120 SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_ENA);
2121 /* The Link LED is initialized by RLMT or Diagnostics itself */
2122
2123 SkXmInitMac(pAC, IoC, Port);
2124 }
2125#endif /* GENESIS */
2126
2127#ifdef YUKON
2128 if (pAC->GIni.GIYukon) {
2129
2130 SkGmInitMac(pAC, IoC, Port);
2131 }
2132#endif /* YUKON */
2133
2134 /* do NOT initialize the Link Sync Counter */
2135
2136 SkGeInitMacFifo(pAC, IoC, Port);
2137
2138 SkGeInitRamBufs(pAC, IoC, Port);
2139
2140 if (pPrt->PXSQSize != 0) {
2141 /* enable Force Sync bit if synchronous queue available */
2142 SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_ENA_FSYNC);
2143 }
2144
2145 SkGeInitBmu(pAC, IoC, Port);
2146
2147 /* mark port as initialized */
2148 pPrt->PState = SK_PRT_INIT;
2149
2150 return(0);
2151} /* SkGeInitPort */
diff --git a/drivers/net/sk98lin/skgemib.c b/drivers/net/sk98lin/skgemib.c
new file mode 100644
index 000000000000..2991bc85cf2c
--- /dev/null
+++ b/drivers/net/sk98lin/skgemib.c
@@ -0,0 +1,1082 @@
1/*****************************************************************************
2 *
3 * Name: skgemib.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.11 $
6 * Date: $Date: 2003/09/15 13:38:12 $
7 * Purpose: Private Network Management Interface Management Database
8 *
9 ****************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * PRIVATE OID handler function prototypes
27 */
28PNMI_STATIC int Addr(SK_AC *pAC, SK_IOC IoC, int action,
29 SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance,
30 unsigned int TableIndex, SK_U32 NetIndex);
31PNMI_STATIC int CsumStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
32 char *pBuf, unsigned int *pLen, SK_U32 Instance,
33 unsigned int TableIndex, SK_U32 NetIndex);
34PNMI_STATIC int General(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
35 char *pBuf, unsigned int *pLen, SK_U32 Instance,
36 unsigned int TableIndex, SK_U32 NetIndex);
37PNMI_STATIC int Mac8023Stat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
38 char *pBuf, unsigned int *pLen, SK_U32 Instance,
39 unsigned int TableIndex, SK_U32 NetIndex);
40PNMI_STATIC int MacPrivateConf(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
41 char *pBuf, unsigned int *pLen, SK_U32 Instance,
42 unsigned int TableIndex, SK_U32 NetIndex);
43PNMI_STATIC int MacPrivateStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
44 char *pBuf, unsigned int *pLen, SK_U32 Instance,
45 unsigned int TableIndex, SK_U32 NetIndex);
46PNMI_STATIC int Monitor(SK_AC *pAC, SK_IOC IoC, int action,
47 SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance,
48 unsigned int TableIndex, SK_U32 NetIndex);
49PNMI_STATIC int OidStruct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
50 char *pBuf, unsigned int *pLen, SK_U32 Instance,
51 unsigned int TableIndex, SK_U32 NetIndex);
52PNMI_STATIC int Perform(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
53 char *pBuf, unsigned int* pLen, SK_U32 Instance,
54 unsigned int TableIndex, SK_U32 NetIndex);
55PNMI_STATIC int Rlmt(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
56 char *pBuf, unsigned int *pLen, SK_U32 Instance,
57 unsigned int TableIndex, SK_U32 NetIndex);
58PNMI_STATIC int RlmtStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
59 char *pBuf, unsigned int *pLen, SK_U32 Instance,
60 unsigned int TableIndex, SK_U32 NetIndex);
61PNMI_STATIC int SensorStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
62 char *pBuf, unsigned int *pLen, SK_U32 Instance,
63 unsigned int TableIndex, SK_U32 NetIndex);
64PNMI_STATIC int Vpd(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
65 char *pBuf, unsigned int *pLen, SK_U32 Instance,
66 unsigned int TableIndex, SK_U32 NetIndex);
67PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
68 char *pBuf, unsigned int *pLen, SK_U32 Instance,
69 unsigned int TableIndex, SK_U32 NetIndex);
70
71#ifdef SK_POWER_MGMT
72PNMI_STATIC int PowerManagement(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
73 char *pBuf, unsigned int *pLen, SK_U32 Instance,
74 unsigned int TableIndex, SK_U32 NetIndex);
75#endif /* SK_POWER_MGMT */
76
77#ifdef SK_DIAG_SUPPORT
78PNMI_STATIC int DiagActions(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
79 char *pBuf, unsigned int *pLen, SK_U32 Instance,
80 unsigned int TableIndex, SK_U32 NetIndex);
81#endif /* SK_DIAG_SUPPORT */
82
83
84/* defines *******************************************************************/
85#define ID_TABLE_SIZE (sizeof(IdTable)/sizeof(IdTable[0]))
86
87
88/* global variables **********************************************************/
89
90/*
91 * Table to correlate OID with handler function and index to
92 * hardware register stored in StatAddress if applicable.
93 */
94PNMI_STATIC const SK_PNMI_TAB_ENTRY IdTable[] = {
95 {OID_GEN_XMIT_OK,
96 0,
97 0,
98 0,
99 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX},
100 {OID_GEN_RCV_OK,
101 0,
102 0,
103 0,
104 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX},
105 {OID_GEN_XMIT_ERROR,
106 0,
107 0,
108 0,
109 SK_PNMI_RO, General, 0},
110 {OID_GEN_RCV_ERROR,
111 0,
112 0,
113 0,
114 SK_PNMI_RO, General, 0},
115 {OID_GEN_RCV_NO_BUFFER,
116 0,
117 0,
118 0,
119 SK_PNMI_RO, General, 0},
120 {OID_GEN_DIRECTED_FRAMES_XMIT,
121 0,
122 0,
123 0,
124 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNICAST},
125 {OID_GEN_MULTICAST_FRAMES_XMIT,
126 0,
127 0,
128 0,
129 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTICAST},
130 {OID_GEN_BROADCAST_FRAMES_XMIT,
131 0,
132 0,
133 0,
134 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_BROADCAST},
135 {OID_GEN_DIRECTED_FRAMES_RCV,
136 0,
137 0,
138 0,
139 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_UNICAST},
140 {OID_GEN_MULTICAST_FRAMES_RCV,
141 0,
142 0,
143 0,
144 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_MULTICAST},
145 {OID_GEN_BROADCAST_FRAMES_RCV,
146 0,
147 0,
148 0,
149 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_BROADCAST},
150 {OID_GEN_RCV_CRC_ERROR,
151 0,
152 0,
153 0,
154 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FCS},
155 {OID_GEN_TRANSMIT_QUEUE_LENGTH,
156 0,
157 0,
158 0,
159 SK_PNMI_RO, General, 0},
160 {OID_802_3_PERMANENT_ADDRESS,
161 0,
162 0,
163 0,
164 SK_PNMI_RO, Mac8023Stat, 0},
165 {OID_802_3_CURRENT_ADDRESS,
166 0,
167 0,
168 0,
169 SK_PNMI_RO, Mac8023Stat, 0},
170 {OID_802_3_RCV_ERROR_ALIGNMENT,
171 0,
172 0,
173 0,
174 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FRAMING},
175 {OID_802_3_XMIT_ONE_COLLISION,
176 0,
177 0,
178 0,
179 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_SINGLE_COL},
180 {OID_802_3_XMIT_MORE_COLLISIONS,
181 0,
182 0,
183 0,
184 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTI_COL},
185 {OID_802_3_XMIT_DEFERRED,
186 0,
187 0,
188 0,
189 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_DEFFERAL},
190 {OID_802_3_XMIT_MAX_COLLISIONS,
191 0,
192 0,
193 0,
194 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_EXCESS_COL},
195 {OID_802_3_RCV_OVERRUN,
196 0,
197 0,
198 0,
199 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_OVERFLOW},
200 {OID_802_3_XMIT_UNDERRUN,
201 0,
202 0,
203 0,
204 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNDERRUN},
205 {OID_802_3_XMIT_TIMES_CRS_LOST,
206 0,
207 0,
208 0,
209 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_CARRIER},
210 {OID_802_3_XMIT_LATE_COLLISIONS,
211 0,
212 0,
213 0,
214 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_LATE_COL},
215#ifdef SK_POWER_MGMT
216 {OID_PNP_CAPABILITIES,
217 0,
218 0,
219 0,
220 SK_PNMI_RO, PowerManagement, 0},
221 {OID_PNP_SET_POWER,
222 0,
223 0,
224 0,
225 SK_PNMI_WO, PowerManagement, 0},
226 {OID_PNP_QUERY_POWER,
227 0,
228 0,
229 0,
230 SK_PNMI_RO, PowerManagement, 0},
231 {OID_PNP_ADD_WAKE_UP_PATTERN,
232 0,
233 0,
234 0,
235 SK_PNMI_WO, PowerManagement, 0},
236 {OID_PNP_REMOVE_WAKE_UP_PATTERN,
237 0,
238 0,
239 0,
240 SK_PNMI_WO, PowerManagement, 0},
241 {OID_PNP_ENABLE_WAKE_UP,
242 0,
243 0,
244 0,
245 SK_PNMI_RW, PowerManagement, 0},
246#endif /* SK_POWER_MGMT */
247#ifdef SK_DIAG_SUPPORT
248 {OID_SKGE_DIAG_MODE,
249 0,
250 0,
251 0,
252 SK_PNMI_RW, DiagActions, 0},
253#endif /* SK_DIAG_SUPPORT */
254 {OID_SKGE_MDB_VERSION,
255 1,
256 0,
257 SK_PNMI_MAI_OFF(MgmtDBVersion),
258 SK_PNMI_RO, General, 0},
259 {OID_SKGE_SUPPORTED_LIST,
260 0,
261 0,
262 0,
263 SK_PNMI_RO, General, 0},
264 {OID_SKGE_ALL_DATA,
265 0,
266 0,
267 0,
268 SK_PNMI_RW, OidStruct, 0},
269 {OID_SKGE_VPD_FREE_BYTES,
270 1,
271 0,
272 SK_PNMI_MAI_OFF(VpdFreeBytes),
273 SK_PNMI_RO, Vpd, 0},
274 {OID_SKGE_VPD_ENTRIES_LIST,
275 1,
276 0,
277 SK_PNMI_MAI_OFF(VpdEntriesList),
278 SK_PNMI_RO, Vpd, 0},
279 {OID_SKGE_VPD_ENTRIES_NUMBER,
280 1,
281 0,
282 SK_PNMI_MAI_OFF(VpdEntriesNumber),
283 SK_PNMI_RO, Vpd, 0},
284 {OID_SKGE_VPD_KEY,
285 SK_PNMI_VPD_ENTRIES,
286 sizeof(SK_PNMI_VPD),
287 SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdKey),
288 SK_PNMI_RO, Vpd, 0},
289 {OID_SKGE_VPD_VALUE,
290 SK_PNMI_VPD_ENTRIES,
291 sizeof(SK_PNMI_VPD),
292 SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdValue),
293 SK_PNMI_RO, Vpd, 0},
294 {OID_SKGE_VPD_ACCESS,
295 SK_PNMI_VPD_ENTRIES,
296 sizeof(SK_PNMI_VPD),
297 SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAccess),
298 SK_PNMI_RO, Vpd, 0},
299 {OID_SKGE_VPD_ACTION,
300 SK_PNMI_VPD_ENTRIES,
301 sizeof(SK_PNMI_VPD),
302 SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAction),
303 SK_PNMI_RW, Vpd, 0},
304 {OID_SKGE_PORT_NUMBER,
305 1,
306 0,
307 SK_PNMI_MAI_OFF(PortNumber),
308 SK_PNMI_RO, General, 0},
309 {OID_SKGE_DEVICE_TYPE,
310 1,
311 0,
312 SK_PNMI_MAI_OFF(DeviceType),
313 SK_PNMI_RO, General, 0},
314 {OID_SKGE_DRIVER_DESCR,
315 1,
316 0,
317 SK_PNMI_MAI_OFF(DriverDescr),
318 SK_PNMI_RO, General, 0},
319 {OID_SKGE_DRIVER_VERSION,
320 1,
321 0,
322 SK_PNMI_MAI_OFF(DriverVersion),
323 SK_PNMI_RO, General, 0},
324 {OID_SKGE_DRIVER_RELDATE,
325 1,
326 0,
327 SK_PNMI_MAI_OFF(DriverReleaseDate),
328 SK_PNMI_RO, General, 0},
329 {OID_SKGE_DRIVER_FILENAME,
330 1,
331 0,
332 SK_PNMI_MAI_OFF(DriverFileName),
333 SK_PNMI_RO, General, 0},
334 {OID_SKGE_HW_DESCR,
335 1,
336 0,
337 SK_PNMI_MAI_OFF(HwDescr),
338 SK_PNMI_RO, General, 0},
339 {OID_SKGE_HW_VERSION,
340 1,
341 0,
342 SK_PNMI_MAI_OFF(HwVersion),
343 SK_PNMI_RO, General, 0},
344 {OID_SKGE_CHIPSET,
345 1,
346 0,
347 SK_PNMI_MAI_OFF(Chipset),
348 SK_PNMI_RO, General, 0},
349 {OID_SKGE_CHIPID,
350 1,
351 0,
352 SK_PNMI_MAI_OFF(ChipId),
353 SK_PNMI_RO, General, 0},
354 {OID_SKGE_RAMSIZE,
355 1,
356 0,
357 SK_PNMI_MAI_OFF(RamSize),
358 SK_PNMI_RO, General, 0},
359 {OID_SKGE_VAUXAVAIL,
360 1,
361 0,
362 SK_PNMI_MAI_OFF(VauxAvail),
363 SK_PNMI_RO, General, 0},
364 {OID_SKGE_ACTION,
365 1,
366 0,
367 SK_PNMI_MAI_OFF(Action),
368 SK_PNMI_RW, Perform, 0},
369 {OID_SKGE_RESULT,
370 1,
371 0,
372 SK_PNMI_MAI_OFF(TestResult),
373 SK_PNMI_RO, General, 0},
374 {OID_SKGE_BUS_TYPE,
375 1,
376 0,
377 SK_PNMI_MAI_OFF(BusType),
378 SK_PNMI_RO, General, 0},
379 {OID_SKGE_BUS_SPEED,
380 1,
381 0,
382 SK_PNMI_MAI_OFF(BusSpeed),
383 SK_PNMI_RO, General, 0},
384 {OID_SKGE_BUS_WIDTH,
385 1,
386 0,
387 SK_PNMI_MAI_OFF(BusWidth),
388 SK_PNMI_RO, General, 0},
389 {OID_SKGE_TX_SW_QUEUE_LEN,
390 1,
391 0,
392 SK_PNMI_MAI_OFF(TxSwQueueLen),
393 SK_PNMI_RO, General, 0},
394 {OID_SKGE_TX_SW_QUEUE_MAX,
395 1,
396 0,
397 SK_PNMI_MAI_OFF(TxSwQueueMax),
398 SK_PNMI_RO, General, 0},
399 {OID_SKGE_TX_RETRY,
400 1,
401 0,
402 SK_PNMI_MAI_OFF(TxRetryCts),
403 SK_PNMI_RO, General, 0},
404 {OID_SKGE_RX_INTR_CTS,
405 1,
406 0,
407 SK_PNMI_MAI_OFF(RxIntrCts),
408 SK_PNMI_RO, General, 0},
409 {OID_SKGE_TX_INTR_CTS,
410 1,
411 0,
412 SK_PNMI_MAI_OFF(TxIntrCts),
413 SK_PNMI_RO, General, 0},
414 {OID_SKGE_RX_NO_BUF_CTS,
415 1,
416 0,
417 SK_PNMI_MAI_OFF(RxNoBufCts),
418 SK_PNMI_RO, General, 0},
419 {OID_SKGE_TX_NO_BUF_CTS,
420 1,
421 0,
422 SK_PNMI_MAI_OFF(TxNoBufCts),
423 SK_PNMI_RO, General, 0},
424 {OID_SKGE_TX_USED_DESCR_NO,
425 1,
426 0,
427 SK_PNMI_MAI_OFF(TxUsedDescrNo),
428 SK_PNMI_RO, General, 0},
429 {OID_SKGE_RX_DELIVERED_CTS,
430 1,
431 0,
432 SK_PNMI_MAI_OFF(RxDeliveredCts),
433 SK_PNMI_RO, General, 0},
434 {OID_SKGE_RX_OCTETS_DELIV_CTS,
435 1,
436 0,
437 SK_PNMI_MAI_OFF(RxOctetsDeliveredCts),
438 SK_PNMI_RO, General, 0},
439 {OID_SKGE_RX_HW_ERROR_CTS,
440 1,
441 0,
442 SK_PNMI_MAI_OFF(RxHwErrorsCts),
443 SK_PNMI_RO, General, 0},
444 {OID_SKGE_TX_HW_ERROR_CTS,
445 1,
446 0,
447 SK_PNMI_MAI_OFF(TxHwErrorsCts),
448 SK_PNMI_RO, General, 0},
449 {OID_SKGE_IN_ERRORS_CTS,
450 1,
451 0,
452 SK_PNMI_MAI_OFF(InErrorsCts),
453 SK_PNMI_RO, General, 0},
454 {OID_SKGE_OUT_ERROR_CTS,
455 1,
456 0,
457 SK_PNMI_MAI_OFF(OutErrorsCts),
458 SK_PNMI_RO, General, 0},
459 {OID_SKGE_ERR_RECOVERY_CTS,
460 1,
461 0,
462 SK_PNMI_MAI_OFF(ErrRecoveryCts),
463 SK_PNMI_RO, General, 0},
464 {OID_SKGE_SYSUPTIME,
465 1,
466 0,
467 SK_PNMI_MAI_OFF(SysUpTime),
468 SK_PNMI_RO, General, 0},
469 {OID_SKGE_SENSOR_NUMBER,
470 1,
471 0,
472 SK_PNMI_MAI_OFF(SensorNumber),
473 SK_PNMI_RO, General, 0},
474 {OID_SKGE_SENSOR_INDEX,
475 SK_PNMI_SENSOR_ENTRIES,
476 sizeof(SK_PNMI_SENSOR),
477 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorIndex),
478 SK_PNMI_RO, SensorStat, 0},
479 {OID_SKGE_SENSOR_DESCR,
480 SK_PNMI_SENSOR_ENTRIES,
481 sizeof(SK_PNMI_SENSOR),
482 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorDescr),
483 SK_PNMI_RO, SensorStat, 0},
484 {OID_SKGE_SENSOR_TYPE,
485 SK_PNMI_SENSOR_ENTRIES,
486 sizeof(SK_PNMI_SENSOR),
487 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorType),
488 SK_PNMI_RO, SensorStat, 0},
489 {OID_SKGE_SENSOR_VALUE,
490 SK_PNMI_SENSOR_ENTRIES,
491 sizeof(SK_PNMI_SENSOR),
492 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorValue),
493 SK_PNMI_RO, SensorStat, 0},
494 {OID_SKGE_SENSOR_WAR_THRES_LOW,
495 SK_PNMI_SENSOR_ENTRIES,
496 sizeof(SK_PNMI_SENSOR),
497 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdLow),
498 SK_PNMI_RO, SensorStat, 0},
499 {OID_SKGE_SENSOR_WAR_THRES_UPP,
500 SK_PNMI_SENSOR_ENTRIES,
501 sizeof(SK_PNMI_SENSOR),
502 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdHigh),
503 SK_PNMI_RO, SensorStat, 0},
504 {OID_SKGE_SENSOR_ERR_THRES_LOW,
505 SK_PNMI_SENSOR_ENTRIES,
506 sizeof(SK_PNMI_SENSOR),
507 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdLow),
508 SK_PNMI_RO, SensorStat, 0},
509 {OID_SKGE_SENSOR_ERR_THRES_UPP,
510 SK_PNMI_SENSOR_ENTRIES,
511 sizeof(SK_PNMI_SENSOR),
512 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdHigh),
513 SK_PNMI_RO, SensorStat, 0},
514 {OID_SKGE_SENSOR_STATUS,
515 SK_PNMI_SENSOR_ENTRIES,
516 sizeof(SK_PNMI_SENSOR),
517 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorStatus),
518 SK_PNMI_RO, SensorStat, 0},
519 {OID_SKGE_SENSOR_WAR_CTS,
520 SK_PNMI_SENSOR_ENTRIES,
521 sizeof(SK_PNMI_SENSOR),
522 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningCts),
523 SK_PNMI_RO, SensorStat, 0},
524 {OID_SKGE_SENSOR_ERR_CTS,
525 SK_PNMI_SENSOR_ENTRIES,
526 sizeof(SK_PNMI_SENSOR),
527 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorCts),
528 SK_PNMI_RO, SensorStat, 0},
529 {OID_SKGE_SENSOR_WAR_TIME,
530 SK_PNMI_SENSOR_ENTRIES,
531 sizeof(SK_PNMI_SENSOR),
532 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningTimestamp),
533 SK_PNMI_RO, SensorStat, 0},
534 {OID_SKGE_SENSOR_ERR_TIME,
535 SK_PNMI_SENSOR_ENTRIES,
536 sizeof(SK_PNMI_SENSOR),
537 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorTimestamp),
538 SK_PNMI_RO, SensorStat, 0},
539 {OID_SKGE_CHKSM_NUMBER,
540 1,
541 0,
542 SK_PNMI_MAI_OFF(ChecksumNumber),
543 SK_PNMI_RO, General, 0},
544 {OID_SKGE_CHKSM_RX_OK_CTS,
545 SKCS_NUM_PROTOCOLS,
546 sizeof(SK_PNMI_CHECKSUM),
547 SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxOkCts),
548 SK_PNMI_RO, CsumStat, 0},
549 {OID_SKGE_CHKSM_RX_UNABLE_CTS,
550 SKCS_NUM_PROTOCOLS,
551 sizeof(SK_PNMI_CHECKSUM),
552 SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxUnableCts),
553 SK_PNMI_RO, CsumStat, 0},
554 {OID_SKGE_CHKSM_RX_ERR_CTS,
555 SKCS_NUM_PROTOCOLS,
556 sizeof(SK_PNMI_CHECKSUM),
557 SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxErrCts),
558 SK_PNMI_RO, CsumStat, 0},
559 {OID_SKGE_CHKSM_TX_OK_CTS,
560 SKCS_NUM_PROTOCOLS,
561 sizeof(SK_PNMI_CHECKSUM),
562 SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxOkCts),
563 SK_PNMI_RO, CsumStat, 0},
564 {OID_SKGE_CHKSM_TX_UNABLE_CTS,
565 SKCS_NUM_PROTOCOLS,
566 sizeof(SK_PNMI_CHECKSUM),
567 SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxUnableCts),
568 SK_PNMI_RO, CsumStat, 0},
569 {OID_SKGE_STAT_TX,
570 SK_PNMI_MAC_ENTRIES,
571 sizeof(SK_PNMI_STAT),
572 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOkCts),
573 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX},
574 {OID_SKGE_STAT_TX_OCTETS,
575 SK_PNMI_MAC_ENTRIES,
576 sizeof(SK_PNMI_STAT),
577 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOctetsOkCts),
578 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_OCTET},
579 {OID_SKGE_STAT_TX_BROADCAST,
580 SK_PNMI_MAC_ENTRIES,
581 sizeof(SK_PNMI_STAT),
582 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBroadcastOkCts),
583 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BROADCAST},
584 {OID_SKGE_STAT_TX_MULTICAST,
585 SK_PNMI_MAC_ENTRIES,
586 sizeof(SK_PNMI_STAT),
587 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMulticastOkCts),
588 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTICAST},
589 {OID_SKGE_STAT_TX_UNICAST,
590 SK_PNMI_MAC_ENTRIES,
591 sizeof(SK_PNMI_STAT),
592 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUnicastOkCts),
593 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNICAST},
594 {OID_SKGE_STAT_TX_LONGFRAMES,
595 SK_PNMI_MAC_ENTRIES,
596 sizeof(SK_PNMI_STAT),
597 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLongFramesCts),
598 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LONGFRAMES},
599 {OID_SKGE_STAT_TX_BURST,
600 SK_PNMI_MAC_ENTRIES,
601 sizeof(SK_PNMI_STAT),
602 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBurstCts),
603 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BURST},
604 {OID_SKGE_STAT_TX_PFLOWC,
605 SK_PNMI_MAC_ENTRIES,
606 sizeof(SK_PNMI_STAT),
607 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxPauseMacCtrlCts),
608 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_PMACC},
609 {OID_SKGE_STAT_TX_FLOWC,
610 SK_PNMI_MAC_ENTRIES,
611 sizeof(SK_PNMI_STAT),
612 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMacCtrlCts),
613 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MACC},
614 {OID_SKGE_STAT_TX_SINGLE_COL,
615 SK_PNMI_MAC_ENTRIES,
616 sizeof(SK_PNMI_STAT),
617 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSingleCollisionCts),
618 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SINGLE_COL},
619 {OID_SKGE_STAT_TX_MULTI_COL,
620 SK_PNMI_MAC_ENTRIES,
621 sizeof(SK_PNMI_STAT),
622 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMultipleCollisionCts),
623 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTI_COL},
624 {OID_SKGE_STAT_TX_EXCESS_COL,
625 SK_PNMI_MAC_ENTRIES,
626 sizeof(SK_PNMI_STAT),
627 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveCollisionCts),
628 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_COL},
629 {OID_SKGE_STAT_TX_LATE_COL,
630 SK_PNMI_MAC_ENTRIES,
631 sizeof(SK_PNMI_STAT),
632 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLateCollisionCts),
633 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LATE_COL},
634 {OID_SKGE_STAT_TX_DEFFERAL,
635 SK_PNMI_MAC_ENTRIES,
636 sizeof(SK_PNMI_STAT),
637 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxDeferralCts),
638 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_DEFFERAL},
639 {OID_SKGE_STAT_TX_EXCESS_DEF,
640 SK_PNMI_MAC_ENTRIES,
641 sizeof(SK_PNMI_STAT),
642 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveDeferralCts),
643 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_DEF},
644 {OID_SKGE_STAT_TX_UNDERRUN,
645 SK_PNMI_MAC_ENTRIES,
646 sizeof(SK_PNMI_STAT),
647 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxFifoUnderrunCts),
648 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNDERRUN},
649 {OID_SKGE_STAT_TX_CARRIER,
650 SK_PNMI_MAC_ENTRIES,
651 sizeof(SK_PNMI_STAT),
652 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxCarrierCts),
653 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_CARRIER},
654/* {OID_SKGE_STAT_TX_UTIL,
655 SK_PNMI_MAC_ENTRIES,
656 sizeof(SK_PNMI_STAT),
657 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUtilization),
658 SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */
659 {OID_SKGE_STAT_TX_64,
660 SK_PNMI_MAC_ENTRIES,
661 sizeof(SK_PNMI_STAT),
662 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx64Cts),
663 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_64},
664 {OID_SKGE_STAT_TX_127,
665 SK_PNMI_MAC_ENTRIES,
666 sizeof(SK_PNMI_STAT),
667 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx127Cts),
668 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_127},
669 {OID_SKGE_STAT_TX_255,
670 SK_PNMI_MAC_ENTRIES,
671 sizeof(SK_PNMI_STAT),
672 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx255Cts),
673 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_255},
674 {OID_SKGE_STAT_TX_511,
675 SK_PNMI_MAC_ENTRIES,
676 sizeof(SK_PNMI_STAT),
677 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx511Cts),
678 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_511},
679 {OID_SKGE_STAT_TX_1023,
680 SK_PNMI_MAC_ENTRIES,
681 sizeof(SK_PNMI_STAT),
682 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx1023Cts),
683 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_1023},
684 {OID_SKGE_STAT_TX_MAX,
685 SK_PNMI_MAC_ENTRIES,
686 sizeof(SK_PNMI_STAT),
687 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMaxCts),
688 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MAX},
689 {OID_SKGE_STAT_TX_SYNC,
690 SK_PNMI_MAC_ENTRIES,
691 sizeof(SK_PNMI_STAT),
692 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncCts),
693 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC},
694 {OID_SKGE_STAT_TX_SYNC_OCTETS,
695 SK_PNMI_MAC_ENTRIES,
696 sizeof(SK_PNMI_STAT),
697 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncOctetsCts),
698 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC_OCTET},
699 {OID_SKGE_STAT_RX,
700 SK_PNMI_MAC_ENTRIES,
701 sizeof(SK_PNMI_STAT),
702 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOkCts),
703 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX},
704 {OID_SKGE_STAT_RX_OCTETS,
705 SK_PNMI_MAC_ENTRIES,
706 sizeof(SK_PNMI_STAT),
707 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOctetsOkCts),
708 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OCTET},
709 {OID_SKGE_STAT_RX_BROADCAST,
710 SK_PNMI_MAC_ENTRIES,
711 sizeof(SK_PNMI_STAT),
712 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBroadcastOkCts),
713 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BROADCAST},
714 {OID_SKGE_STAT_RX_MULTICAST,
715 SK_PNMI_MAC_ENTRIES,
716 sizeof(SK_PNMI_STAT),
717 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMulticastOkCts),
718 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MULTICAST},
719 {OID_SKGE_STAT_RX_UNICAST,
720 SK_PNMI_MAC_ENTRIES,
721 sizeof(SK_PNMI_STAT),
722 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUnicastOkCts),
723 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_UNICAST},
724 {OID_SKGE_STAT_RX_LONGFRAMES,
725 SK_PNMI_MAC_ENTRIES,
726 sizeof(SK_PNMI_STAT),
727 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxLongFramesCts),
728 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_LONGFRAMES},
729 {OID_SKGE_STAT_RX_PFLOWC,
730 SK_PNMI_MAC_ENTRIES,
731 sizeof(SK_PNMI_STAT),
732 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlCts),
733 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC},
734 {OID_SKGE_STAT_RX_FLOWC,
735 SK_PNMI_MAC_ENTRIES,
736 sizeof(SK_PNMI_STAT),
737 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlCts),
738 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC},
739 {OID_SKGE_STAT_RX_PFLOWC_ERR,
740 SK_PNMI_MAC_ENTRIES,
741 sizeof(SK_PNMI_STAT),
742 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlErrorCts),
743 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC_ERR},
744 {OID_SKGE_STAT_RX_FLOWC_UNKWN,
745 SK_PNMI_MAC_ENTRIES,
746 sizeof(SK_PNMI_STAT),
747 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlUnknownCts),
748 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC_UNKWN},
749 {OID_SKGE_STAT_RX_BURST,
750 SK_PNMI_MAC_ENTRIES,
751 sizeof(SK_PNMI_STAT),
752 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBurstCts),
753 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BURST},
754 {OID_SKGE_STAT_RX_MISSED,
755 SK_PNMI_MAC_ENTRIES,
756 sizeof(SK_PNMI_STAT),
757 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMissedCts),
758 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MISSED},
759 {OID_SKGE_STAT_RX_FRAMING,
760 SK_PNMI_MAC_ENTRIES,
761 sizeof(SK_PNMI_STAT),
762 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFramingCts),
763 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FRAMING},
764 {OID_SKGE_STAT_RX_OVERFLOW,
765 SK_PNMI_MAC_ENTRIES,
766 sizeof(SK_PNMI_STAT),
767 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFifoOverflowCts),
768 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OVERFLOW},
769 {OID_SKGE_STAT_RX_JABBER,
770 SK_PNMI_MAC_ENTRIES,
771 sizeof(SK_PNMI_STAT),
772 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxJabberCts),
773 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_JABBER},
774 {OID_SKGE_STAT_RX_CARRIER,
775 SK_PNMI_MAC_ENTRIES,
776 sizeof(SK_PNMI_STAT),
777 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCarrierCts),
778 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CARRIER},
779 {OID_SKGE_STAT_RX_IR_LENGTH,
780 SK_PNMI_MAC_ENTRIES,
781 sizeof(SK_PNMI_STAT),
782 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxIRLengthCts),
783 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_IRLENGTH},
784 {OID_SKGE_STAT_RX_SYMBOL,
785 SK_PNMI_MAC_ENTRIES,
786 sizeof(SK_PNMI_STAT),
787 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxSymbolCts),
788 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SYMBOL},
789 {OID_SKGE_STAT_RX_SHORTS,
790 SK_PNMI_MAC_ENTRIES,
791 sizeof(SK_PNMI_STAT),
792 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxShortsCts),
793 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SHORTS},
794 {OID_SKGE_STAT_RX_RUNT,
795 SK_PNMI_MAC_ENTRIES,
796 sizeof(SK_PNMI_STAT),
797 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxRuntCts),
798 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_RUNT},
799 {OID_SKGE_STAT_RX_CEXT,
800 SK_PNMI_MAC_ENTRIES,
801 sizeof(SK_PNMI_STAT),
802 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCextCts),
803 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CEXT},
804 {OID_SKGE_STAT_RX_TOO_LONG,
805 SK_PNMI_MAC_ENTRIES,
806 sizeof(SK_PNMI_STAT),
807 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxTooLongCts),
808 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_TOO_LONG},
809 {OID_SKGE_STAT_RX_FCS,
810 SK_PNMI_MAC_ENTRIES,
811 sizeof(SK_PNMI_STAT),
812 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFcsCts),
813 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FCS},
814/* {OID_SKGE_STAT_RX_UTIL,
815 SK_PNMI_MAC_ENTRIES,
816 sizeof(SK_PNMI_STAT),
817 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUtilization),
818 SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */
819 {OID_SKGE_STAT_RX_64,
820 SK_PNMI_MAC_ENTRIES,
821 sizeof(SK_PNMI_STAT),
822 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx64Cts),
823 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_64},
824 {OID_SKGE_STAT_RX_127,
825 SK_PNMI_MAC_ENTRIES,
826 sizeof(SK_PNMI_STAT),
827 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx127Cts),
828 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_127},
829 {OID_SKGE_STAT_RX_255,
830 SK_PNMI_MAC_ENTRIES,
831 sizeof(SK_PNMI_STAT),
832 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx255Cts),
833 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_255},
834 {OID_SKGE_STAT_RX_511,
835 SK_PNMI_MAC_ENTRIES,
836 sizeof(SK_PNMI_STAT),
837 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx511Cts),
838 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_511},
839 {OID_SKGE_STAT_RX_1023,
840 SK_PNMI_MAC_ENTRIES,
841 sizeof(SK_PNMI_STAT),
842 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx1023Cts),
843 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_1023},
844 {OID_SKGE_STAT_RX_MAX,
845 SK_PNMI_MAC_ENTRIES,
846 sizeof(SK_PNMI_STAT),
847 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMaxCts),
848 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MAX},
849 {OID_SKGE_PHYS_CUR_ADDR,
850 SK_PNMI_MAC_ENTRIES,
851 sizeof(SK_PNMI_CONF),
852 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacCurrentAddr),
853 SK_PNMI_RW, Addr, 0},
854 {OID_SKGE_PHYS_FAC_ADDR,
855 SK_PNMI_MAC_ENTRIES,
856 sizeof(SK_PNMI_CONF),
857 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacFactoryAddr),
858 SK_PNMI_RO, Addr, 0},
859 {OID_SKGE_PMD,
860 SK_PNMI_MAC_ENTRIES,
861 sizeof(SK_PNMI_CONF),
862 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPMD),
863 SK_PNMI_RO, MacPrivateConf, 0},
864 {OID_SKGE_CONNECTOR,
865 SK_PNMI_MAC_ENTRIES,
866 sizeof(SK_PNMI_CONF),
867 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfConnector),
868 SK_PNMI_RO, MacPrivateConf, 0},
869 {OID_SKGE_PHY_TYPE,
870 SK_PNMI_MAC_ENTRIES,
871 sizeof(SK_PNMI_CONF),
872 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyType),
873 SK_PNMI_RO, MacPrivateConf, 0},
874#ifdef SK_PHY_LP_MODE
875 {OID_SKGE_PHY_LP_MODE,
876 SK_PNMI_MAC_ENTRIES,
877 sizeof(SK_PNMI_CONF),
878 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyMode),
879 SK_PNMI_RW, MacPrivateConf, 0},
880#endif
881 {OID_SKGE_LINK_CAP,
882 SK_PNMI_MAC_ENTRIES,
883 sizeof(SK_PNMI_CONF),
884 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkCapability),
885 SK_PNMI_RO, MacPrivateConf, 0},
886 {OID_SKGE_LINK_MODE,
887 SK_PNMI_MAC_ENTRIES,
888 sizeof(SK_PNMI_CONF),
889 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkMode),
890 SK_PNMI_RW, MacPrivateConf, 0},
891 {OID_SKGE_LINK_MODE_STATUS,
892 SK_PNMI_MAC_ENTRIES,
893 sizeof(SK_PNMI_CONF),
894 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkModeStatus),
895 SK_PNMI_RO, MacPrivateConf, 0},
896 {OID_SKGE_LINK_STATUS,
897 SK_PNMI_MAC_ENTRIES,
898 sizeof(SK_PNMI_CONF),
899 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkStatus),
900 SK_PNMI_RO, MacPrivateConf, 0},
901 {OID_SKGE_FLOWCTRL_CAP,
902 SK_PNMI_MAC_ENTRIES,
903 sizeof(SK_PNMI_CONF),
904 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlCapability),
905 SK_PNMI_RO, MacPrivateConf, 0},
906 {OID_SKGE_FLOWCTRL_MODE,
907 SK_PNMI_MAC_ENTRIES,
908 sizeof(SK_PNMI_CONF),
909 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlMode),
910 SK_PNMI_RW, MacPrivateConf, 0},
911 {OID_SKGE_FLOWCTRL_STATUS,
912 SK_PNMI_MAC_ENTRIES,
913 sizeof(SK_PNMI_CONF),
914 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlStatus),
915 SK_PNMI_RO, MacPrivateConf, 0},
916 {OID_SKGE_PHY_OPERATION_CAP,
917 SK_PNMI_MAC_ENTRIES,
918 sizeof(SK_PNMI_CONF),
919 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationCapability),
920 SK_PNMI_RO, MacPrivateConf, 0},
921 {OID_SKGE_PHY_OPERATION_MODE,
922 SK_PNMI_MAC_ENTRIES,
923 sizeof(SK_PNMI_CONF),
924 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationMode),
925 SK_PNMI_RW, MacPrivateConf, 0},
926 {OID_SKGE_PHY_OPERATION_STATUS,
927 SK_PNMI_MAC_ENTRIES,
928 sizeof(SK_PNMI_CONF),
929 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationStatus),
930 SK_PNMI_RO, MacPrivateConf, 0},
931 {OID_SKGE_SPEED_CAP,
932 SK_PNMI_MAC_ENTRIES,
933 sizeof(SK_PNMI_CONF),
934 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedCapability),
935 SK_PNMI_RO, MacPrivateConf, 0},
936 {OID_SKGE_SPEED_MODE,
937 SK_PNMI_MAC_ENTRIES,
938 sizeof(SK_PNMI_CONF),
939 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedMode),
940 SK_PNMI_RW, MacPrivateConf, 0},
941 {OID_SKGE_SPEED_STATUS,
942 SK_PNMI_MAC_ENTRIES,
943 sizeof(SK_PNMI_CONF),
944 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedStatus),
945 SK_PNMI_RO, MacPrivateConf, 0},
946 {OID_SKGE_TRAP,
947 1,
948 0,
949 SK_PNMI_MAI_OFF(Trap),
950 SK_PNMI_RO, General, 0},
951 {OID_SKGE_TRAP_NUMBER,
952 1,
953 0,
954 SK_PNMI_MAI_OFF(TrapNumber),
955 SK_PNMI_RO, General, 0},
956 {OID_SKGE_RLMT_MODE,
957 1,
958 0,
959 SK_PNMI_MAI_OFF(RlmtMode),
960 SK_PNMI_RW, Rlmt, 0},
961 {OID_SKGE_RLMT_PORT_NUMBER,
962 1,
963 0,
964 SK_PNMI_MAI_OFF(RlmtPortNumber),
965 SK_PNMI_RO, Rlmt, 0},
966 {OID_SKGE_RLMT_PORT_ACTIVE,
967 1,
968 0,
969 SK_PNMI_MAI_OFF(RlmtPortActive),
970 SK_PNMI_RO, Rlmt, 0},
971 {OID_SKGE_RLMT_PORT_PREFERRED,
972 1,
973 0,
974 SK_PNMI_MAI_OFF(RlmtPortPreferred),
975 SK_PNMI_RW, Rlmt, 0},
976 {OID_SKGE_RLMT_CHANGE_CTS,
977 1,
978 0,
979 SK_PNMI_MAI_OFF(RlmtChangeCts),
980 SK_PNMI_RO, Rlmt, 0},
981 {OID_SKGE_RLMT_CHANGE_TIME,
982 1,
983 0,
984 SK_PNMI_MAI_OFF(RlmtChangeTime),
985 SK_PNMI_RO, Rlmt, 0},
986 {OID_SKGE_RLMT_CHANGE_ESTIM,
987 1,
988 0,
989 SK_PNMI_MAI_OFF(RlmtChangeEstimate),
990 SK_PNMI_RO, Rlmt, 0},
991 {OID_SKGE_RLMT_CHANGE_THRES,
992 1,
993 0,
994 SK_PNMI_MAI_OFF(RlmtChangeThreshold),
995 SK_PNMI_RW, Rlmt, 0},
996 {OID_SKGE_RLMT_PORT_INDEX,
997 SK_PNMI_MAC_ENTRIES,
998 sizeof(SK_PNMI_RLMT),
999 SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtIndex),
1000 SK_PNMI_RO, RlmtStat, 0},
1001 {OID_SKGE_RLMT_STATUS,
1002 SK_PNMI_MAC_ENTRIES,
1003 sizeof(SK_PNMI_RLMT),
1004 SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtStatus),
1005 SK_PNMI_RO, RlmtStat, 0},
1006 {OID_SKGE_RLMT_TX_HELLO_CTS,
1007 SK_PNMI_MAC_ENTRIES,
1008 sizeof(SK_PNMI_RLMT),
1009 SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxHelloCts),
1010 SK_PNMI_RO, RlmtStat, 0},
1011 {OID_SKGE_RLMT_RX_HELLO_CTS,
1012 SK_PNMI_MAC_ENTRIES,
1013 sizeof(SK_PNMI_RLMT),
1014 SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxHelloCts),
1015 SK_PNMI_RO, RlmtStat, 0},
1016 {OID_SKGE_RLMT_TX_SP_REQ_CTS,
1017 SK_PNMI_MAC_ENTRIES,
1018 sizeof(SK_PNMI_RLMT),
1019 SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxSpHelloReqCts),
1020 SK_PNMI_RO, RlmtStat, 0},
1021 {OID_SKGE_RLMT_RX_SP_CTS,
1022 SK_PNMI_MAC_ENTRIES,
1023 sizeof(SK_PNMI_RLMT),
1024 SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxSpHelloCts),
1025 SK_PNMI_RO, RlmtStat, 0},
1026 {OID_SKGE_RLMT_MONITOR_NUMBER,
1027 1,
1028 0,
1029 SK_PNMI_MAI_OFF(RlmtMonitorNumber),
1030 SK_PNMI_RO, General, 0},
1031 {OID_SKGE_RLMT_MONITOR_INDEX,
1032 SK_PNMI_MONITOR_ENTRIES,
1033 sizeof(SK_PNMI_RLMT_MONITOR),
1034 SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorIndex),
1035 SK_PNMI_RO, Monitor, 0},
1036 {OID_SKGE_RLMT_MONITOR_ADDR,
1037 SK_PNMI_MONITOR_ENTRIES,
1038 sizeof(SK_PNMI_RLMT_MONITOR),
1039 SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAddr),
1040 SK_PNMI_RO, Monitor, 0},
1041 {OID_SKGE_RLMT_MONITOR_ERRS,
1042 SK_PNMI_MONITOR_ENTRIES,
1043 sizeof(SK_PNMI_RLMT_MONITOR),
1044 SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorErrorCts),
1045 SK_PNMI_RO, Monitor, 0},
1046 {OID_SKGE_RLMT_MONITOR_TIMESTAMP,
1047 SK_PNMI_MONITOR_ENTRIES,
1048 sizeof(SK_PNMI_RLMT_MONITOR),
1049 SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorTimestamp),
1050 SK_PNMI_RO, Monitor, 0},
1051 {OID_SKGE_RLMT_MONITOR_ADMIN,
1052 SK_PNMI_MONITOR_ENTRIES,
1053 sizeof(SK_PNMI_RLMT_MONITOR),
1054 SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAdmin),
1055 SK_PNMI_RW, Monitor, 0},
1056 {OID_SKGE_MTU,
1057 1,
1058 0,
1059 SK_PNMI_MAI_OFF(MtuSize),
1060 SK_PNMI_RW, MacPrivateConf, 0},
1061 {OID_SKGE_VCT_GET,
1062 0,
1063 0,
1064 0,
1065 SK_PNMI_RO, Vct, 0},
1066 {OID_SKGE_VCT_SET,
1067 0,
1068 0,
1069 0,
1070 SK_PNMI_WO, Vct, 0},
1071 {OID_SKGE_VCT_STATUS,
1072 0,
1073 0,
1074 0,
1075 SK_PNMI_RO, Vct, 0},
1076 {OID_SKGE_BOARDLEVEL,
1077 0,
1078 0,
1079 0,
1080 SK_PNMI_RO, General, 0},
1081};
1082
diff --git a/drivers/net/sk98lin/skgepnmi.c b/drivers/net/sk98lin/skgepnmi.c
new file mode 100644
index 000000000000..58e1a5be913f
--- /dev/null
+++ b/drivers/net/sk98lin/skgepnmi.c
@@ -0,0 +1,8359 @@
1/*****************************************************************************
2 *
3 * Name: skgepnmi.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.111 $
6 * Date: $Date: 2003/09/15 13:35:35 $
7 * Purpose: Private Network Management Interface
8 *
9 ****************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25
26#ifndef _lint
27static const char SysKonnectFileId[] =
28 "@(#) $Id: skgepnmi.c,v 1.111 2003/09/15 13:35:35 tschilli Exp $ (C) Marvell.";
29#endif /* !_lint */
30
31#include "h/skdrv1st.h"
32#include "h/sktypes.h"
33#include "h/xmac_ii.h"
34#include "h/skdebug.h"
35#include "h/skqueue.h"
36#include "h/skgepnmi.h"
37#include "h/skgesirq.h"
38#include "h/skcsum.h"
39#include "h/skvpd.h"
40#include "h/skgehw.h"
41#include "h/skgeinit.h"
42#include "h/skdrv2nd.h"
43#include "h/skgepnm2.h"
44#ifdef SK_POWER_MGMT
45#include "h/skgepmgt.h"
46#endif
47/* defines *******************************************************************/
48
49#ifndef DEBUG
50#define PNMI_STATIC static
51#else /* DEBUG */
52#define PNMI_STATIC
53#endif /* DEBUG */
54
55/*
56 * Public Function prototypes
57 */
58int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level);
59int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
60 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
61int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
62 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
63int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
64 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
65int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
66 unsigned int *pLen, SK_U32 NetIndex);
67int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
68 unsigned int *pLen, SK_U32 NetIndex);
69int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
70 unsigned int *pLen, SK_U32 NetIndex);
71int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
72int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf,
73 unsigned int * pLen, SK_U32 NetIndex);
74
75
76/*
77 * Private Function prototypes
78 */
79
80PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
81 PhysPortIndex);
82PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
83 PhysPortIndex);
84PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac);
85PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
86PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
87 unsigned int PhysPortIndex, unsigned int StatIndex);
88PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
89 unsigned int StatIndex, SK_U32 NetIndex);
90PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
91PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
92 unsigned int *pEntries);
93PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr,
94 unsigned int KeyArrLen, unsigned int *pKeyNo);
95PNMI_STATIC int LookupId(SK_U32 Id);
96PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
97 unsigned int LastMac);
98PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
99 unsigned int *pLen, SK_U32 NetIndex);
100PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id,
101 char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
102PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
103PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
104 unsigned int PortIndex);
105PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
106 unsigned int SensorIndex);
107PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
108PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
109PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
110PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
111PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
112PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
113 unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
114PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
115
116/*
117 * Table to correlate OID with handler function and index to
118 * hardware register stored in StatAddress if applicable.
119 */
120#include "skgemib.c"
121
122/* global variables **********************************************************/
123
124/*
125 * Overflow status register bit table and corresponding counter
126 * dependent on MAC type - the number relates to the size of overflow
127 * mask returned by the pFnMacOverflow function
128 */
129PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = {
130/* Bit0 */ { SK_PNMI_HTX, SK_PNMI_HTX_UNICAST},
131/* Bit1 */ { SK_PNMI_HTX_OCTETHIGH, SK_PNMI_HTX_BROADCAST},
132/* Bit2 */ { SK_PNMI_HTX_OCTETLOW, SK_PNMI_HTX_PMACC},
133/* Bit3 */ { SK_PNMI_HTX_BROADCAST, SK_PNMI_HTX_MULTICAST},
134/* Bit4 */ { SK_PNMI_HTX_MULTICAST, SK_PNMI_HTX_OCTETLOW},
135/* Bit5 */ { SK_PNMI_HTX_UNICAST, SK_PNMI_HTX_OCTETHIGH},
136/* Bit6 */ { SK_PNMI_HTX_LONGFRAMES, SK_PNMI_HTX_64},
137/* Bit7 */ { SK_PNMI_HTX_BURST, SK_PNMI_HTX_127},
138/* Bit8 */ { SK_PNMI_HTX_PMACC, SK_PNMI_HTX_255},
139/* Bit9 */ { SK_PNMI_HTX_MACC, SK_PNMI_HTX_511},
140/* Bit10 */ { SK_PNMI_HTX_SINGLE_COL, SK_PNMI_HTX_1023},
141/* Bit11 */ { SK_PNMI_HTX_MULTI_COL, SK_PNMI_HTX_MAX},
142/* Bit12 */ { SK_PNMI_HTX_EXCESS_COL, SK_PNMI_HTX_LONGFRAMES},
143/* Bit13 */ { SK_PNMI_HTX_LATE_COL, SK_PNMI_HTX_RESERVED},
144/* Bit14 */ { SK_PNMI_HTX_DEFFERAL, SK_PNMI_HTX_COL},
145/* Bit15 */ { SK_PNMI_HTX_EXCESS_DEF, SK_PNMI_HTX_LATE_COL},
146/* Bit16 */ { SK_PNMI_HTX_UNDERRUN, SK_PNMI_HTX_EXCESS_COL},
147/* Bit17 */ { SK_PNMI_HTX_CARRIER, SK_PNMI_HTX_MULTI_COL},
148/* Bit18 */ { SK_PNMI_HTX_UTILUNDER, SK_PNMI_HTX_SINGLE_COL},
149/* Bit19 */ { SK_PNMI_HTX_UTILOVER, SK_PNMI_HTX_UNDERRUN},
150/* Bit20 */ { SK_PNMI_HTX_64, SK_PNMI_HTX_RESERVED},
151/* Bit21 */ { SK_PNMI_HTX_127, SK_PNMI_HTX_RESERVED},
152/* Bit22 */ { SK_PNMI_HTX_255, SK_PNMI_HTX_RESERVED},
153/* Bit23 */ { SK_PNMI_HTX_511, SK_PNMI_HTX_RESERVED},
154/* Bit24 */ { SK_PNMI_HTX_1023, SK_PNMI_HTX_RESERVED},
155/* Bit25 */ { SK_PNMI_HTX_MAX, SK_PNMI_HTX_RESERVED},
156/* Bit26 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
157/* Bit27 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
158/* Bit28 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
159/* Bit29 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
160/* Bit30 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
161/* Bit31 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
162/* Bit32 */ { SK_PNMI_HRX, SK_PNMI_HRX_UNICAST},
163/* Bit33 */ { SK_PNMI_HRX_OCTETHIGH, SK_PNMI_HRX_BROADCAST},
164/* Bit34 */ { SK_PNMI_HRX_OCTETLOW, SK_PNMI_HRX_PMACC},
165/* Bit35 */ { SK_PNMI_HRX_BROADCAST, SK_PNMI_HRX_MULTICAST},
166/* Bit36 */ { SK_PNMI_HRX_MULTICAST, SK_PNMI_HRX_FCS},
167/* Bit37 */ { SK_PNMI_HRX_UNICAST, SK_PNMI_HRX_RESERVED},
168/* Bit38 */ { SK_PNMI_HRX_PMACC, SK_PNMI_HRX_OCTETLOW},
169/* Bit39 */ { SK_PNMI_HRX_MACC, SK_PNMI_HRX_OCTETHIGH},
170/* Bit40 */ { SK_PNMI_HRX_PMACC_ERR, SK_PNMI_HRX_BADOCTETLOW},
171/* Bit41 */ { SK_PNMI_HRX_MACC_UNKWN, SK_PNMI_HRX_BADOCTETHIGH},
172/* Bit42 */ { SK_PNMI_HRX_BURST, SK_PNMI_HRX_UNDERSIZE},
173/* Bit43 */ { SK_PNMI_HRX_MISSED, SK_PNMI_HRX_RUNT},
174/* Bit44 */ { SK_PNMI_HRX_FRAMING, SK_PNMI_HRX_64},
175/* Bit45 */ { SK_PNMI_HRX_OVERFLOW, SK_PNMI_HRX_127},
176/* Bit46 */ { SK_PNMI_HRX_JABBER, SK_PNMI_HRX_255},
177/* Bit47 */ { SK_PNMI_HRX_CARRIER, SK_PNMI_HRX_511},
178/* Bit48 */ { SK_PNMI_HRX_IRLENGTH, SK_PNMI_HRX_1023},
179/* Bit49 */ { SK_PNMI_HRX_SYMBOL, SK_PNMI_HRX_MAX},
180/* Bit50 */ { SK_PNMI_HRX_SHORTS, SK_PNMI_HRX_LONGFRAMES},
181/* Bit51 */ { SK_PNMI_HRX_RUNT, SK_PNMI_HRX_TOO_LONG},
182/* Bit52 */ { SK_PNMI_HRX_TOO_LONG, SK_PNMI_HRX_JABBER},
183/* Bit53 */ { SK_PNMI_HRX_FCS, SK_PNMI_HRX_RESERVED},
184/* Bit54 */ { SK_PNMI_HRX_RESERVED, SK_PNMI_HRX_OVERFLOW},
185/* Bit55 */ { SK_PNMI_HRX_CEXT, SK_PNMI_HRX_RESERVED},
186/* Bit56 */ { SK_PNMI_HRX_UTILUNDER, SK_PNMI_HRX_RESERVED},
187/* Bit57 */ { SK_PNMI_HRX_UTILOVER, SK_PNMI_HRX_RESERVED},
188/* Bit58 */ { SK_PNMI_HRX_64, SK_PNMI_HRX_RESERVED},
189/* Bit59 */ { SK_PNMI_HRX_127, SK_PNMI_HRX_RESERVED},
190/* Bit60 */ { SK_PNMI_HRX_255, SK_PNMI_HRX_RESERVED},
191/* Bit61 */ { SK_PNMI_HRX_511, SK_PNMI_HRX_RESERVED},
192/* Bit62 */ { SK_PNMI_HRX_1023, SK_PNMI_HRX_RESERVED},
193/* Bit63 */ { SK_PNMI_HRX_MAX, SK_PNMI_HRX_RESERVED}
194};
195
196/*
197 * Table for hardware register saving on resets and port switches
198 */
199PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = {
200 /* SK_PNMI_HTX */
201 {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}},
202 /* SK_PNMI_HTX_OCTETHIGH */
203 {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}},
204 /* SK_PNMI_HTX_OCTETLOW */
205 {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}},
206 /* SK_PNMI_HTX_BROADCAST */
207 {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}},
208 /* SK_PNMI_HTX_MULTICAST */
209 {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}},
210 /* SK_PNMI_HTX_UNICAST */
211 {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}},
212 /* SK_PNMI_HTX_BURST */
213 {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}},
214 /* SK_PNMI_HTX_PMACC */
215 {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}},
216 /* SK_PNMI_HTX_MACC */
217 {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
218 /* SK_PNMI_HTX_COL */
219 {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}},
220 /* SK_PNMI_HTX_SINGLE_COL */
221 {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}},
222 /* SK_PNMI_HTX_MULTI_COL */
223 {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}},
224 /* SK_PNMI_HTX_EXCESS_COL */
225 {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}},
226 /* SK_PNMI_HTX_LATE_COL */
227 {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}},
228 /* SK_PNMI_HTX_DEFFERAL */
229 {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}},
230 /* SK_PNMI_HTX_EXCESS_DEF */
231 {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}},
232 /* SK_PNMI_HTX_UNDERRUN */
233 {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}},
234 /* SK_PNMI_HTX_CARRIER */
235 {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}},
236 /* SK_PNMI_HTX_UTILUNDER */
237 {{0, SK_FALSE}, {0, SK_FALSE}},
238 /* SK_PNMI_HTX_UTILOVER */
239 {{0, SK_FALSE}, {0, SK_FALSE}},
240 /* SK_PNMI_HTX_64 */
241 {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}},
242 /* SK_PNMI_HTX_127 */
243 {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}},
244 /* SK_PNMI_HTX_255 */
245 {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}},
246 /* SK_PNMI_HTX_511 */
247 {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}},
248 /* SK_PNMI_HTX_1023 */
249 {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}},
250 /* SK_PNMI_HTX_MAX */
251 {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}},
252 /* SK_PNMI_HTX_LONGFRAMES */
253 {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}},
254 /* SK_PNMI_HTX_SYNC */
255 {{0, SK_FALSE}, {0, SK_FALSE}},
256 /* SK_PNMI_HTX_SYNC_OCTET */
257 {{0, SK_FALSE}, {0, SK_FALSE}},
258 /* SK_PNMI_HTX_RESERVED */
259 {{0, SK_FALSE}, {0, SK_FALSE}},
260 /* SK_PNMI_HRX */
261 {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}},
262 /* SK_PNMI_HRX_OCTETHIGH */
263 {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}},
264 /* SK_PNMI_HRX_OCTETLOW */
265 {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}},
266 /* SK_PNMI_HRX_BADOCTETHIGH */
267 {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}},
268 /* SK_PNMI_HRX_BADOCTETLOW */
269 {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}},
270 /* SK_PNMI_HRX_BROADCAST */
271 {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}},
272 /* SK_PNMI_HRX_MULTICAST */
273 {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}},
274 /* SK_PNMI_HRX_UNICAST */
275 {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}},
276 /* SK_PNMI_HRX_PMACC */
277 {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}},
278 /* SK_PNMI_HRX_MACC */
279 {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
280 /* SK_PNMI_HRX_PMACC_ERR */
281 {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}},
282 /* SK_PNMI_HRX_MACC_UNKWN */
283 {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}},
284 /* SK_PNMI_HRX_BURST */
285 {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}},
286 /* SK_PNMI_HRX_MISSED */
287 {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}},
288 /* SK_PNMI_HRX_FRAMING */
289 {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}},
290 /* SK_PNMI_HRX_UNDERSIZE */
291 {{0, SK_FALSE}, {GM_RXF_SHT, SK_TRUE}},
292 /* SK_PNMI_HRX_OVERFLOW */
293 {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}},
294 /* SK_PNMI_HRX_JABBER */
295 {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}},
296 /* SK_PNMI_HRX_CARRIER */
297 {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}},
298 /* SK_PNMI_HRX_IRLENGTH */
299 {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}},
300 /* SK_PNMI_HRX_SYMBOL */
301 {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}},
302 /* SK_PNMI_HRX_SHORTS */
303 {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}},
304 /* SK_PNMI_HRX_RUNT */
305 {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}},
306 /* SK_PNMI_HRX_TOO_LONG */
307 {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}},
308 /* SK_PNMI_HRX_FCS */
309 {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}},
310 /* SK_PNMI_HRX_CEXT */
311 {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}},
312 /* SK_PNMI_HRX_UTILUNDER */
313 {{0, SK_FALSE}, {0, SK_FALSE}},
314 /* SK_PNMI_HRX_UTILOVER */
315 {{0, SK_FALSE}, {0, SK_FALSE}},
316 /* SK_PNMI_HRX_64 */
317 {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}},
318 /* SK_PNMI_HRX_127 */
319 {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}},
320 /* SK_PNMI_HRX_255 */
321 {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}},
322 /* SK_PNMI_HRX_511 */
323 {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}},
324 /* SK_PNMI_HRX_1023 */
325 {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}},
326 /* SK_PNMI_HRX_MAX */
327 {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}},
328 /* SK_PNMI_HRX_LONGFRAMES */
329 {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}},
330 /* SK_PNMI_HRX_RESERVED */
331 {{0, SK_FALSE}, {0, SK_FALSE}}
332};
333
334
335/*****************************************************************************
336 *
337 * Public functions
338 *
339 */
340
341/*****************************************************************************
342 *
343 * SkPnmiInit - Init function of PNMI
344 *
345 * Description:
346 * SK_INIT_DATA: Initialises the data structures
347 * SK_INIT_IO: Resets the XMAC statistics, determines the device and
348 * connector type.
349 * SK_INIT_RUN: Starts a timer event for port switch per hour
350 * calculation.
351 *
352 * Returns:
353 * Always 0
354 */
355int SkPnmiInit(
356SK_AC *pAC, /* Pointer to adapter context */
357SK_IOC IoC, /* IO context handle */
358int Level) /* Initialization level */
359{
360 unsigned int PortMax; /* Number of ports */
361 unsigned int PortIndex; /* Current port index in loop */
362 SK_U16 Val16; /* Multiple purpose 16 bit variable */
363 SK_U8 Val8; /* Mulitple purpose 8 bit variable */
364 SK_EVPARA EventParam; /* Event struct for timer event */
365 SK_PNMI_VCT *pVctBackupData;
366
367
368 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
369 ("PNMI: SkPnmiInit: Called, level=%d\n", Level));
370
371 switch (Level) {
372
373 case SK_INIT_DATA:
374 SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
375 pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
376 pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
377 pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
378 for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
379
380 pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
381 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
382 }
383
384#ifdef SK_PNMI_CHECK
385 if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) {
386
387 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG);
388
389 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
390 ("CounterOffset struct size (%d) differs from"
391 "SK_PNMI_MAX_IDX (%d)\n",
392 SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
393 }
394
395 if (SK_PNMI_MAX_IDX !=
396 (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) {
397
398 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG);
399
400 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
401 ("StatAddr table size (%d) differs from "
402 "SK_PNMI_MAX_IDX (%d)\n",
403 (sizeof(StatAddr) /
404 (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)),
405 SK_PNMI_MAX_IDX));
406 }
407#endif /* SK_PNMI_CHECK */
408 break;
409
410 case SK_INIT_IO:
411 /*
412 * Reset MAC counters
413 */
414 PortMax = pAC->GIni.GIMacsFound;
415
416 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
417
418 pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
419 }
420
421 /* Initialize DSP variables for Vct() to 0xff => Never written! */
422 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
423 pAC->GIni.GP[PortIndex].PCableLen = 0xff;
424 pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
425 pVctBackupData->PCableLen = 0xff;
426 }
427
428 /*
429 * Get pci bus speed
430 */
431 SK_IN16(IoC, B0_CTST, &Val16);
432 if ((Val16 & CS_BUS_CLOCK) == 0) {
433
434 pAC->Pnmi.PciBusSpeed = 33;
435 }
436 else {
437 pAC->Pnmi.PciBusSpeed = 66;
438 }
439
440 /*
441 * Get pci bus width
442 */
443 SK_IN16(IoC, B0_CTST, &Val16);
444 if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
445
446 pAC->Pnmi.PciBusWidth = 32;
447 }
448 else {
449 pAC->Pnmi.PciBusWidth = 64;
450 }
451
452 /*
453 * Get chipset
454 */
455 switch (pAC->GIni.GIChipId) {
456 case CHIP_ID_GENESIS:
457 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
458 break;
459
460 case CHIP_ID_YUKON:
461 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
462 break;
463
464 default:
465 break;
466 }
467
468 /*
469 * Get PMD and DeviceType
470 */
471 SK_IN8(IoC, B2_PMD_TYP, &Val8);
472 switch (Val8) {
473 case 'S':
474 pAC->Pnmi.PMD = 3;
475 if (pAC->GIni.GIMacsFound > 1) {
476
477 pAC->Pnmi.DeviceType = 0x00020002;
478 }
479 else {
480 pAC->Pnmi.DeviceType = 0x00020001;
481 }
482 break;
483
484 case 'L':
485 pAC->Pnmi.PMD = 2;
486 if (pAC->GIni.GIMacsFound > 1) {
487
488 pAC->Pnmi.DeviceType = 0x00020004;
489 }
490 else {
491 pAC->Pnmi.DeviceType = 0x00020003;
492 }
493 break;
494
495 case 'C':
496 pAC->Pnmi.PMD = 4;
497 if (pAC->GIni.GIMacsFound > 1) {
498
499 pAC->Pnmi.DeviceType = 0x00020006;
500 }
501 else {
502 pAC->Pnmi.DeviceType = 0x00020005;
503 }
504 break;
505
506 case 'T':
507 pAC->Pnmi.PMD = 5;
508 if (pAC->GIni.GIMacsFound > 1) {
509
510 pAC->Pnmi.DeviceType = 0x00020008;
511 }
512 else {
513 pAC->Pnmi.DeviceType = 0x00020007;
514 }
515 break;
516
517 default :
518 pAC->Pnmi.PMD = 1;
519 pAC->Pnmi.DeviceType = 0;
520 break;
521 }
522
523 /*
524 * Get connector
525 */
526 SK_IN8(IoC, B2_CONN_TYP, &Val8);
527 switch (Val8) {
528 case 'C':
529 pAC->Pnmi.Connector = 2;
530 break;
531
532 case 'D':
533 pAC->Pnmi.Connector = 3;
534 break;
535
536 case 'F':
537 pAC->Pnmi.Connector = 4;
538 break;
539
540 case 'J':
541 pAC->Pnmi.Connector = 5;
542 break;
543
544 case 'V':
545 pAC->Pnmi.Connector = 6;
546 break;
547
548 default:
549 pAC->Pnmi.Connector = 1;
550 break;
551 }
552 break;
553
554 case SK_INIT_RUN:
555 /*
556 * Start timer for RLMT change counter
557 */
558 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
559 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
560 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
561 EventParam);
562 break;
563
564 default:
565 break; /* Nothing todo */
566 }
567
568 return (0);
569}
570
571/*****************************************************************************
572 *
573 * SkPnmiGetVar - Retrieves the value of a single OID
574 *
575 * Description:
576 * Calls a general sub-function for all this stuff. If the instance
577 * -1 is passed, the values of all instances are returned in an
578 * array of values.
579 *
580 * Returns:
581 * SK_PNMI_ERR_OK The request was successfully performed
582 * SK_PNMI_ERR_GENERAL A general severe internal error occured
583 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
584 * the data.
585 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
586 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
587 * exist (e.g. port instance 3 on a two port
588 * adapter.
589 */
590int SkPnmiGetVar(
591SK_AC *pAC, /* Pointer to adapter context */
592SK_IOC IoC, /* IO context handle */
593SK_U32 Id, /* Object ID that is to be processed */
594void *pBuf, /* Buffer to which the management data will be copied */
595unsigned int *pLen, /* On call: buffer length. On return: used buffer */
596SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
597SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
598{
599 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
600 ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
601 Id, *pLen, Instance, NetIndex));
602
603 return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
604 Instance, NetIndex));
605}
606
607/*****************************************************************************
608 *
609 * SkPnmiPreSetVar - Presets the value of a single OID
610 *
611 * Description:
612 * Calls a general sub-function for all this stuff. The preset does
613 * the same as a set, but returns just before finally setting the
614 * new value. This is usefull to check if a set might be successfull.
615 * If the instance -1 is passed, an array of values is supposed and
616 * all instances of the OID will be set.
617 *
618 * Returns:
619 * SK_PNMI_ERR_OK The request was successfully performed.
620 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
621 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
622 * the correct data (e.g. a 32bit value is
623 * needed, but a 16 bit value was passed).
624 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
625 * value range.
626 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
627 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
628 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
629 * exist (e.g. port instance 3 on a two port
630 * adapter.
631 */
632int SkPnmiPreSetVar(
633SK_AC *pAC, /* Pointer to adapter context */
634SK_IOC IoC, /* IO context handle */
635SK_U32 Id, /* Object ID that is to be processed */
636void *pBuf, /* Buffer to which the management data will be copied */
637unsigned int *pLen, /* Total length of management data */
638SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
639SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
640{
641 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
642 ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
643 Id, *pLen, Instance, NetIndex));
644
645
646 return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
647 Instance, NetIndex));
648}
649
650/*****************************************************************************
651 *
652 * SkPnmiSetVar - Sets the value of a single OID
653 *
654 * Description:
655 * Calls a general sub-function for all this stuff. The preset does
656 * the same as a set, but returns just before finally setting the
657 * new value. This is usefull to check if a set might be successfull.
658 * If the instance -1 is passed, an array of values is supposed and
659 * all instances of the OID will be set.
660 *
661 * Returns:
662 * SK_PNMI_ERR_OK The request was successfully performed.
663 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
664 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
665 * the correct data (e.g. a 32bit value is
666 * needed, but a 16 bit value was passed).
667 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
668 * value range.
669 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
670 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
671 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
672 * exist (e.g. port instance 3 on a two port
673 * adapter.
674 */
675int SkPnmiSetVar(
676SK_AC *pAC, /* Pointer to adapter context */
677SK_IOC IoC, /* IO context handle */
678SK_U32 Id, /* Object ID that is to be processed */
679void *pBuf, /* Buffer to which the management data will be copied */
680unsigned int *pLen, /* Total length of management data */
681SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
682SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
683{
684 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
685 ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
686 Id, *pLen, Instance, NetIndex));
687
688 return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
689 Instance, NetIndex));
690}
691
692/*****************************************************************************
693 *
694 * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA
695 *
696 * Description:
697 * Runs through the IdTable, queries the single OIDs and stores the
698 * returned data into the management database structure
699 * SK_PNMI_STRUCT_DATA. The offset of the OID in the structure
700 * is stored in the IdTable. The return value of the function will also
701 * be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
702 * minimum size of SK_PNMI_MIN_STRUCT_SIZE.
703 *
704 * Returns:
705 * SK_PNMI_ERR_OK The request was successfully performed
706 * SK_PNMI_ERR_GENERAL A general severe internal error occured
707 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
708 * the data.
709 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
710 */
711int SkPnmiGetStruct(
712SK_AC *pAC, /* Pointer to adapter context */
713SK_IOC IoC, /* IO context handle */
714void *pBuf, /* Buffer to which the management data will be copied. */
715unsigned int *pLen, /* Length of buffer */
716SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
717{
718 int Ret;
719 unsigned int TableIndex;
720 unsigned int DstOffset;
721 unsigned int InstanceNo;
722 unsigned int InstanceCnt;
723 SK_U32 Instance;
724 unsigned int TmpLen;
725 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
726
727
728 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
729 ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
730 *pLen, NetIndex));
731
732 if (*pLen < SK_PNMI_STRUCT_SIZE) {
733
734 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
735
736 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
737 (SK_U32)(-1));
738 }
739
740 *pLen = SK_PNMI_STRUCT_SIZE;
741 return (SK_PNMI_ERR_TOO_SHORT);
742 }
743
744 /*
745 * Check NetIndex
746 */
747 if (NetIndex >= pAC->Rlmt.NumNets) {
748 return (SK_PNMI_ERR_UNKNOWN_NET);
749 }
750
751 /* Update statistic */
752 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
753
754 if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
755 SK_PNMI_ERR_OK) {
756
757 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
758 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
759 return (Ret);
760 }
761
762 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
763
764 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
765 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
766 return (Ret);
767 }
768
769 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
770
771 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
772 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
773 return (Ret);
774 }
775
776 /*
777 * Increment semaphores to indicate that an update was
778 * already done
779 */
780 pAC->Pnmi.MacUpdatedFlag ++;
781 pAC->Pnmi.RlmtUpdatedFlag ++;
782 pAC->Pnmi.SirqUpdatedFlag ++;
783
784 /* Get vpd keys for instance calculation */
785 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
786 if (Ret != SK_PNMI_ERR_OK) {
787
788 pAC->Pnmi.MacUpdatedFlag --;
789 pAC->Pnmi.RlmtUpdatedFlag --;
790 pAC->Pnmi.SirqUpdatedFlag --;
791
792 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
793 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
794 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
795 return (SK_PNMI_ERR_GENERAL);
796 }
797
798 /* Retrieve values */
799 SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
800 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
801
802 InstanceNo = IdTable[TableIndex].InstanceNo;
803 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
804 InstanceCnt ++) {
805
806 DstOffset = IdTable[TableIndex].Offset +
807 (InstanceCnt - 1) *
808 IdTable[TableIndex].StructSize;
809
810 /*
811 * For the VPD the instance is not an index number
812 * but the key itself. Determin with the instance
813 * counter the VPD key to be used.
814 */
815 if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
816 IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
817 IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
818 IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
819
820 SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
821 }
822 else {
823 Instance = (SK_U32)InstanceCnt;
824 }
825
826 TmpLen = *pLen - DstOffset;
827 Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
828 IdTable[TableIndex].Id, (char *)pBuf +
829 DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
830
831 /*
832 * An unknown instance error means that we reached
833 * the last instance of that variable. Proceed with
834 * the next OID in the table and ignore the return
835 * code.
836 */
837 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
838
839 break;
840 }
841
842 if (Ret != SK_PNMI_ERR_OK) {
843
844 pAC->Pnmi.MacUpdatedFlag --;
845 pAC->Pnmi.RlmtUpdatedFlag --;
846 pAC->Pnmi.SirqUpdatedFlag --;
847
848 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
849 SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
850 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
851 return (Ret);
852 }
853 }
854 }
855
856 pAC->Pnmi.MacUpdatedFlag --;
857 pAC->Pnmi.RlmtUpdatedFlag --;
858 pAC->Pnmi.SirqUpdatedFlag --;
859
860 *pLen = SK_PNMI_STRUCT_SIZE;
861 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
862 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
863 return (SK_PNMI_ERR_OK);
864}
865
866/*****************************************************************************
867 *
868 * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
869 *
870 * Description:
871 * Calls a general sub-function for all this set stuff. The preset does
872 * the same as a set, but returns just before finally setting the
873 * new value. This is usefull to check if a set might be successfull.
874 * The sub-function runs through the IdTable, checks which OIDs are able
875 * to set, and calls the handler function of the OID to perform the
876 * preset. The return value of the function will also be stored in
877 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
878 * SK_PNMI_MIN_STRUCT_SIZE.
879 *
880 * Returns:
881 * SK_PNMI_ERR_OK The request was successfully performed.
882 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
883 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
884 * the correct data (e.g. a 32bit value is
885 * needed, but a 16 bit value was passed).
886 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
887 * value range.
888 */
889int SkPnmiPreSetStruct(
890SK_AC *pAC, /* Pointer to adapter context */
891SK_IOC IoC, /* IO context handle */
892void *pBuf, /* Buffer which contains the data to be set */
893unsigned int *pLen, /* Length of buffer */
894SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
895{
896 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
897 ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
898 *pLen, NetIndex));
899
900 return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf,
901 pLen, NetIndex));
902}
903
904/*****************************************************************************
905 *
906 * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA
907 *
908 * Description:
909 * Calls a general sub-function for all this set stuff. The return value
910 * of the function will also be stored in SK_PNMI_STRUCT_DATA if the
911 * passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE.
912 * The sub-function runs through the IdTable, checks which OIDs are able
913 * to set, and calls the handler function of the OID to perform the
914 * set. The return value of the function will also be stored in
915 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
916 * SK_PNMI_MIN_STRUCT_SIZE.
917 *
918 * Returns:
919 * SK_PNMI_ERR_OK The request was successfully performed.
920 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
921 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
922 * the correct data (e.g. a 32bit value is
923 * needed, but a 16 bit value was passed).
924 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
925 * value range.
926 */
927int SkPnmiSetStruct(
928SK_AC *pAC, /* Pointer to adapter context */
929SK_IOC IoC, /* IO context handle */
930void *pBuf, /* Buffer which contains the data to be set */
931unsigned int *pLen, /* Length of buffer */
932SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
933{
934 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
935 ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
936 *pLen, NetIndex));
937
938 return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf,
939 pLen, NetIndex));
940}
941
942/*****************************************************************************
943 *
944 * SkPnmiEvent - Event handler
945 *
946 * Description:
947 * Handles the following events:
948 * SK_PNMI_EVT_SIRQ_OVERFLOW When a hardware counter overflows an
949 * interrupt will be generated which is
950 * first handled by SIRQ which generates a
951 * this event. The event increments the
952 * upper 32 bit of the 64 bit counter.
953 * SK_PNMI_EVT_SEN_XXX The event is generated by the I2C module
954 * when a sensor reports a warning or
955 * error. The event will store a trap
956 * message in the trap buffer.
957 * SK_PNMI_EVT_CHG_EST_TIMER The timer event was initiated by this
958 * module and is used to calculate the
959 * port switches per hour.
960 * SK_PNMI_EVT_CLEAR_COUNTER The event clears all counters and
961 * timestamps.
962 * SK_PNMI_EVT_XMAC_RESET The event is generated by the driver
963 * before a hard reset of the XMAC is
964 * performed. All counters will be saved
965 * and added to the hardware counter
966 * values after reset to grant continuous
967 * counter values.
968 * SK_PNMI_EVT_RLMT_PORT_UP Generated by RLMT to notify that a port
969 * went logically up. A trap message will
970 * be stored to the trap buffer.
971 * SK_PNMI_EVT_RLMT_PORT_DOWN Generated by RLMT to notify that a port
972 * went logically down. A trap message will
973 * be stored to the trap buffer.
974 * SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
975 * spanning tree root bridges were
976 * detected. A trap message will be stored
977 * to the trap buffer.
978 * SK_PNMI_EVT_RLMT_ACTIVE_DOWN Notifies PNMI that an active port went
979 * down. PNMI will not further add the
980 * statistic values to the virtual port.
981 * SK_PNMI_EVT_RLMT_ACTIVE_UP Notifies PNMI that a port went up and
982 * is now an active port. PNMI will now
983 * add the statistic data of this port to
984 * the virtual port.
985 * SK_PNMI_EVT_RLMT_SET_NETS Notifies PNMI about the net mode. The first parameter
986 * contains the number of nets. 1 means single net, 2 means
987 * dual net. The second parameter is -1
988 *
989 * Returns:
990 * Always 0
991 */
992int SkPnmiEvent(
993SK_AC *pAC, /* Pointer to adapter context */
994SK_IOC IoC, /* IO context handle */
995SK_U32 Event, /* Event-Id */
996SK_EVPARA Param) /* Event dependent parameter */
997{
998 unsigned int PhysPortIndex;
999 unsigned int MaxNetNumber;
1000 int CounterIndex;
1001 int Ret;
1002 SK_U16 MacStatus;
1003 SK_U64 OverflowStatus;
1004 SK_U64 Mask;
1005 int MacType;
1006 SK_U64 Value;
1007 SK_U32 Val32;
1008 SK_U16 Register;
1009 SK_EVPARA EventParam;
1010 SK_U64 NewestValue;
1011 SK_U64 OldestValue;
1012 SK_U64 Delta;
1013 SK_PNMI_ESTIMATE *pEst;
1014 SK_U32 NetIndex;
1015 SK_GEPORT *pPrt;
1016 SK_PNMI_VCT *pVctBackupData;
1017 SK_U32 RetCode;
1018 int i;
1019 SK_U32 CableLength;
1020
1021
1022#ifdef DEBUG
1023 if (Event != SK_PNMI_EVT_XMAC_RESET) {
1024
1025 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1026 ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n",
1027 (unsigned int)Event, (unsigned int)Param.Para64));
1028 }
1029#endif /* DEBUG */
1030 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call");
1031
1032 MacType = pAC->GIni.GIMacType;
1033
1034 switch (Event) {
1035
1036 case SK_PNMI_EVT_SIRQ_OVERFLOW:
1037 PhysPortIndex = (int)Param.Para32[0];
1038 MacStatus = (SK_U16)Param.Para32[1];
1039#ifdef DEBUG
1040 if (PhysPortIndex >= SK_MAX_MACS) {
1041
1042 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1043 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter"
1044 " wrong, PhysPortIndex=0x%x\n",
1045 PhysPortIndex));
1046 return (0);
1047 }
1048#endif /* DEBUG */
1049 OverflowStatus = 0;
1050
1051 /*
1052 * Check which source caused an overflow interrupt.
1053 */
1054 if ((pAC->GIni.GIFunc.pFnMacOverflow(pAC, IoC, PhysPortIndex,
1055 MacStatus, &OverflowStatus) != 0) ||
1056 (OverflowStatus == 0)) {
1057
1058 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1059 return (0);
1060 }
1061
1062 /*
1063 * Check the overflow status register and increment
1064 * the upper dword of corresponding counter.
1065 */
1066 for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8;
1067 CounterIndex ++) {
1068
1069 Mask = (SK_U64)1 << CounterIndex;
1070 if ((OverflowStatus & Mask) == 0) {
1071
1072 continue;
1073 }
1074
1075 switch (StatOvrflwBit[CounterIndex][MacType]) {
1076
1077 case SK_PNMI_HTX_UTILUNDER:
1078 case SK_PNMI_HTX_UTILOVER:
1079 if (MacType == SK_MAC_XMAC) {
1080 XM_IN16(IoC, PhysPortIndex, XM_TX_CMD, &Register);
1081 Register |= XM_TX_SAM_LINE;
1082 XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD, Register);
1083 }
1084 break;
1085
1086 case SK_PNMI_HRX_UTILUNDER:
1087 case SK_PNMI_HRX_UTILOVER:
1088 if (MacType == SK_MAC_XMAC) {
1089 XM_IN16(IoC, PhysPortIndex, XM_RX_CMD, &Register);
1090 Register |= XM_RX_SAM_LINE;
1091 XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD, Register);
1092 }
1093 break;
1094
1095 case SK_PNMI_HTX_OCTETHIGH:
1096 case SK_PNMI_HTX_OCTETLOW:
1097 case SK_PNMI_HTX_RESERVED:
1098 case SK_PNMI_HRX_OCTETHIGH:
1099 case SK_PNMI_HRX_OCTETLOW:
1100 case SK_PNMI_HRX_IRLENGTH:
1101 case SK_PNMI_HRX_RESERVED:
1102
1103 /*
1104 * the following counters aren't be handled (id > 63)
1105 */
1106 case SK_PNMI_HTX_SYNC:
1107 case SK_PNMI_HTX_SYNC_OCTET:
1108 break;
1109
1110 case SK_PNMI_HRX_LONGFRAMES:
1111 if (MacType == SK_MAC_GMAC) {
1112 pAC->Pnmi.Port[PhysPortIndex].
1113 CounterHigh[CounterIndex] ++;
1114 }
1115 break;
1116
1117 default:
1118 pAC->Pnmi.Port[PhysPortIndex].
1119 CounterHigh[CounterIndex] ++;
1120 }
1121 }
1122 break;
1123
1124 case SK_PNMI_EVT_SEN_WAR_LOW:
1125#ifdef DEBUG
1126 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1127
1128 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1129 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n",
1130 (unsigned int)Param.Para64));
1131 return (0);
1132 }
1133#endif /* DEBUG */
1134
1135 /*
1136 * Store a trap message in the trap buffer and generate
1137 * an event for user space applications with the
1138 * SK_DRIVER_SENDEVENT macro.
1139 */
1140 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW,
1141 (unsigned int)Param.Para64);
1142 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1143 break;
1144
1145 case SK_PNMI_EVT_SEN_WAR_UPP:
1146#ifdef DEBUG
1147 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1148
1149 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1150 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n",
1151 (unsigned int)Param.Para64));
1152 return (0);
1153 }
1154#endif /* DEBUG */
1155
1156 /*
1157 * Store a trap message in the trap buffer and generate
1158 * an event for user space applications with the
1159 * SK_DRIVER_SENDEVENT macro.
1160 */
1161 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP,
1162 (unsigned int)Param.Para64);
1163 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1164 break;
1165
1166 case SK_PNMI_EVT_SEN_ERR_LOW:
1167#ifdef DEBUG
1168 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1169
1170 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1171 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n",
1172 (unsigned int)Param.Para64));
1173 return (0);
1174 }
1175#endif /* DEBUG */
1176
1177 /*
1178 * Store a trap message in the trap buffer and generate
1179 * an event for user space applications with the
1180 * SK_DRIVER_SENDEVENT macro.
1181 */
1182 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW,
1183 (unsigned int)Param.Para64);
1184 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1185 break;
1186
1187 case SK_PNMI_EVT_SEN_ERR_UPP:
1188#ifdef DEBUG
1189 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1190
1191 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1192 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
1193 (unsigned int)Param.Para64));
1194 return (0);
1195 }
1196#endif /* DEBUG */
1197
1198 /*
1199 * Store a trap message in the trap buffer and generate
1200 * an event for user space applications with the
1201 * SK_DRIVER_SENDEVENT macro.
1202 */
1203 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP,
1204 (unsigned int)Param.Para64);
1205 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1206 break;
1207
1208 case SK_PNMI_EVT_CHG_EST_TIMER:
1209 /*
1210 * Calculate port switch average on a per hour basis
1211 * Time interval for check : 28125 ms
1212 * Number of values for average : 8
1213 *
1214 * Be careful in changing these values, on change check
1215 * - typedef of SK_PNMI_ESTIMATE (Size of EstValue
1216 * array one less than value number)
1217 * - Timer initialization SkTimerStart() in SkPnmiInit
1218 * - Delta value below must be multiplicated with
1219 * power of 2
1220 *
1221 */
1222 pEst = &pAC->Pnmi.RlmtChangeEstimate;
1223 CounterIndex = pEst->EstValueIndex + 1;
1224 if (CounterIndex == 7) {
1225
1226 CounterIndex = 0;
1227 }
1228 pEst->EstValueIndex = CounterIndex;
1229
1230 NewestValue = pAC->Pnmi.RlmtChangeCts;
1231 OldestValue = pEst->EstValue[CounterIndex];
1232 pEst->EstValue[CounterIndex] = NewestValue;
1233
1234 /*
1235 * Calculate average. Delta stores the number of
1236 * port switches per 28125 * 8 = 225000 ms
1237 */
1238 if (NewestValue >= OldestValue) {
1239
1240 Delta = NewestValue - OldestValue;
1241 }
1242 else {
1243 /* Overflow situation */
1244 Delta = (SK_U64)(0 - OldestValue) + NewestValue;
1245 }
1246
1247 /*
1248 * Extrapolate delta to port switches per hour.
1249 * Estimate = Delta * (3600000 / 225000)
1250 * = Delta * 16
1251 * = Delta << 4
1252 */
1253 pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4;
1254
1255 /*
1256 * Check if threshold is exceeded. If the threshold is
1257 * permanently exceeded every 28125 ms an event will be
1258 * generated to remind the user of this condition.
1259 */
1260 if ((pAC->Pnmi.RlmtChangeThreshold != 0) &&
1261 (pAC->Pnmi.RlmtChangeEstimate.Estimate >=
1262 pAC->Pnmi.RlmtChangeThreshold)) {
1263
1264 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES);
1265 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1266 }
1267
1268 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
1269 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
1270 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
1271 EventParam);
1272 break;
1273
1274 case SK_PNMI_EVT_CLEAR_COUNTER:
1275 /*
1276 * Param.Para32[0] contains the NetIndex (0 ..1).
1277 * Param.Para32[1] is reserved, contains -1.
1278 */
1279 NetIndex = (SK_U32)Param.Para32[0];
1280
1281#ifdef DEBUG
1282 if (NetIndex >= pAC->Rlmt.NumNets) {
1283
1284 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1285 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
1286 NetIndex));
1287
1288 return (0);
1289 }
1290#endif /* DEBUG */
1291
1292 /*
1293 * Set all counters and timestamps to zero.
1294 * The according NetIndex is required as a
1295 * parameter of the event.
1296 */
1297 ResetCounter(pAC, IoC, NetIndex);
1298 break;
1299
1300 case SK_PNMI_EVT_XMAC_RESET:
1301 /*
1302 * To grant continuous counter values store the current
1303 * XMAC statistic values to the entries 1..n of the
1304 * CounterOffset array. XMAC Errata #2
1305 */
1306#ifdef DEBUG
1307 if ((unsigned int)Param.Para64 >= SK_MAX_MACS) {
1308
1309 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1310 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n",
1311 (unsigned int)Param.Para64));
1312 return (0);
1313 }
1314#endif
1315 PhysPortIndex = (unsigned int)Param.Para64;
1316
1317 /*
1318 * Update XMAC statistic to get fresh values
1319 */
1320 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
1321 if (Ret != SK_PNMI_ERR_OK) {
1322
1323 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1324 return (0);
1325 }
1326 /*
1327 * Increment semaphore to indicate that an update was
1328 * already done
1329 */
1330 pAC->Pnmi.MacUpdatedFlag ++;
1331
1332 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1333 CounterIndex ++) {
1334
1335 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1336
1337 continue;
1338 }
1339
1340 pAC->Pnmi.Port[PhysPortIndex].CounterOffset[CounterIndex] =
1341 GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1342
1343 pAC->Pnmi.Port[PhysPortIndex].CounterHigh[CounterIndex] = 0;
1344 }
1345
1346 pAC->Pnmi.MacUpdatedFlag --;
1347 break;
1348
1349 case SK_PNMI_EVT_RLMT_PORT_UP:
1350 PhysPortIndex = (unsigned int)Param.Para32[0];
1351#ifdef DEBUG
1352 if (PhysPortIndex >= SK_MAX_MACS) {
1353
1354 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1355 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter"
1356 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1357
1358 return (0);
1359 }
1360#endif /* DEBUG */
1361
1362 /*
1363 * Store a trap message in the trap buffer and generate an event for
1364 * user space applications with the SK_DRIVER_SENDEVENT macro.
1365 */
1366 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
1367 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1368
1369 /* Bugfix for XMAC errata (#10620)*/
1370 if (MacType == SK_MAC_XMAC) {
1371 /* Add incremental difference to offset (#10620)*/
1372 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1373 XM_RXE_SHT_ERR, &Val32);
1374
1375 Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1376 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1377 pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
1378 Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
1379 }
1380
1381 /* Tell VctStatus() that a link was up meanwhile. */
1382 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK;
1383 break;
1384
1385 case SK_PNMI_EVT_RLMT_PORT_DOWN:
1386 PhysPortIndex = (unsigned int)Param.Para32[0];
1387
1388#ifdef DEBUG
1389 if (PhysPortIndex >= SK_MAX_MACS) {
1390
1391 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1392 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter"
1393 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1394
1395 return (0);
1396 }
1397#endif /* DEBUG */
1398
1399 /*
1400 * Store a trap message in the trap buffer and generate an event for
1401 * user space applications with the SK_DRIVER_SENDEVENT macro.
1402 */
1403 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
1404 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1405
1406 /* Bugfix #10620 - get zero level for incremental difference */
1407 if (MacType == SK_MAC_XMAC) {
1408
1409 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1410 XM_RXE_SHT_ERR, &Val32);
1411
1412 pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark =
1413 (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1414 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1415 }
1416 break;
1417
1418 case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
1419 PhysPortIndex = (unsigned int)Param.Para32[0];
1420 NetIndex = (SK_U32)Param.Para32[1];
1421
1422#ifdef DEBUG
1423 if (PhysPortIndex >= SK_MAX_MACS) {
1424
1425 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1426 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
1427 PhysPortIndex));
1428 }
1429
1430 if (NetIndex >= pAC->Rlmt.NumNets) {
1431
1432 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1433 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
1434 NetIndex));
1435 }
1436#endif /* DEBUG */
1437
1438 /*
1439 * For now, ignore event if NetIndex != 0.
1440 */
1441 if (Param.Para32[1] != 0) {
1442
1443 return (0);
1444 }
1445
1446 /*
1447 * Nothing to do if port is already inactive
1448 */
1449 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1450
1451 return (0);
1452 }
1453
1454 /*
1455 * Update statistic counters to calculate new offset for the virtual
1456 * port and increment semaphore to indicate that an update was already
1457 * done.
1458 */
1459 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1460 SK_PNMI_ERR_OK) {
1461
1462 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1463 return (0);
1464 }
1465 pAC->Pnmi.MacUpdatedFlag ++;
1466
1467 /*
1468 * Calculate new counter offset for virtual port to grant continous
1469 * counting on port switches. The virtual port consists of all currently
1470 * active ports. The port down event indicates that a port is removed
1471 * from the virtual port. Therefore add the counter value of the removed
1472 * port to the CounterOffset for the virtual port to grant the same
1473 * counter value.
1474 */
1475 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1476 CounterIndex ++) {
1477
1478 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1479
1480 continue;
1481 }
1482
1483 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1484
1485 pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
1486 }
1487
1488 /*
1489 * Set port to inactive
1490 */
1491 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
1492
1493 pAC->Pnmi.MacUpdatedFlag --;
1494 break;
1495
1496 case SK_PNMI_EVT_RLMT_ACTIVE_UP:
1497 PhysPortIndex = (unsigned int)Param.Para32[0];
1498 NetIndex = (SK_U32)Param.Para32[1];
1499
1500#ifdef DEBUG
1501 if (PhysPortIndex >= SK_MAX_MACS) {
1502
1503 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1504 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
1505 PhysPortIndex));
1506 }
1507
1508 if (NetIndex >= pAC->Rlmt.NumNets) {
1509
1510 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1511 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
1512 NetIndex));
1513 }
1514#endif /* DEBUG */
1515
1516 /*
1517 * For now, ignore event if NetIndex != 0.
1518 */
1519 if (Param.Para32[1] != 0) {
1520
1521 return (0);
1522 }
1523
1524 /*
1525 * Nothing to do if port is already active
1526 */
1527 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1528
1529 return (0);
1530 }
1531
1532 /*
1533 * Statistic maintenance
1534 */
1535 pAC->Pnmi.RlmtChangeCts ++;
1536 pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
1537
1538 /*
1539 * Store a trap message in the trap buffer and generate an event for
1540 * user space applications with the SK_DRIVER_SENDEVENT macro.
1541 */
1542 QueueRlmtNewMacTrap(pAC, PhysPortIndex);
1543 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1544
1545 /*
1546 * Update statistic counters to calculate new offset for the virtual
1547 * port and increment semaphore to indicate that an update was
1548 * already done.
1549 */
1550 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1551 SK_PNMI_ERR_OK) {
1552
1553 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1554 return (0);
1555 }
1556 pAC->Pnmi.MacUpdatedFlag ++;
1557
1558 /*
1559 * Calculate new counter offset for virtual port to grant continous
1560 * counting on port switches. A new port is added to the virtual port.
1561 * Therefore substract the counter value of the new port from the
1562 * CounterOffset for the virtual port to grant the same value.
1563 */
1564 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1565 CounterIndex ++) {
1566
1567 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1568
1569 continue;
1570 }
1571
1572 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1573
1574 pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
1575 }
1576
1577 /* Set port to active */
1578 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
1579
1580 pAC->Pnmi.MacUpdatedFlag --;
1581 break;
1582
1583 case SK_PNMI_EVT_RLMT_SEGMENTATION:
1584 /*
1585 * Para.Para32[0] contains the NetIndex.
1586 */
1587
1588 /*
1589 * Store a trap message in the trap buffer and generate an event for
1590 * user space applications with the SK_DRIVER_SENDEVENT macro.
1591 */
1592 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
1593 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1594 break;
1595
1596 case SK_PNMI_EVT_RLMT_SET_NETS:
1597 /*
1598 * Param.Para32[0] contains the number of Nets.
1599 * Param.Para32[1] is reserved, contains -1.
1600 */
1601 /*
1602 * Check number of nets
1603 */
1604 MaxNetNumber = pAC->GIni.GIMacsFound;
1605 if (((unsigned int)Param.Para32[0] < 1)
1606 || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
1607 return (SK_PNMI_ERR_UNKNOWN_NET);
1608 }
1609
1610 if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
1611 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
1612 }
1613 else { /* dual net mode */
1614 pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
1615 }
1616 break;
1617
1618 case SK_PNMI_EVT_VCT_RESET:
1619 PhysPortIndex = Param.Para32[0];
1620 pPrt = &pAC->GIni.GP[PhysPortIndex];
1621 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
1622
1623 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
1624 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
1625 if (RetCode == 2) {
1626 /*
1627 * VCT test is still running.
1628 * Start VCT timer counter again.
1629 */
1630 SK_MEMSET((char *) &Param, 0, sizeof(Param));
1631 Param.Para32[0] = PhysPortIndex;
1632 Param.Para32[1] = -1;
1633 SkTimerStart(pAC, IoC,
1634 &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
1635 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
1636 break;
1637 }
1638 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
1639 pAC->Pnmi.VctStatus[PhysPortIndex] |=
1640 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
1641
1642 /* Copy results for later use to PNMI struct. */
1643 for (i = 0; i < 4; i++) {
1644 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
1645 if ((pPrt->PMdiPairLen[i] > 35) &&
1646 (pPrt->PMdiPairLen[i] < 0xff)) {
1647 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
1648 }
1649 }
1650 if ((pPrt->PMdiPairLen[i] > 35) &&
1651 (pPrt->PMdiPairLen[i] != 0xff)) {
1652 CableLength = 1000 *
1653 (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
1654 }
1655 else {
1656 CableLength = 0;
1657 }
1658 pVctBackupData->PMdiPairLen[i] = CableLength;
1659 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
1660 }
1661
1662 Param.Para32[0] = PhysPortIndex;
1663 Param.Para32[1] = -1;
1664 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
1665 SkEventDispatcher(pAC, IoC);
1666 }
1667
1668 break;
1669
1670 default:
1671 break;
1672 }
1673
1674 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1675 return (0);
1676}
1677
1678
1679/******************************************************************************
1680 *
1681 * Private functions
1682 *
1683 */
1684
1685/*****************************************************************************
1686 *
1687 * PnmiVar - Gets, presets, and sets single OIDs
1688 *
1689 * Description:
1690 * Looks up the requested OID, calls the corresponding handler
1691 * function, and passes the parameters with the get, preset, or
1692 * set command. The function is called by SkGePnmiGetVar,
1693 * SkGePnmiPreSetVar, or SkGePnmiSetVar.
1694 *
1695 * Returns:
1696 * SK_PNMI_ERR_XXX. For details have a look at the description of the
1697 * calling functions.
1698 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
1699 */
1700PNMI_STATIC int PnmiVar(
1701SK_AC *pAC, /* Pointer to adapter context */
1702SK_IOC IoC, /* IO context handle */
1703int Action, /* GET/PRESET/SET action */
1704SK_U32 Id, /* Object ID that is to be processed */
1705char *pBuf, /* Buffer used for the management data transfer */
1706unsigned int *pLen, /* Total length of pBuf management data */
1707SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
1708SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1709{
1710 unsigned int TableIndex;
1711 int Ret;
1712
1713
1714 if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
1715
1716 *pLen = 0;
1717 return (SK_PNMI_ERR_UNKNOWN_OID);
1718 }
1719
1720 /* Check NetIndex */
1721 if (NetIndex >= pAC->Rlmt.NumNets) {
1722 return (SK_PNMI_ERR_UNKNOWN_NET);
1723 }
1724
1725 SK_PNMI_CHECKFLAGS("PnmiVar: On call");
1726
1727 Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
1728 Instance, TableIndex, NetIndex);
1729
1730 SK_PNMI_CHECKFLAGS("PnmiVar: On return");
1731
1732 return (Ret);
1733}
1734
1735/*****************************************************************************
1736 *
1737 * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA
1738 *
1739 * Description:
1740 * The return value of the function will also be stored in
1741 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
1742 * SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable,
1743 * checks which OIDs are able to set, and calls the handler function of
1744 * the OID to perform the set. The return value of the function will
1745 * also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
1746 * minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called
1747 * by SkGePnmiPreSetStruct and SkGePnmiSetStruct.
1748 *
1749 * Returns:
1750 * SK_PNMI_ERR_XXX. The codes are described in the calling functions.
1751 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
1752 */
1753PNMI_STATIC int PnmiStruct(
1754SK_AC *pAC, /* Pointer to adapter context */
1755SK_IOC IoC, /* IO context handle */
1756int Action, /* PRESET/SET action to be performed */
1757char *pBuf, /* Buffer used for the management data transfer */
1758unsigned int *pLen, /* Length of pBuf management data buffer */
1759SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1760{
1761 int Ret;
1762 unsigned int TableIndex;
1763 unsigned int DstOffset;
1764 unsigned int Len;
1765 unsigned int InstanceNo;
1766 unsigned int InstanceCnt;
1767 SK_U32 Instance;
1768 SK_U32 Id;
1769
1770
1771 /* Check if the passed buffer has the right size */
1772 if (*pLen < SK_PNMI_STRUCT_SIZE) {
1773
1774 /* Check if we can return the error within the buffer */
1775 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
1776
1777 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
1778 (SK_U32)(-1));
1779 }
1780
1781 *pLen = SK_PNMI_STRUCT_SIZE;
1782 return (SK_PNMI_ERR_TOO_SHORT);
1783 }
1784
1785 /* Check NetIndex */
1786 if (NetIndex >= pAC->Rlmt.NumNets) {
1787 return (SK_PNMI_ERR_UNKNOWN_NET);
1788 }
1789
1790 SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
1791
1792 /*
1793 * Update the values of RLMT and SIRQ and increment semaphores to
1794 * indicate that an update was already done.
1795 */
1796 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
1797
1798 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1799 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1800 return (Ret);
1801 }
1802
1803 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
1804
1805 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1806 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1807 return (Ret);
1808 }
1809
1810 pAC->Pnmi.RlmtUpdatedFlag ++;
1811 pAC->Pnmi.SirqUpdatedFlag ++;
1812
1813 /* Preset/Set values */
1814 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
1815
1816 if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
1817 (IdTable[TableIndex].Access != SK_PNMI_WO)) {
1818
1819 continue;
1820 }
1821
1822 InstanceNo = IdTable[TableIndex].InstanceNo;
1823 Id = IdTable[TableIndex].Id;
1824
1825 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
1826 InstanceCnt ++) {
1827
1828 DstOffset = IdTable[TableIndex].Offset +
1829 (InstanceCnt - 1) *
1830 IdTable[TableIndex].StructSize;
1831
1832 /*
1833 * Because VPD multiple instance variables are
1834 * not setable we do not need to evaluate VPD
1835 * instances. Have a look to VPD instance
1836 * calculation in SkPnmiGetStruct().
1837 */
1838 Instance = (SK_U32)InstanceCnt;
1839
1840 /*
1841 * Evaluate needed buffer length
1842 */
1843 Len = 0;
1844 Ret = IdTable[TableIndex].Func(pAC, IoC,
1845 SK_PNMI_GET, IdTable[TableIndex].Id,
1846 NULL, &Len, Instance, TableIndex, NetIndex);
1847
1848 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
1849
1850 break;
1851 }
1852 if (Ret != SK_PNMI_ERR_TOO_SHORT) {
1853
1854 pAC->Pnmi.RlmtUpdatedFlag --;
1855 pAC->Pnmi.SirqUpdatedFlag --;
1856
1857 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1858 SK_PNMI_SET_STAT(pBuf,
1859 SK_PNMI_ERR_GENERAL, DstOffset);
1860 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1861 return (SK_PNMI_ERR_GENERAL);
1862 }
1863 if (Id == OID_SKGE_VPD_ACTION) {
1864
1865 switch (*(pBuf + DstOffset)) {
1866
1867 case SK_PNMI_VPD_CREATE:
1868 Len = 3 + *(pBuf + DstOffset + 3);
1869 break;
1870
1871 case SK_PNMI_VPD_DELETE:
1872 Len = 3;
1873 break;
1874
1875 default:
1876 Len = 1;
1877 break;
1878 }
1879 }
1880
1881 /* Call the OID handler function */
1882 Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
1883 IdTable[TableIndex].Id, pBuf + DstOffset,
1884 &Len, Instance, TableIndex, NetIndex);
1885
1886 if (Ret != SK_PNMI_ERR_OK) {
1887
1888 pAC->Pnmi.RlmtUpdatedFlag --;
1889 pAC->Pnmi.SirqUpdatedFlag --;
1890
1891 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1892 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
1893 DstOffset);
1894 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1895 return (SK_PNMI_ERR_BAD_VALUE);
1896 }
1897 }
1898 }
1899
1900 pAC->Pnmi.RlmtUpdatedFlag --;
1901 pAC->Pnmi.SirqUpdatedFlag --;
1902
1903 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1904 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
1905 return (SK_PNMI_ERR_OK);
1906}
1907
1908/*****************************************************************************
1909 *
1910 * LookupId - Lookup an OID in the IdTable
1911 *
1912 * Description:
1913 * Scans the IdTable to find the table entry of an OID.
1914 *
1915 * Returns:
1916 * The table index or -1 if not found.
1917 */
1918PNMI_STATIC int LookupId(
1919SK_U32 Id) /* Object identifier to be searched */
1920{
1921 int i;
1922
1923 for (i = 0; i < ID_TABLE_SIZE; i++) {
1924
1925 if (IdTable[i].Id == Id) {
1926
1927 return i;
1928 }
1929 }
1930
1931 return (-1);
1932}
1933
1934/*****************************************************************************
1935 *
1936 * OidStruct - Handler of OID_SKGE_ALL_DATA
1937 *
1938 * Description:
1939 * This OID performs a Get/Preset/SetStruct call and returns all data
1940 * in a SK_PNMI_STRUCT_DATA structure.
1941 *
1942 * Returns:
1943 * SK_PNMI_ERR_OK The request was successfully performed.
1944 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1945 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1946 * the correct data (e.g. a 32bit value is
1947 * needed, but a 16 bit value was passed).
1948 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1949 * value range.
1950 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
1951 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1952 * exist (e.g. port instance 3 on a two port
1953 * adapter.
1954 */
1955PNMI_STATIC int OidStruct(
1956SK_AC *pAC, /* Pointer to adapter context */
1957SK_IOC IoC, /* IO context handle */
1958int Action, /* GET/PRESET/SET action */
1959SK_U32 Id, /* Object ID that is to be processed */
1960char *pBuf, /* Buffer used for the management data transfer */
1961unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
1962SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
1963unsigned int TableIndex, /* Index to the Id table */
1964SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1965{
1966 if (Id != OID_SKGE_ALL_DATA) {
1967
1968 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
1969 SK_PNMI_ERR003MSG);
1970
1971 *pLen = 0;
1972 return (SK_PNMI_ERR_GENERAL);
1973 }
1974
1975 /*
1976 * Check instance. We only handle single instance variables
1977 */
1978 if (Instance != (SK_U32)(-1) && Instance != 1) {
1979
1980 *pLen = 0;
1981 return (SK_PNMI_ERR_UNKNOWN_INST);
1982 }
1983
1984 switch (Action) {
1985
1986 case SK_PNMI_GET:
1987 return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1988
1989 case SK_PNMI_PRESET:
1990 return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1991
1992 case SK_PNMI_SET:
1993 return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1994 }
1995
1996 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
1997
1998 *pLen = 0;
1999 return (SK_PNMI_ERR_GENERAL);
2000}
2001
2002/*****************************************************************************
2003 *
2004 * Perform - OID handler of OID_SKGE_ACTION
2005 *
2006 * Description:
2007 * None.
2008 *
2009 * Returns:
2010 * SK_PNMI_ERR_OK The request was successfully performed.
2011 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2012 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2013 * the correct data (e.g. a 32bit value is
2014 * needed, but a 16 bit value was passed).
2015 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2016 * value range.
2017 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2018 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2019 * exist (e.g. port instance 3 on a two port
2020 * adapter.
2021 */
2022PNMI_STATIC int Perform(
2023SK_AC *pAC, /* Pointer to adapter context */
2024SK_IOC IoC, /* IO context handle */
2025int Action, /* GET/PRESET/SET action */
2026SK_U32 Id, /* Object ID that is to be processed */
2027char *pBuf, /* Buffer used for the management data transfer */
2028unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2029SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2030unsigned int TableIndex, /* Index to the Id table */
2031SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2032{
2033 int Ret;
2034 SK_U32 ActionOp;
2035
2036
2037 /*
2038 * Check instance. We only handle single instance variables
2039 */
2040 if (Instance != (SK_U32)(-1) && Instance != 1) {
2041
2042 *pLen = 0;
2043 return (SK_PNMI_ERR_UNKNOWN_INST);
2044 }
2045
2046 if (*pLen < sizeof(SK_U32)) {
2047
2048 *pLen = sizeof(SK_U32);
2049 return (SK_PNMI_ERR_TOO_SHORT);
2050 }
2051
2052 /* Check if a get should be performed */
2053 if (Action == SK_PNMI_GET) {
2054
2055 /* A get is easy. We always return the same value */
2056 ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
2057 SK_PNMI_STORE_U32(pBuf, ActionOp);
2058 *pLen = sizeof(SK_U32);
2059
2060 return (SK_PNMI_ERR_OK);
2061 }
2062
2063 /* Continue with PRESET/SET action */
2064 if (*pLen > sizeof(SK_U32)) {
2065
2066 return (SK_PNMI_ERR_BAD_VALUE);
2067 }
2068
2069 /* Check if the command is a known one */
2070 SK_PNMI_READ_U32(pBuf, ActionOp);
2071 if (*pLen > sizeof(SK_U32) ||
2072 (ActionOp != SK_PNMI_ACT_IDLE &&
2073 ActionOp != SK_PNMI_ACT_RESET &&
2074 ActionOp != SK_PNMI_ACT_SELFTEST &&
2075 ActionOp != SK_PNMI_ACT_RESETCNT)) {
2076
2077 *pLen = 0;
2078 return (SK_PNMI_ERR_BAD_VALUE);
2079 }
2080
2081 /* A preset ends here */
2082 if (Action == SK_PNMI_PRESET) {
2083
2084 return (SK_PNMI_ERR_OK);
2085 }
2086
2087 switch (ActionOp) {
2088
2089 case SK_PNMI_ACT_IDLE:
2090 /* Nothing to do */
2091 break;
2092
2093 case SK_PNMI_ACT_RESET:
2094 /*
2095 * Perform a driver reset or something that comes near
2096 * to this.
2097 */
2098 Ret = SK_DRIVER_RESET(pAC, IoC);
2099 if (Ret != 0) {
2100
2101 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
2102 SK_PNMI_ERR005MSG);
2103
2104 return (SK_PNMI_ERR_GENERAL);
2105 }
2106 break;
2107
2108 case SK_PNMI_ACT_SELFTEST:
2109 /*
2110 * Perform a driver selftest or something similar to this.
2111 * Currently this feature is not used and will probably
2112 * implemented in another way.
2113 */
2114 Ret = SK_DRIVER_SELFTEST(pAC, IoC);
2115 pAC->Pnmi.TestResult = Ret;
2116 break;
2117
2118 case SK_PNMI_ACT_RESETCNT:
2119 /* Set all counters and timestamps to zero */
2120 ResetCounter(pAC, IoC, NetIndex);
2121 break;
2122
2123 default:
2124 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
2125 SK_PNMI_ERR006MSG);
2126
2127 return (SK_PNMI_ERR_GENERAL);
2128 }
2129
2130 return (SK_PNMI_ERR_OK);
2131}
2132
2133/*****************************************************************************
2134 *
2135 * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX
2136 *
2137 * Description:
2138 * Retrieves the statistic values of the virtual port (logical
2139 * index 0). Only special OIDs of NDIS are handled which consist
2140 * of a 32 bit instead of a 64 bit value. The OIDs are public
2141 * because perhaps some other platform can use them too.
2142 *
2143 * Returns:
2144 * SK_PNMI_ERR_OK The request was successfully performed.
2145 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2146 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2147 * the correct data (e.g. a 32bit value is
2148 * needed, but a 16 bit value was passed).
2149 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2150 * exist (e.g. port instance 3 on a two port
2151 * adapter.
2152 */
2153PNMI_STATIC int Mac8023Stat(
2154SK_AC *pAC, /* Pointer to adapter context */
2155SK_IOC IoC, /* IO context handle */
2156int Action, /* GET/PRESET/SET action */
2157SK_U32 Id, /* Object ID that is to be processed */
2158char *pBuf, /* Buffer used for the management data transfer */
2159unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2160SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2161unsigned int TableIndex, /* Index to the Id table */
2162SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2163{
2164 int Ret;
2165 SK_U64 StatVal;
2166 SK_U32 StatVal32;
2167 SK_BOOL Is64BitReq = SK_FALSE;
2168
2169 /*
2170 * Only the active Mac is returned
2171 */
2172 if (Instance != (SK_U32)(-1) && Instance != 1) {
2173
2174 *pLen = 0;
2175 return (SK_PNMI_ERR_UNKNOWN_INST);
2176 }
2177
2178 /*
2179 * Check action type
2180 */
2181 if (Action != SK_PNMI_GET) {
2182
2183 *pLen = 0;
2184 return (SK_PNMI_ERR_READ_ONLY);
2185 }
2186
2187 /* Check length */
2188 switch (Id) {
2189
2190 case OID_802_3_PERMANENT_ADDRESS:
2191 case OID_802_3_CURRENT_ADDRESS:
2192 if (*pLen < sizeof(SK_MAC_ADDR)) {
2193
2194 *pLen = sizeof(SK_MAC_ADDR);
2195 return (SK_PNMI_ERR_TOO_SHORT);
2196 }
2197 break;
2198
2199 default:
2200#ifndef SK_NDIS_64BIT_CTR
2201 if (*pLen < sizeof(SK_U32)) {
2202 *pLen = sizeof(SK_U32);
2203 return (SK_PNMI_ERR_TOO_SHORT);
2204 }
2205
2206#else /* SK_NDIS_64BIT_CTR */
2207
2208 /* for compatibility, at least 32bit are required for OID */
2209 if (*pLen < sizeof(SK_U32)) {
2210 /*
2211 * but indicate handling for 64bit values,
2212 * if insufficient space is provided
2213 */
2214 *pLen = sizeof(SK_U64);
2215 return (SK_PNMI_ERR_TOO_SHORT);
2216 }
2217
2218 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
2219#endif /* SK_NDIS_64BIT_CTR */
2220 break;
2221 }
2222
2223 /*
2224 * Update all statistics, because we retrieve virtual MAC, which
2225 * consists of multiple physical statistics and increment semaphore
2226 * to indicate that an update was already done.
2227 */
2228 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2229 if ( Ret != SK_PNMI_ERR_OK) {
2230
2231 *pLen = 0;
2232 return (Ret);
2233 }
2234 pAC->Pnmi.MacUpdatedFlag ++;
2235
2236 /*
2237 * Get value (MAC Index 0 identifies the virtual MAC)
2238 */
2239 switch (Id) {
2240
2241 case OID_802_3_PERMANENT_ADDRESS:
2242 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2243 *pLen = sizeof(SK_MAC_ADDR);
2244 break;
2245
2246 case OID_802_3_CURRENT_ADDRESS:
2247 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2248 *pLen = sizeof(SK_MAC_ADDR);
2249 break;
2250
2251 default:
2252 StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
2253
2254 /* by default 32bit values are evaluated */
2255 if (!Is64BitReq) {
2256 StatVal32 = (SK_U32)StatVal;
2257 SK_PNMI_STORE_U32(pBuf, StatVal32);
2258 *pLen = sizeof(SK_U32);
2259 }
2260 else {
2261 SK_PNMI_STORE_U64(pBuf, StatVal);
2262 *pLen = sizeof(SK_U64);
2263 }
2264 break;
2265 }
2266
2267 pAC->Pnmi.MacUpdatedFlag --;
2268
2269 return (SK_PNMI_ERR_OK);
2270}
2271
2272/*****************************************************************************
2273 *
2274 * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX
2275 *
2276 * Description:
2277 * Retrieves the MAC statistic data.
2278 *
2279 * Returns:
2280 * SK_PNMI_ERR_OK The request was successfully performed.
2281 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2282 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2283 * the correct data (e.g. a 32bit value is
2284 * needed, but a 16 bit value was passed).
2285 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2286 * exist (e.g. port instance 3 on a two port
2287 * adapter.
2288 */
2289PNMI_STATIC int MacPrivateStat(
2290SK_AC *pAC, /* Pointer to adapter context */
2291SK_IOC IoC, /* IO context handle */
2292int Action, /* GET/PRESET/SET action */
2293SK_U32 Id, /* Object ID that is to be processed */
2294char *pBuf, /* Buffer used for the management data transfer */
2295unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2296SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2297unsigned int TableIndex, /* Index to the Id table */
2298SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2299{
2300 unsigned int LogPortMax;
2301 unsigned int LogPortIndex;
2302 unsigned int PhysPortMax;
2303 unsigned int Limit;
2304 unsigned int Offset;
2305 int MacType;
2306 int Ret;
2307 SK_U64 StatVal;
2308
2309
2310
2311 /* Calculate instance if wished. MAC index 0 is the virtual MAC */
2312 PhysPortMax = pAC->GIni.GIMacsFound;
2313 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2314
2315 MacType = pAC->GIni.GIMacType;
2316
2317 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2318 LogPortMax--;
2319 }
2320
2321 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2322 /* Check instance range */
2323 if ((Instance < 1) || (Instance > LogPortMax)) {
2324
2325 *pLen = 0;
2326 return (SK_PNMI_ERR_UNKNOWN_INST);
2327 }
2328 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2329 Limit = LogPortIndex + 1;
2330 }
2331
2332 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2333
2334 LogPortIndex = 0;
2335 Limit = LogPortMax;
2336 }
2337
2338 /* Check action */
2339 if (Action != SK_PNMI_GET) {
2340
2341 *pLen = 0;
2342 return (SK_PNMI_ERR_READ_ONLY);
2343 }
2344
2345 /* Check length */
2346 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
2347
2348 *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
2349 return (SK_PNMI_ERR_TOO_SHORT);
2350 }
2351
2352 /*
2353 * Update MAC statistic and increment semaphore to indicate that
2354 * an update was already done.
2355 */
2356 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2357 if (Ret != SK_PNMI_ERR_OK) {
2358
2359 *pLen = 0;
2360 return (Ret);
2361 }
2362 pAC->Pnmi.MacUpdatedFlag ++;
2363
2364 /* Get value */
2365 Offset = 0;
2366 for (; LogPortIndex < Limit; LogPortIndex ++) {
2367
2368 switch (Id) {
2369
2370/* XXX not yet implemented due to XMAC problems
2371 case OID_SKGE_STAT_TX_UTIL:
2372 return (SK_PNMI_ERR_GENERAL);
2373*/
2374/* XXX not yet implemented due to XMAC problems
2375 case OID_SKGE_STAT_RX_UTIL:
2376 return (SK_PNMI_ERR_GENERAL);
2377*/
2378 case OID_SKGE_STAT_RX:
2379 if (MacType == SK_MAC_GMAC) {
2380 StatVal =
2381 GetStatVal(pAC, IoC, LogPortIndex,
2382 SK_PNMI_HRX_BROADCAST, NetIndex) +
2383 GetStatVal(pAC, IoC, LogPortIndex,
2384 SK_PNMI_HRX_MULTICAST, NetIndex) +
2385 GetStatVal(pAC, IoC, LogPortIndex,
2386 SK_PNMI_HRX_UNICAST, NetIndex) +
2387 GetStatVal(pAC, IoC, LogPortIndex,
2388 SK_PNMI_HRX_UNDERSIZE, NetIndex);
2389 }
2390 else {
2391 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2392 IdTable[TableIndex].Param, NetIndex);
2393 }
2394 break;
2395
2396 case OID_SKGE_STAT_TX:
2397 if (MacType == SK_MAC_GMAC) {
2398 StatVal =
2399 GetStatVal(pAC, IoC, LogPortIndex,
2400 SK_PNMI_HTX_BROADCAST, NetIndex) +
2401 GetStatVal(pAC, IoC, LogPortIndex,
2402 SK_PNMI_HTX_MULTICAST, NetIndex) +
2403 GetStatVal(pAC, IoC, LogPortIndex,
2404 SK_PNMI_HTX_UNICAST, NetIndex);
2405 }
2406 else {
2407 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2408 IdTable[TableIndex].Param, NetIndex);
2409 }
2410 break;
2411
2412 default:
2413 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2414 IdTable[TableIndex].Param, NetIndex);
2415 }
2416 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2417
2418 Offset += sizeof(SK_U64);
2419 }
2420 *pLen = Offset;
2421
2422 pAC->Pnmi.MacUpdatedFlag --;
2423
2424 return (SK_PNMI_ERR_OK);
2425}
2426
2427/*****************************************************************************
2428 *
2429 * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR
2430 *
2431 * Description:
2432 * Get/Presets/Sets the current and factory MAC address. The MAC
2433 * address of the virtual port, which is reported to the OS, may
2434 * not be changed, but the physical ones. A set to the virtual port
2435 * will be ignored. No error should be reported because otherwise
2436 * a multiple instance set (-1) would always fail.
2437 *
2438 * Returns:
2439 * SK_PNMI_ERR_OK The request was successfully performed.
2440 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2441 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2442 * the correct data (e.g. a 32bit value is
2443 * needed, but a 16 bit value was passed).
2444 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2445 * value range.
2446 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2447 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2448 * exist (e.g. port instance 3 on a two port
2449 * adapter.
2450 */
2451PNMI_STATIC int Addr(
2452SK_AC *pAC, /* Pointer to adapter context */
2453SK_IOC IoC, /* IO context handle */
2454int Action, /* GET/PRESET/SET action */
2455SK_U32 Id, /* Object ID that is to be processed */
2456char *pBuf, /* Buffer used for the management data transfer */
2457unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2458SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2459unsigned int TableIndex, /* Index to the Id table */
2460SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2461{
2462 int Ret;
2463 unsigned int LogPortMax;
2464 unsigned int PhysPortMax;
2465 unsigned int LogPortIndex;
2466 unsigned int PhysPortIndex;
2467 unsigned int Limit;
2468 unsigned int Offset = 0;
2469
2470 /*
2471 * Calculate instance if wished. MAC index 0 is the virtual
2472 * MAC.
2473 */
2474 PhysPortMax = pAC->GIni.GIMacsFound;
2475 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2476
2477 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2478 LogPortMax--;
2479 }
2480
2481 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2482 /* Check instance range */
2483 if ((Instance < 1) || (Instance > LogPortMax)) {
2484
2485 *pLen = 0;
2486 return (SK_PNMI_ERR_UNKNOWN_INST);
2487 }
2488 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2489 Limit = LogPortIndex + 1;
2490 }
2491 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2492
2493 LogPortIndex = 0;
2494 Limit = LogPortMax;
2495 }
2496
2497 /*
2498 * Perform Action
2499 */
2500 if (Action == SK_PNMI_GET) {
2501
2502 /* Check length */
2503 if (*pLen < (Limit - LogPortIndex) * 6) {
2504
2505 *pLen = (Limit - LogPortIndex) * 6;
2506 return (SK_PNMI_ERR_TOO_SHORT);
2507 }
2508
2509 /*
2510 * Get value
2511 */
2512 for (; LogPortIndex < Limit; LogPortIndex ++) {
2513
2514 switch (Id) {
2515
2516 case OID_SKGE_PHYS_CUR_ADDR:
2517 if (LogPortIndex == 0) {
2518 CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2519 }
2520 else {
2521 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
2522
2523 CopyMac(pBuf + Offset,
2524 &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
2525 }
2526 Offset += 6;
2527 break;
2528
2529 case OID_SKGE_PHYS_FAC_ADDR:
2530 if (LogPortIndex == 0) {
2531 CopyMac(pBuf + Offset,
2532 &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2533 }
2534 else {
2535 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
2536 pAC, LogPortIndex);
2537
2538 CopyMac(pBuf + Offset,
2539 &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
2540 }
2541 Offset += 6;
2542 break;
2543
2544 default:
2545 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
2546 SK_PNMI_ERR008MSG);
2547
2548 *pLen = 0;
2549 return (SK_PNMI_ERR_GENERAL);
2550 }
2551 }
2552
2553 *pLen = Offset;
2554 }
2555 else {
2556 /*
2557 * The logical MAC address may not be changed only
2558 * the physical ones
2559 */
2560 if (Id == OID_SKGE_PHYS_FAC_ADDR) {
2561
2562 *pLen = 0;
2563 return (SK_PNMI_ERR_READ_ONLY);
2564 }
2565
2566 /*
2567 * Only the current address may be changed
2568 */
2569 if (Id != OID_SKGE_PHYS_CUR_ADDR) {
2570
2571 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
2572 SK_PNMI_ERR009MSG);
2573
2574 *pLen = 0;
2575 return (SK_PNMI_ERR_GENERAL);
2576 }
2577
2578 /* Check length */
2579 if (*pLen < (Limit - LogPortIndex) * 6) {
2580
2581 *pLen = (Limit - LogPortIndex) * 6;
2582 return (SK_PNMI_ERR_TOO_SHORT);
2583 }
2584 if (*pLen > (Limit - LogPortIndex) * 6) {
2585
2586 *pLen = 0;
2587 return (SK_PNMI_ERR_BAD_VALUE);
2588 }
2589
2590 /*
2591 * Check Action
2592 */
2593 if (Action == SK_PNMI_PRESET) {
2594
2595 *pLen = 0;
2596 return (SK_PNMI_ERR_OK);
2597 }
2598
2599 /*
2600 * Set OID_SKGE_MAC_CUR_ADDR
2601 */
2602 for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
2603
2604 /*
2605 * A set to virtual port and set of broadcast
2606 * address will be ignored
2607 */
2608 if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
2609 "\xff\xff\xff\xff\xff\xff", 6) == 0) {
2610
2611 continue;
2612 }
2613
2614 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
2615 LogPortIndex);
2616
2617 Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
2618 (SK_MAC_ADDR *)(pBuf + Offset),
2619 (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
2620 SK_ADDR_PHYSICAL_ADDRESS));
2621 if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {
2622
2623 return (SK_PNMI_ERR_GENERAL);
2624 }
2625 }
2626 *pLen = Offset;
2627 }
2628
2629 return (SK_PNMI_ERR_OK);
2630}
2631
2632/*****************************************************************************
2633 *
2634 * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
2635 *
2636 * Description:
2637 * Retrieves the statistic values of the CSUM module. The CSUM data
2638 * structure must be available in the SK_AC even if the CSUM module
2639 * is not included, because PNMI reads the statistic data from the
2640 * CSUM part of SK_AC directly.
2641 *
2642 * Returns:
2643 * SK_PNMI_ERR_OK The request was successfully performed.
2644 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2645 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2646 * the correct data (e.g. a 32bit value is
2647 * needed, but a 16 bit value was passed).
2648 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2649 * exist (e.g. port instance 3 on a two port
2650 * adapter.
2651 */
2652PNMI_STATIC int CsumStat(
2653SK_AC *pAC, /* Pointer to adapter context */
2654SK_IOC IoC, /* IO context handle */
2655int Action, /* GET/PRESET/SET action */
2656SK_U32 Id, /* Object ID that is to be processed */
2657char *pBuf, /* Buffer used for the management data transfer */
2658unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2659SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2660unsigned int TableIndex, /* Index to the Id table */
2661SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2662{
2663 unsigned int Index;
2664 unsigned int Limit;
2665 unsigned int Offset = 0;
2666 SK_U64 StatVal;
2667
2668
2669 /*
2670 * Calculate instance if wished
2671 */
2672 if (Instance != (SK_U32)(-1)) {
2673
2674 if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
2675
2676 *pLen = 0;
2677 return (SK_PNMI_ERR_UNKNOWN_INST);
2678 }
2679 Index = (unsigned int)Instance - 1;
2680 Limit = Index + 1;
2681 }
2682 else {
2683 Index = 0;
2684 Limit = SKCS_NUM_PROTOCOLS;
2685 }
2686
2687 /*
2688 * Check action
2689 */
2690 if (Action != SK_PNMI_GET) {
2691
2692 *pLen = 0;
2693 return (SK_PNMI_ERR_READ_ONLY);
2694 }
2695
2696 /* Check length */
2697 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
2698
2699 *pLen = (Limit - Index) * sizeof(SK_U64);
2700 return (SK_PNMI_ERR_TOO_SHORT);
2701 }
2702
2703 /*
2704 * Get value
2705 */
2706 for (; Index < Limit; Index ++) {
2707
2708 switch (Id) {
2709
2710 case OID_SKGE_CHKSM_RX_OK_CTS:
2711 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
2712 break;
2713
2714 case OID_SKGE_CHKSM_RX_UNABLE_CTS:
2715 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
2716 break;
2717
2718 case OID_SKGE_CHKSM_RX_ERR_CTS:
2719 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
2720 break;
2721
2722 case OID_SKGE_CHKSM_TX_OK_CTS:
2723 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
2724 break;
2725
2726 case OID_SKGE_CHKSM_TX_UNABLE_CTS:
2727 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
2728 break;
2729
2730 default:
2731 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
2732 SK_PNMI_ERR010MSG);
2733
2734 *pLen = 0;
2735 return (SK_PNMI_ERR_GENERAL);
2736 }
2737
2738 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2739 Offset += sizeof(SK_U64);
2740 }
2741
2742 /*
2743 * Store used buffer space
2744 */
2745 *pLen = Offset;
2746
2747 return (SK_PNMI_ERR_OK);
2748}
2749
2750/*****************************************************************************
2751 *
2752 * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
2753 *
2754 * Description:
2755 * Retrieves the statistic values of the I2C module, which handles
2756 * the temperature and voltage sensors.
2757 *
2758 * Returns:
2759 * SK_PNMI_ERR_OK The request was successfully performed.
2760 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2761 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2762 * the correct data (e.g. a 32bit value is
2763 * needed, but a 16 bit value was passed).
2764 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2765 * exist (e.g. port instance 3 on a two port
2766 * adapter.
2767 */
2768PNMI_STATIC int SensorStat(
2769SK_AC *pAC, /* Pointer to adapter context */
2770SK_IOC IoC, /* IO context handle */
2771int Action, /* GET/PRESET/SET action */
2772SK_U32 Id, /* Object ID that is to be processed */
2773char *pBuf, /* Buffer used for the management data transfer */
2774unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2775SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2776unsigned int TableIndex, /* Index to the Id table */
2777SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2778{
2779 unsigned int i;
2780 unsigned int Index;
2781 unsigned int Limit;
2782 unsigned int Offset;
2783 unsigned int Len;
2784 SK_U32 Val32;
2785 SK_U64 Val64;
2786
2787
2788 /*
2789 * Calculate instance if wished
2790 */
2791 if ((Instance != (SK_U32)(-1))) {
2792
2793 if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
2794
2795 *pLen = 0;
2796 return (SK_PNMI_ERR_UNKNOWN_INST);
2797 }
2798
2799 Index = (unsigned int)Instance -1;
2800 Limit = (unsigned int)Instance;
2801 }
2802 else {
2803 Index = 0;
2804 Limit = (unsigned int) pAC->I2c.MaxSens;
2805 }
2806
2807 /*
2808 * Check action
2809 */
2810 if (Action != SK_PNMI_GET) {
2811
2812 *pLen = 0;
2813 return (SK_PNMI_ERR_READ_ONLY);
2814 }
2815
2816 /* Check length */
2817 switch (Id) {
2818
2819 case OID_SKGE_SENSOR_VALUE:
2820 case OID_SKGE_SENSOR_WAR_THRES_LOW:
2821 case OID_SKGE_SENSOR_WAR_THRES_UPP:
2822 case OID_SKGE_SENSOR_ERR_THRES_LOW:
2823 case OID_SKGE_SENSOR_ERR_THRES_UPP:
2824 if (*pLen < (Limit - Index) * sizeof(SK_U32)) {
2825
2826 *pLen = (Limit - Index) * sizeof(SK_U32);
2827 return (SK_PNMI_ERR_TOO_SHORT);
2828 }
2829 break;
2830
2831 case OID_SKGE_SENSOR_DESCR:
2832 for (Offset = 0, i = Index; i < Limit; i ++) {
2833
2834 Len = (unsigned int)
2835 SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1;
2836 if (Len >= SK_PNMI_STRINGLEN2) {
2837
2838 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011,
2839 SK_PNMI_ERR011MSG);
2840
2841 *pLen = 0;
2842 return (SK_PNMI_ERR_GENERAL);
2843 }
2844 Offset += Len;
2845 }
2846 if (*pLen < Offset) {
2847
2848 *pLen = Offset;
2849 return (SK_PNMI_ERR_TOO_SHORT);
2850 }
2851 break;
2852
2853 case OID_SKGE_SENSOR_INDEX:
2854 case OID_SKGE_SENSOR_TYPE:
2855 case OID_SKGE_SENSOR_STATUS:
2856 if (*pLen < Limit - Index) {
2857
2858 *pLen = Limit - Index;
2859 return (SK_PNMI_ERR_TOO_SHORT);
2860 }
2861 break;
2862
2863 case OID_SKGE_SENSOR_WAR_CTS:
2864 case OID_SKGE_SENSOR_WAR_TIME:
2865 case OID_SKGE_SENSOR_ERR_CTS:
2866 case OID_SKGE_SENSOR_ERR_TIME:
2867 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
2868
2869 *pLen = (Limit - Index) * sizeof(SK_U64);
2870 return (SK_PNMI_ERR_TOO_SHORT);
2871 }
2872 break;
2873
2874 default:
2875 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
2876 SK_PNMI_ERR012MSG);
2877
2878 *pLen = 0;
2879 return (SK_PNMI_ERR_GENERAL);
2880
2881 }
2882
2883 /*
2884 * Get value
2885 */
2886 for (Offset = 0; Index < Limit; Index ++) {
2887
2888 switch (Id) {
2889
2890 case OID_SKGE_SENSOR_INDEX:
2891 *(pBuf + Offset) = (char)Index;
2892 Offset += sizeof(char);
2893 break;
2894
2895 case OID_SKGE_SENSOR_DESCR:
2896 Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
2897 SK_MEMCPY(pBuf + Offset + 1,
2898 pAC->I2c.SenTable[Index].SenDesc, Len);
2899 *(pBuf + Offset) = (char)Len;
2900 Offset += Len + 1;
2901 break;
2902
2903 case OID_SKGE_SENSOR_TYPE:
2904 *(pBuf + Offset) =
2905 (char)pAC->I2c.SenTable[Index].SenType;
2906 Offset += sizeof(char);
2907 break;
2908
2909 case OID_SKGE_SENSOR_VALUE:
2910 Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
2911 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2912 Offset += sizeof(SK_U32);
2913 break;
2914
2915 case OID_SKGE_SENSOR_WAR_THRES_LOW:
2916 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2917 SenThreWarnLow;
2918 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2919 Offset += sizeof(SK_U32);
2920 break;
2921
2922 case OID_SKGE_SENSOR_WAR_THRES_UPP:
2923 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2924 SenThreWarnHigh;
2925 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2926 Offset += sizeof(SK_U32);
2927 break;
2928
2929 case OID_SKGE_SENSOR_ERR_THRES_LOW:
2930 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2931 SenThreErrLow;
2932 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2933 Offset += sizeof(SK_U32);
2934 break;
2935
2936 case OID_SKGE_SENSOR_ERR_THRES_UPP:
2937 Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
2938 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2939 Offset += sizeof(SK_U32);
2940 break;
2941
2942 case OID_SKGE_SENSOR_STATUS:
2943 *(pBuf + Offset) =
2944 (char)pAC->I2c.SenTable[Index].SenErrFlag;
2945 Offset += sizeof(char);
2946 break;
2947
2948 case OID_SKGE_SENSOR_WAR_CTS:
2949 Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
2950 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2951 Offset += sizeof(SK_U64);
2952 break;
2953
2954 case OID_SKGE_SENSOR_ERR_CTS:
2955 Val64 = pAC->I2c.SenTable[Index].SenErrCts;
2956 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2957 Offset += sizeof(SK_U64);
2958 break;
2959
2960 case OID_SKGE_SENSOR_WAR_TIME:
2961 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
2962 SenBegWarnTS);
2963 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2964 Offset += sizeof(SK_U64);
2965 break;
2966
2967 case OID_SKGE_SENSOR_ERR_TIME:
2968 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
2969 SenBegErrTS);
2970 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2971 Offset += sizeof(SK_U64);
2972 break;
2973
2974 default:
2975 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
2976 ("SensorStat: Unknown OID should be handled before"));
2977
2978 return (SK_PNMI_ERR_GENERAL);
2979 }
2980 }
2981
2982 /*
2983 * Store used buffer space
2984 */
2985 *pLen = Offset;
2986
2987 return (SK_PNMI_ERR_OK);
2988}
2989
2990/*****************************************************************************
2991 *
2992 * Vpd - OID handler function of OID_SKGE_VPD_XXX
2993 *
2994 * Description:
2995 * Get/preset/set of VPD data. As instance the name of a VPD key
2996 * can be passed. The Instance parameter is a SK_U32 and can be
2997 * used as a string buffer for the VPD key, because their maximum
2998 * length is 4 byte.
2999 *
3000 * Returns:
3001 * SK_PNMI_ERR_OK The request was successfully performed.
3002 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3003 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3004 * the correct data (e.g. a 32bit value is
3005 * needed, but a 16 bit value was passed).
3006 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
3007 * value range.
3008 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
3009 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3010 * exist (e.g. port instance 3 on a two port
3011 * adapter.
3012 */
3013PNMI_STATIC int Vpd(
3014SK_AC *pAC, /* Pointer to adapter context */
3015SK_IOC IoC, /* IO context handle */
3016int Action, /* GET/PRESET/SET action */
3017SK_U32 Id, /* Object ID that is to be processed */
3018char *pBuf, /* Buffer used for the management data transfer */
3019unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
3020SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3021unsigned int TableIndex, /* Index to the Id table */
3022SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
3023{
3024 SK_VPD_STATUS *pVpdStatus;
3025 unsigned int BufLen;
3026 char Buf[256];
3027 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
3028 char KeyStr[SK_PNMI_VPD_KEY_SIZE];
3029 unsigned int KeyNo;
3030 unsigned int Offset;
3031 unsigned int Index;
3032 unsigned int FirstIndex;
3033 unsigned int LastIndex;
3034 unsigned int Len;
3035 int Ret;
3036 SK_U32 Val32;
3037
3038 /*
3039 * Get array of all currently stored VPD keys
3040 */
3041 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &KeyNo);
3042 if (Ret != SK_PNMI_ERR_OK) {
3043 *pLen = 0;
3044 return (Ret);
3045 }
3046
3047 /*
3048 * If instance is not -1, try to find the requested VPD key for
3049 * the multiple instance variables. The other OIDs as for example
3050 * OID VPD_ACTION are single instance variables and must be
3051 * handled separatly.
3052 */
3053 FirstIndex = 0;
3054 LastIndex = KeyNo;
3055
3056 if ((Instance != (SK_U32)(-1))) {
3057
3058 if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
3059 Id == OID_SKGE_VPD_ACCESS) {
3060
3061 SK_STRNCPY(KeyStr, (char *)&Instance, 4);
3062 KeyStr[4] = 0;
3063
3064 for (Index = 0; Index < KeyNo; Index ++) {
3065
3066 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3067 FirstIndex = Index;
3068 LastIndex = Index+1;
3069 break;
3070 }
3071 }
3072 if (Index == KeyNo) {
3073
3074 *pLen = 0;
3075 return (SK_PNMI_ERR_UNKNOWN_INST);
3076 }
3077 }
3078 else if (Instance != 1) {
3079
3080 *pLen = 0;
3081 return (SK_PNMI_ERR_UNKNOWN_INST);
3082 }
3083 }
3084
3085 /*
3086 * Get value, if a query should be performed
3087 */
3088 if (Action == SK_PNMI_GET) {
3089
3090 switch (Id) {
3091
3092 case OID_SKGE_VPD_FREE_BYTES:
3093 /* Check length of buffer */
3094 if (*pLen < sizeof(SK_U32)) {
3095
3096 *pLen = sizeof(SK_U32);
3097 return (SK_PNMI_ERR_TOO_SHORT);
3098 }
3099 /* Get number of free bytes */
3100 pVpdStatus = VpdStat(pAC, IoC);
3101 if (pVpdStatus == NULL) {
3102
3103 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
3104 SK_PNMI_ERR017MSG);
3105
3106 *pLen = 0;
3107 return (SK_PNMI_ERR_GENERAL);
3108 }
3109 if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
3110
3111 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
3112 SK_PNMI_ERR018MSG);
3113
3114 *pLen = 0;
3115 return (SK_PNMI_ERR_GENERAL);
3116 }
3117
3118 Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
3119 SK_PNMI_STORE_U32(pBuf, Val32);
3120 *pLen = sizeof(SK_U32);
3121 break;
3122
3123 case OID_SKGE_VPD_ENTRIES_LIST:
3124 /* Check length */
3125 for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
3126
3127 Len += SK_STRLEN(KeyArr[Index]) + 1;
3128 }
3129 if (*pLen < Len) {
3130
3131 *pLen = Len;
3132 return (SK_PNMI_ERR_TOO_SHORT);
3133 }
3134
3135 /* Get value */
3136 *(pBuf) = (char)Len - 1;
3137 for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
3138
3139 Len = SK_STRLEN(KeyArr[Index]);
3140 SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
3141
3142 Offset += Len;
3143
3144 if (Index < KeyNo - 1) {
3145
3146 *(pBuf + Offset) = ' ';
3147 Offset ++;
3148 }
3149 }
3150 *pLen = Offset;
3151 break;
3152
3153 case OID_SKGE_VPD_ENTRIES_NUMBER:
3154 /* Check length */
3155 if (*pLen < sizeof(SK_U32)) {
3156
3157 *pLen = sizeof(SK_U32);
3158 return (SK_PNMI_ERR_TOO_SHORT);
3159 }
3160
3161 Val32 = (SK_U32)KeyNo;
3162 SK_PNMI_STORE_U32(pBuf, Val32);
3163 *pLen = sizeof(SK_U32);
3164 break;
3165
3166 case OID_SKGE_VPD_KEY:
3167 /* Check buffer length, if it is large enough */
3168 for (Len = 0, Index = FirstIndex;
3169 Index < LastIndex; Index ++) {
3170
3171 Len += SK_STRLEN(KeyArr[Index]) + 1;
3172 }
3173 if (*pLen < Len) {
3174
3175 *pLen = Len;
3176 return (SK_PNMI_ERR_TOO_SHORT);
3177 }
3178
3179 /*
3180 * Get the key to an intermediate buffer, because
3181 * we have to prepend a length byte.
3182 */
3183 for (Offset = 0, Index = FirstIndex;
3184 Index < LastIndex; Index ++) {
3185
3186 Len = SK_STRLEN(KeyArr[Index]);
3187
3188 *(pBuf + Offset) = (char)Len;
3189 SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
3190 Len);
3191 Offset += Len + 1;
3192 }
3193 *pLen = Offset;
3194 break;
3195
3196 case OID_SKGE_VPD_VALUE:
3197 /* Check the buffer length if it is large enough */
3198 for (Offset = 0, Index = FirstIndex;
3199 Index < LastIndex; Index ++) {
3200
3201 BufLen = 256;
3202 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3203 (int *)&BufLen) > 0 ||
3204 BufLen >= SK_PNMI_VPD_DATALEN) {
3205
3206 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3207 SK_PNMI_ERR021,
3208 SK_PNMI_ERR021MSG);
3209
3210 return (SK_PNMI_ERR_GENERAL);
3211 }
3212 Offset += BufLen + 1;
3213 }
3214 if (*pLen < Offset) {
3215
3216 *pLen = Offset;
3217 return (SK_PNMI_ERR_TOO_SHORT);
3218 }
3219
3220 /*
3221 * Get the value to an intermediate buffer, because
3222 * we have to prepend a length byte.
3223 */
3224 for (Offset = 0, Index = FirstIndex;
3225 Index < LastIndex; Index ++) {
3226
3227 BufLen = 256;
3228 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3229 (int *)&BufLen) > 0 ||
3230 BufLen >= SK_PNMI_VPD_DATALEN) {
3231
3232 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3233 SK_PNMI_ERR022,
3234 SK_PNMI_ERR022MSG);
3235
3236 *pLen = 0;
3237 return (SK_PNMI_ERR_GENERAL);
3238 }
3239
3240 *(pBuf + Offset) = (char)BufLen;
3241 SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
3242 Offset += BufLen + 1;
3243 }
3244 *pLen = Offset;
3245 break;
3246
3247 case OID_SKGE_VPD_ACCESS:
3248 if (*pLen < LastIndex - FirstIndex) {
3249
3250 *pLen = LastIndex - FirstIndex;
3251 return (SK_PNMI_ERR_TOO_SHORT);
3252 }
3253
3254 for (Offset = 0, Index = FirstIndex;
3255 Index < LastIndex; Index ++) {
3256
3257 if (VpdMayWrite(KeyArr[Index])) {
3258
3259 *(pBuf + Offset) = SK_PNMI_VPD_RW;
3260 }
3261 else {
3262 *(pBuf + Offset) = SK_PNMI_VPD_RO;
3263 }
3264 Offset ++;
3265 }
3266 *pLen = Offset;
3267 break;
3268
3269 case OID_SKGE_VPD_ACTION:
3270 Offset = LastIndex - FirstIndex;
3271 if (*pLen < Offset) {
3272
3273 *pLen = Offset;
3274 return (SK_PNMI_ERR_TOO_SHORT);
3275 }
3276 SK_MEMSET(pBuf, 0, Offset);
3277 *pLen = Offset;
3278 break;
3279
3280 default:
3281 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
3282 SK_PNMI_ERR023MSG);
3283
3284 *pLen = 0;
3285 return (SK_PNMI_ERR_GENERAL);
3286 }
3287 }
3288 else {
3289 /* The only OID which can be set is VPD_ACTION */
3290 if (Id != OID_SKGE_VPD_ACTION) {
3291
3292 if (Id == OID_SKGE_VPD_FREE_BYTES ||
3293 Id == OID_SKGE_VPD_ENTRIES_LIST ||
3294 Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
3295 Id == OID_SKGE_VPD_KEY ||
3296 Id == OID_SKGE_VPD_VALUE ||
3297 Id == OID_SKGE_VPD_ACCESS) {
3298
3299 *pLen = 0;
3300 return (SK_PNMI_ERR_READ_ONLY);
3301 }
3302
3303 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
3304 SK_PNMI_ERR024MSG);
3305
3306 *pLen = 0;
3307 return (SK_PNMI_ERR_GENERAL);
3308 }
3309
3310 /*
3311 * From this point we handle VPD_ACTION. Check the buffer
3312 * length. It should at least have the size of one byte.
3313 */
3314 if (*pLen < 1) {
3315
3316 *pLen = 1;
3317 return (SK_PNMI_ERR_TOO_SHORT);
3318 }
3319
3320 /*
3321 * The first byte contains the VPD action type we should
3322 * perform.
3323 */
3324 switch (*pBuf) {
3325
3326 case SK_PNMI_VPD_IGNORE:
3327 /* Nothing to do */
3328 break;
3329
3330 case SK_PNMI_VPD_CREATE:
3331 /*
3332 * We have to create a new VPD entry or we modify
3333 * an existing one. Check first the buffer length.
3334 */
3335 if (*pLen < 4) {
3336
3337 *pLen = 4;
3338 return (SK_PNMI_ERR_TOO_SHORT);
3339 }
3340 KeyStr[0] = pBuf[1];
3341 KeyStr[1] = pBuf[2];
3342 KeyStr[2] = 0;
3343
3344 /*
3345 * Is the entry writable or does it belong to the
3346 * read-only area?
3347 */
3348 if (!VpdMayWrite(KeyStr)) {
3349
3350 *pLen = 0;
3351 return (SK_PNMI_ERR_BAD_VALUE);
3352 }
3353
3354 Offset = (int)pBuf[3] & 0xFF;
3355
3356 SK_MEMCPY(Buf, pBuf + 4, Offset);
3357 Buf[Offset] = 0;
3358
3359 /* A preset ends here */
3360 if (Action == SK_PNMI_PRESET) {
3361
3362 return (SK_PNMI_ERR_OK);
3363 }
3364
3365 /* Write the new entry or modify an existing one */
3366 Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
3367 if (Ret == SK_PNMI_VPD_NOWRITE ) {
3368
3369 *pLen = 0;
3370 return (SK_PNMI_ERR_BAD_VALUE);
3371 }
3372 else if (Ret != SK_PNMI_VPD_OK) {
3373
3374 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
3375 SK_PNMI_ERR025MSG);
3376
3377 *pLen = 0;
3378 return (SK_PNMI_ERR_GENERAL);
3379 }
3380
3381 /*
3382 * Perform an update of the VPD data. This is
3383 * not mandantory, but just to be sure.
3384 */
3385 Ret = VpdUpdate(pAC, IoC);
3386 if (Ret != SK_PNMI_VPD_OK) {
3387
3388 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
3389 SK_PNMI_ERR026MSG);
3390
3391 *pLen = 0;
3392 return (SK_PNMI_ERR_GENERAL);
3393 }
3394 break;
3395
3396 case SK_PNMI_VPD_DELETE:
3397 /* Check if the buffer size is plausible */
3398 if (*pLen < 3) {
3399
3400 *pLen = 3;
3401 return (SK_PNMI_ERR_TOO_SHORT);
3402 }
3403 if (*pLen > 3) {
3404
3405 *pLen = 0;
3406 return (SK_PNMI_ERR_BAD_VALUE);
3407 }
3408 KeyStr[0] = pBuf[1];
3409 KeyStr[1] = pBuf[2];
3410 KeyStr[2] = 0;
3411
3412 /* Find the passed key in the array */
3413 for (Index = 0; Index < KeyNo; Index ++) {
3414
3415 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3416
3417 break;
3418 }
3419 }
3420 /*
3421 * If we cannot find the key it is wrong, so we
3422 * return an appropriate error value.
3423 */
3424 if (Index == KeyNo) {
3425
3426 *pLen = 0;
3427 return (SK_PNMI_ERR_BAD_VALUE);
3428 }
3429
3430 if (Action == SK_PNMI_PRESET) {
3431
3432 return (SK_PNMI_ERR_OK);
3433 }
3434
3435 /* Ok, you wanted it and you will get it */
3436 Ret = VpdDelete(pAC, IoC, KeyStr);
3437 if (Ret != SK_PNMI_VPD_OK) {
3438
3439 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
3440 SK_PNMI_ERR027MSG);
3441
3442 *pLen = 0;
3443 return (SK_PNMI_ERR_GENERAL);
3444 }
3445
3446 /*
3447 * Perform an update of the VPD data. This is
3448 * not mandantory, but just to be sure.
3449 */
3450 Ret = VpdUpdate(pAC, IoC);
3451 if (Ret != SK_PNMI_VPD_OK) {
3452
3453 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
3454 SK_PNMI_ERR028MSG);
3455
3456 *pLen = 0;
3457 return (SK_PNMI_ERR_GENERAL);
3458 }
3459 break;
3460
3461 default:
3462 *pLen = 0;
3463 return (SK_PNMI_ERR_BAD_VALUE);
3464 }
3465 }
3466
3467 return (SK_PNMI_ERR_OK);
3468}
3469
3470/*****************************************************************************
3471 *
3472 * General - OID handler function of various single instance OIDs
3473 *
3474 * Description:
3475 * The code is simple. No description necessary.
3476 *
3477 * Returns:
3478 * SK_PNMI_ERR_OK The request was successfully performed.
3479 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3480 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3481 * the correct data (e.g. a 32bit value is
3482 * needed, but a 16 bit value was passed).
3483 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3484 * exist (e.g. port instance 3 on a two port
3485 * adapter.
3486 */
3487PNMI_STATIC int General(
3488SK_AC *pAC, /* Pointer to adapter context */
3489SK_IOC IoC, /* IO context handle */
3490int Action, /* GET/PRESET/SET action */
3491SK_U32 Id, /* Object ID that is to be processed */
3492char *pBuf, /* Buffer used for the management data transfer */
3493unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3494SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3495unsigned int TableIndex, /* Index to the Id table */
3496SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
3497{
3498 int Ret;
3499 unsigned int Index;
3500 unsigned int Len;
3501 unsigned int Offset;
3502 unsigned int Val;
3503 SK_U8 Val8;
3504 SK_U16 Val16;
3505 SK_U32 Val32;
3506 SK_U64 Val64;
3507 SK_U64 Val64RxHwErrs = 0;
3508 SK_U64 Val64TxHwErrs = 0;
3509 SK_BOOL Is64BitReq = SK_FALSE;
3510 char Buf[256];
3511 int MacType;
3512
3513 /*
3514 * Check instance. We only handle single instance variables.
3515 */
3516 if (Instance != (SK_U32)(-1) && Instance != 1) {
3517
3518 *pLen = 0;
3519 return (SK_PNMI_ERR_UNKNOWN_INST);
3520 }
3521
3522 /*
3523 * Check action. We only allow get requests.
3524 */
3525 if (Action != SK_PNMI_GET) {
3526
3527 *pLen = 0;
3528 return (SK_PNMI_ERR_READ_ONLY);
3529 }
3530
3531 MacType = pAC->GIni.GIMacType;
3532
3533 /*
3534 * Check length for the various supported OIDs
3535 */
3536 switch (Id) {
3537
3538 case OID_GEN_XMIT_ERROR:
3539 case OID_GEN_RCV_ERROR:
3540 case OID_GEN_RCV_NO_BUFFER:
3541#ifndef SK_NDIS_64BIT_CTR
3542 if (*pLen < sizeof(SK_U32)) {
3543 *pLen = sizeof(SK_U32);
3544 return (SK_PNMI_ERR_TOO_SHORT);
3545 }
3546
3547#else /* SK_NDIS_64BIT_CTR */
3548
3549 /*
3550 * for compatibility, at least 32bit are required for oid
3551 */
3552 if (*pLen < sizeof(SK_U32)) {
3553 /*
3554 * but indicate handling for 64bit values,
3555 * if insufficient space is provided
3556 */
3557 *pLen = sizeof(SK_U64);
3558 return (SK_PNMI_ERR_TOO_SHORT);
3559 }
3560
3561 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
3562#endif /* SK_NDIS_64BIT_CTR */
3563 break;
3564
3565 case OID_SKGE_PORT_NUMBER:
3566 case OID_SKGE_DEVICE_TYPE:
3567 case OID_SKGE_RESULT:
3568 case OID_SKGE_RLMT_MONITOR_NUMBER:
3569 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
3570 case OID_SKGE_TRAP_NUMBER:
3571 case OID_SKGE_MDB_VERSION:
3572 case OID_SKGE_BOARDLEVEL:
3573 case OID_SKGE_CHIPID:
3574 case OID_SKGE_RAMSIZE:
3575 if (*pLen < sizeof(SK_U32)) {
3576
3577 *pLen = sizeof(SK_U32);
3578 return (SK_PNMI_ERR_TOO_SHORT);
3579 }
3580 break;
3581
3582 case OID_SKGE_CHIPSET:
3583 if (*pLen < sizeof(SK_U16)) {
3584
3585 *pLen = sizeof(SK_U16);
3586 return (SK_PNMI_ERR_TOO_SHORT);
3587 }
3588 break;
3589
3590 case OID_SKGE_BUS_TYPE:
3591 case OID_SKGE_BUS_SPEED:
3592 case OID_SKGE_BUS_WIDTH:
3593 case OID_SKGE_SENSOR_NUMBER:
3594 case OID_SKGE_CHKSM_NUMBER:
3595 case OID_SKGE_VAUXAVAIL:
3596 if (*pLen < sizeof(SK_U8)) {
3597
3598 *pLen = sizeof(SK_U8);
3599 return (SK_PNMI_ERR_TOO_SHORT);
3600 }
3601 break;
3602
3603 case OID_SKGE_TX_SW_QUEUE_LEN:
3604 case OID_SKGE_TX_SW_QUEUE_MAX:
3605 case OID_SKGE_TX_RETRY:
3606 case OID_SKGE_RX_INTR_CTS:
3607 case OID_SKGE_TX_INTR_CTS:
3608 case OID_SKGE_RX_NO_BUF_CTS:
3609 case OID_SKGE_TX_NO_BUF_CTS:
3610 case OID_SKGE_TX_USED_DESCR_NO:
3611 case OID_SKGE_RX_DELIVERED_CTS:
3612 case OID_SKGE_RX_OCTETS_DELIV_CTS:
3613 case OID_SKGE_RX_HW_ERROR_CTS:
3614 case OID_SKGE_TX_HW_ERROR_CTS:
3615 case OID_SKGE_IN_ERRORS_CTS:
3616 case OID_SKGE_OUT_ERROR_CTS:
3617 case OID_SKGE_ERR_RECOVERY_CTS:
3618 case OID_SKGE_SYSUPTIME:
3619 if (*pLen < sizeof(SK_U64)) {
3620
3621 *pLen = sizeof(SK_U64);
3622 return (SK_PNMI_ERR_TOO_SHORT);
3623 }
3624 break;
3625
3626 default:
3627 /* Checked later */
3628 break;
3629 }
3630
3631 /* Update statistic */
3632 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
3633 Id == OID_SKGE_TX_HW_ERROR_CTS ||
3634 Id == OID_SKGE_IN_ERRORS_CTS ||
3635 Id == OID_SKGE_OUT_ERROR_CTS ||
3636 Id == OID_GEN_XMIT_ERROR ||
3637 Id == OID_GEN_RCV_ERROR) {
3638
3639 /* Force the XMAC to update its statistic counters and
3640 * Increment semaphore to indicate that an update was
3641 * already done.
3642 */
3643 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
3644 if (Ret != SK_PNMI_ERR_OK) {
3645
3646 *pLen = 0;
3647 return (Ret);
3648 }
3649 pAC->Pnmi.MacUpdatedFlag ++;
3650
3651 /*
3652 * Some OIDs consist of multiple hardware counters. Those
3653 * values which are contained in all of them will be added
3654 * now.
3655 */
3656 switch (Id) {
3657
3658 case OID_SKGE_RX_HW_ERROR_CTS:
3659 case OID_SKGE_IN_ERRORS_CTS:
3660 case OID_GEN_RCV_ERROR:
3661 Val64RxHwErrs =
3662 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
3663 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
3664 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex) +
3665 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
3666 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
3667 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex) +
3668 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
3669 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
3670 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
3671 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
3672 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
3673 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
3674 break;
3675
3676 case OID_SKGE_TX_HW_ERROR_CTS:
3677 case OID_SKGE_OUT_ERROR_CTS:
3678 case OID_GEN_XMIT_ERROR:
3679 Val64TxHwErrs =
3680 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
3681 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex) +
3682 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex) +
3683 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex);
3684 break;
3685 }
3686 }
3687
3688 /*
3689 * Retrieve value
3690 */
3691 switch (Id) {
3692
3693 case OID_SKGE_SUPPORTED_LIST:
3694 Len = ID_TABLE_SIZE * sizeof(SK_U32);
3695 if (*pLen < Len) {
3696
3697 *pLen = Len;
3698 return (SK_PNMI_ERR_TOO_SHORT);
3699 }
3700 for (Offset = 0, Index = 0; Offset < Len;
3701 Offset += sizeof(SK_U32), Index ++) {
3702
3703 Val32 = (SK_U32)IdTable[Index].Id;
3704 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3705 }
3706 *pLen = Len;
3707 break;
3708
3709 case OID_SKGE_BOARDLEVEL:
3710 Val32 = (SK_U32)pAC->GIni.GILevel;
3711 SK_PNMI_STORE_U32(pBuf, Val32);
3712 *pLen = sizeof(SK_U32);
3713 break;
3714
3715 case OID_SKGE_PORT_NUMBER:
3716 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
3717 SK_PNMI_STORE_U32(pBuf, Val32);
3718 *pLen = sizeof(SK_U32);
3719 break;
3720
3721 case OID_SKGE_DEVICE_TYPE:
3722 Val32 = (SK_U32)pAC->Pnmi.DeviceType;
3723 SK_PNMI_STORE_U32(pBuf, Val32);
3724 *pLen = sizeof(SK_U32);
3725 break;
3726
3727 case OID_SKGE_DRIVER_DESCR:
3728 if (pAC->Pnmi.pDriverDescription == NULL) {
3729
3730 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
3731 SK_PNMI_ERR007MSG);
3732
3733 *pLen = 0;
3734 return (SK_PNMI_ERR_GENERAL);
3735 }
3736
3737 Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
3738 if (Len > SK_PNMI_STRINGLEN1) {
3739
3740 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
3741 SK_PNMI_ERR029MSG);
3742
3743 *pLen = 0;
3744 return (SK_PNMI_ERR_GENERAL);
3745 }
3746
3747 if (*pLen < Len) {
3748
3749 *pLen = Len;
3750 return (SK_PNMI_ERR_TOO_SHORT);
3751 }
3752 *pBuf = (char)(Len - 1);
3753 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
3754 *pLen = Len;
3755 break;
3756
3757 case OID_SKGE_DRIVER_VERSION:
3758 if (pAC->Pnmi.pDriverVersion == NULL) {
3759
3760 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3761 SK_PNMI_ERR030MSG);
3762
3763 *pLen = 0;
3764 return (SK_PNMI_ERR_GENERAL);
3765 }
3766
3767 Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
3768 if (Len > SK_PNMI_STRINGLEN1) {
3769
3770 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3771 SK_PNMI_ERR031MSG);
3772
3773 *pLen = 0;
3774 return (SK_PNMI_ERR_GENERAL);
3775 }
3776
3777 if (*pLen < Len) {
3778
3779 *pLen = Len;
3780 return (SK_PNMI_ERR_TOO_SHORT);
3781 }
3782 *pBuf = (char)(Len - 1);
3783 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
3784 *pLen = Len;
3785 break;
3786
3787 case OID_SKGE_DRIVER_RELDATE:
3788 if (pAC->Pnmi.pDriverReleaseDate == NULL) {
3789
3790 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3791 SK_PNMI_ERR053MSG);
3792
3793 *pLen = 0;
3794 return (SK_PNMI_ERR_GENERAL);
3795 }
3796
3797 Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1;
3798 if (Len > SK_PNMI_STRINGLEN1) {
3799
3800 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3801 SK_PNMI_ERR054MSG);
3802
3803 *pLen = 0;
3804 return (SK_PNMI_ERR_GENERAL);
3805 }
3806
3807 if (*pLen < Len) {
3808
3809 *pLen = Len;
3810 return (SK_PNMI_ERR_TOO_SHORT);
3811 }
3812 *pBuf = (char)(Len - 1);
3813 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverReleaseDate, Len - 1);
3814 *pLen = Len;
3815 break;
3816
3817 case OID_SKGE_DRIVER_FILENAME:
3818 if (pAC->Pnmi.pDriverFileName == NULL) {
3819
3820 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3821 SK_PNMI_ERR055MSG);
3822
3823 *pLen = 0;
3824 return (SK_PNMI_ERR_GENERAL);
3825 }
3826
3827 Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1;
3828 if (Len > SK_PNMI_STRINGLEN1) {
3829
3830 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3831 SK_PNMI_ERR056MSG);
3832
3833 *pLen = 0;
3834 return (SK_PNMI_ERR_GENERAL);
3835 }
3836
3837 if (*pLen < Len) {
3838
3839 *pLen = Len;
3840 return (SK_PNMI_ERR_TOO_SHORT);
3841 }
3842 *pBuf = (char)(Len - 1);
3843 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverFileName, Len - 1);
3844 *pLen = Len;
3845 break;
3846
3847 case OID_SKGE_HW_DESCR:
3848 /*
3849 * The hardware description is located in the VPD. This
3850 * query may move to the initialisation routine. But
3851 * the VPD data is cached and therefore a call here
3852 * will not make much difference.
3853 */
3854 Len = 256;
3855 if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
3856
3857 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
3858 SK_PNMI_ERR032MSG);
3859
3860 *pLen = 0;
3861 return (SK_PNMI_ERR_GENERAL);
3862 }
3863 Len ++;
3864 if (Len > SK_PNMI_STRINGLEN1) {
3865
3866 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
3867 SK_PNMI_ERR033MSG);
3868
3869 *pLen = 0;
3870 return (SK_PNMI_ERR_GENERAL);
3871 }
3872 if (*pLen < Len) {
3873
3874 *pLen = Len;
3875 return (SK_PNMI_ERR_TOO_SHORT);
3876 }
3877 *pBuf = (char)(Len - 1);
3878 SK_MEMCPY(pBuf + 1, Buf, Len - 1);
3879 *pLen = Len;
3880 break;
3881
3882 case OID_SKGE_HW_VERSION:
3883 /* Oh, I love to do some string manipulation */
3884 if (*pLen < 5) {
3885
3886 *pLen = 5;
3887 return (SK_PNMI_ERR_TOO_SHORT);
3888 }
3889 Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
3890 pBuf[0] = 4;
3891 pBuf[1] = 'v';
3892 pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
3893 pBuf[3] = '.';
3894 pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
3895 *pLen = 5;
3896 break;
3897
3898 case OID_SKGE_CHIPSET:
3899 Val16 = pAC->Pnmi.Chipset;
3900 SK_PNMI_STORE_U16(pBuf, Val16);
3901 *pLen = sizeof(SK_U16);
3902 break;
3903
3904 case OID_SKGE_CHIPID:
3905 Val32 = pAC->GIni.GIChipId;
3906 SK_PNMI_STORE_U32(pBuf, Val32);
3907 *pLen = sizeof(SK_U32);
3908 break;
3909
3910 case OID_SKGE_RAMSIZE:
3911 Val32 = pAC->GIni.GIRamSize;
3912 SK_PNMI_STORE_U32(pBuf, Val32);
3913 *pLen = sizeof(SK_U32);
3914 break;
3915
3916 case OID_SKGE_VAUXAVAIL:
3917 *pBuf = (char) pAC->GIni.GIVauxAvail;
3918 *pLen = sizeof(char);
3919 break;
3920
3921 case OID_SKGE_BUS_TYPE:
3922 *pBuf = (char) SK_PNMI_BUS_PCI;
3923 *pLen = sizeof(char);
3924 break;
3925
3926 case OID_SKGE_BUS_SPEED:
3927 *pBuf = pAC->Pnmi.PciBusSpeed;
3928 *pLen = sizeof(char);
3929 break;
3930
3931 case OID_SKGE_BUS_WIDTH:
3932 *pBuf = pAC->Pnmi.PciBusWidth;
3933 *pLen = sizeof(char);
3934 break;
3935
3936 case OID_SKGE_RESULT:
3937 Val32 = pAC->Pnmi.TestResult;
3938 SK_PNMI_STORE_U32(pBuf, Val32);
3939 *pLen = sizeof(SK_U32);
3940 break;
3941
3942 case OID_SKGE_SENSOR_NUMBER:
3943 *pBuf = (char)pAC->I2c.MaxSens;
3944 *pLen = sizeof(char);
3945 break;
3946
3947 case OID_SKGE_CHKSM_NUMBER:
3948 *pBuf = SKCS_NUM_PROTOCOLS;
3949 *pLen = sizeof(char);
3950 break;
3951
3952 case OID_SKGE_TRAP_NUMBER:
3953 GetTrapQueueLen(pAC, &Len, &Val);
3954 Val32 = (SK_U32)Val;
3955 SK_PNMI_STORE_U32(pBuf, Val32);
3956 *pLen = sizeof(SK_U32);
3957 break;
3958
3959 case OID_SKGE_TRAP:
3960 GetTrapQueueLen(pAC, &Len, &Val);
3961 if (*pLen < Len) {
3962
3963 *pLen = Len;
3964 return (SK_PNMI_ERR_TOO_SHORT);
3965 }
3966 CopyTrapQueue(pAC, pBuf);
3967 *pLen = Len;
3968 break;
3969
3970 case OID_SKGE_RLMT_MONITOR_NUMBER:
3971/* XXX Not yet implemented by RLMT therefore we return zero elements */
3972 Val32 = 0;
3973 SK_PNMI_STORE_U32(pBuf, Val32);
3974 *pLen = sizeof(SK_U32);
3975 break;
3976
3977 case OID_SKGE_TX_SW_QUEUE_LEN:
3978 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
3979 if (MacType == SK_MAC_XMAC) {
3980 /* Dual net mode */
3981 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
3982 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
3983 }
3984 /* Single net mode */
3985 else {
3986 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
3987 pAC->Pnmi.BufPort[1].TxSwQueueLen;
3988 }
3989 }
3990 else {
3991 /* Dual net mode */
3992 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
3993 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
3994 }
3995 /* Single net mode */
3996 else {
3997 Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
3998 pAC->Pnmi.Port[1].TxSwQueueLen;
3999 }
4000 }
4001 SK_PNMI_STORE_U64(pBuf, Val64);
4002 *pLen = sizeof(SK_U64);
4003 break;
4004
4005
4006 case OID_SKGE_TX_SW_QUEUE_MAX:
4007 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4008 if (MacType == SK_MAC_XMAC) {
4009 /* Dual net mode */
4010 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4011 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
4012 }
4013 /* Single net mode */
4014 else {
4015 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
4016 pAC->Pnmi.BufPort[1].TxSwQueueMax;
4017 }
4018 }
4019 else {
4020 /* Dual net mode */
4021 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4022 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
4023 }
4024 /* Single net mode */
4025 else {
4026 Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
4027 pAC->Pnmi.Port[1].TxSwQueueMax;
4028 }
4029 }
4030 SK_PNMI_STORE_U64(pBuf, Val64);
4031 *pLen = sizeof(SK_U64);
4032 break;
4033
4034 case OID_SKGE_TX_RETRY:
4035 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4036 if (MacType == SK_MAC_XMAC) {
4037 /* Dual net mode */
4038 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4039 Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
4040 }
4041 /* Single net mode */
4042 else {
4043 Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
4044 pAC->Pnmi.BufPort[1].TxRetryCts;
4045 }
4046 }
4047 else {
4048 /* Dual net mode */
4049 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4050 Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
4051 }
4052 /* Single net mode */
4053 else {
4054 Val64 = pAC->Pnmi.Port[0].TxRetryCts +
4055 pAC->Pnmi.Port[1].TxRetryCts;
4056 }
4057 }
4058 SK_PNMI_STORE_U64(pBuf, Val64);
4059 *pLen = sizeof(SK_U64);
4060 break;
4061
4062 case OID_SKGE_RX_INTR_CTS:
4063 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4064 if (MacType == SK_MAC_XMAC) {
4065 /* Dual net mode */
4066 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4067 Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
4068 }
4069 /* Single net mode */
4070 else {
4071 Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
4072 pAC->Pnmi.BufPort[1].RxIntrCts;
4073 }
4074 }
4075 else {
4076 /* Dual net mode */
4077 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4078 Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
4079 }
4080 /* Single net mode */
4081 else {
4082 Val64 = pAC->Pnmi.Port[0].RxIntrCts +
4083 pAC->Pnmi.Port[1].RxIntrCts;
4084 }
4085 }
4086 SK_PNMI_STORE_U64(pBuf, Val64);
4087 *pLen = sizeof(SK_U64);
4088 break;
4089
4090 case OID_SKGE_TX_INTR_CTS:
4091 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4092 if (MacType == SK_MAC_XMAC) {
4093 /* Dual net mode */
4094 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4095 Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
4096 }
4097 /* Single net mode */
4098 else {
4099 Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
4100 pAC->Pnmi.BufPort[1].TxIntrCts;
4101 }
4102 }
4103 else {
4104 /* Dual net mode */
4105 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4106 Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
4107 }
4108 /* Single net mode */
4109 else {
4110 Val64 = pAC->Pnmi.Port[0].TxIntrCts +
4111 pAC->Pnmi.Port[1].TxIntrCts;
4112 }
4113 }
4114 SK_PNMI_STORE_U64(pBuf, Val64);
4115 *pLen = sizeof(SK_U64);
4116 break;
4117
4118 case OID_SKGE_RX_NO_BUF_CTS:
4119 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4120 if (MacType == SK_MAC_XMAC) {
4121 /* Dual net mode */
4122 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4123 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4124 }
4125 /* Single net mode */
4126 else {
4127 Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
4128 pAC->Pnmi.BufPort[1].RxNoBufCts;
4129 }
4130 }
4131 else {
4132 /* Dual net mode */
4133 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4134 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4135 }
4136 /* Single net mode */
4137 else {
4138 Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
4139 pAC->Pnmi.Port[1].RxNoBufCts;
4140 }
4141 }
4142 SK_PNMI_STORE_U64(pBuf, Val64);
4143 *pLen = sizeof(SK_U64);
4144 break;
4145
4146 case OID_SKGE_TX_NO_BUF_CTS:
4147 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4148 if (MacType == SK_MAC_XMAC) {
4149 /* Dual net mode */
4150 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4151 Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4152 }
4153 /* Single net mode */
4154 else {
4155 Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
4156 pAC->Pnmi.BufPort[1].TxNoBufCts;
4157 }
4158 }
4159 else {
4160 /* Dual net mode */
4161 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4162 Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4163 }
4164 /* Single net mode */
4165 else {
4166 Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
4167 pAC->Pnmi.Port[1].TxNoBufCts;
4168 }
4169 }
4170 SK_PNMI_STORE_U64(pBuf, Val64);
4171 *pLen = sizeof(SK_U64);
4172 break;
4173
4174 case OID_SKGE_TX_USED_DESCR_NO:
4175 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4176 if (MacType == SK_MAC_XMAC) {
4177 /* Dual net mode */
4178 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4179 Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
4180 }
4181 /* Single net mode */
4182 else {
4183 Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
4184 pAC->Pnmi.BufPort[1].TxUsedDescrNo;
4185 }
4186 }
4187 else {
4188 /* Dual net mode */
4189 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4190 Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
4191 }
4192 /* Single net mode */
4193 else {
4194 Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
4195 pAC->Pnmi.Port[1].TxUsedDescrNo;
4196 }
4197 }
4198 SK_PNMI_STORE_U64(pBuf, Val64);
4199 *pLen = sizeof(SK_U64);
4200 break;
4201
4202 case OID_SKGE_RX_DELIVERED_CTS:
4203 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4204 if (MacType == SK_MAC_XMAC) {
4205 /* Dual net mode */
4206 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4207 Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
4208 }
4209 /* Single net mode */
4210 else {
4211 Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
4212 pAC->Pnmi.BufPort[1].RxDeliveredCts;
4213 }
4214 }
4215 else {
4216 /* Dual net mode */
4217 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4218 Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
4219 }
4220 /* Single net mode */
4221 else {
4222 Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
4223 pAC->Pnmi.Port[1].RxDeliveredCts;
4224 }
4225 }
4226 SK_PNMI_STORE_U64(pBuf, Val64);
4227 *pLen = sizeof(SK_U64);
4228 break;
4229
4230 case OID_SKGE_RX_OCTETS_DELIV_CTS:
4231 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4232 if (MacType == SK_MAC_XMAC) {
4233 /* Dual net mode */
4234 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4235 Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
4236 }
4237 /* Single net mode */
4238 else {
4239 Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
4240 pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
4241 }
4242 }
4243 else {
4244 /* Dual net mode */
4245 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4246 Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
4247 }
4248 /* Single net mode */
4249 else {
4250 Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
4251 pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
4252 }
4253 }
4254 SK_PNMI_STORE_U64(pBuf, Val64);
4255 *pLen = sizeof(SK_U64);
4256 break;
4257
4258 case OID_SKGE_RX_HW_ERROR_CTS:
4259 SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
4260 *pLen = sizeof(SK_U64);
4261 break;
4262
4263 case OID_SKGE_TX_HW_ERROR_CTS:
4264 SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
4265 *pLen = sizeof(SK_U64);
4266 break;
4267
4268 case OID_SKGE_IN_ERRORS_CTS:
4269 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4270 if (MacType == SK_MAC_XMAC) {
4271 /* Dual net mode */
4272 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4273 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4274 }
4275 /* Single net mode */
4276 else {
4277 Val64 = Val64RxHwErrs +
4278 pAC->Pnmi.BufPort[0].RxNoBufCts +
4279 pAC->Pnmi.BufPort[1].RxNoBufCts;
4280 }
4281 }
4282 else {
4283 /* Dual net mode */
4284 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4285 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4286 }
4287 /* Single net mode */
4288 else {
4289 Val64 = Val64RxHwErrs +
4290 pAC->Pnmi.Port[0].RxNoBufCts +
4291 pAC->Pnmi.Port[1].RxNoBufCts;
4292 }
4293 }
4294 SK_PNMI_STORE_U64(pBuf, Val64);
4295 *pLen = sizeof(SK_U64);
4296 break;
4297
4298 case OID_SKGE_OUT_ERROR_CTS:
4299 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4300 if (MacType == SK_MAC_XMAC) {
4301 /* Dual net mode */
4302 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4303 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4304 }
4305 /* Single net mode */
4306 else {
4307 Val64 = Val64TxHwErrs +
4308 pAC->Pnmi.BufPort[0].TxNoBufCts +
4309 pAC->Pnmi.BufPort[1].TxNoBufCts;
4310 }
4311 }
4312 else {
4313 /* Dual net mode */
4314 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4315 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4316 }
4317 /* Single net mode */
4318 else {
4319 Val64 = Val64TxHwErrs +
4320 pAC->Pnmi.Port[0].TxNoBufCts +
4321 pAC->Pnmi.Port[1].TxNoBufCts;
4322 }
4323 }
4324 SK_PNMI_STORE_U64(pBuf, Val64);
4325 *pLen = sizeof(SK_U64);
4326 break;
4327
4328 case OID_SKGE_ERR_RECOVERY_CTS:
4329 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4330 if (MacType == SK_MAC_XMAC) {
4331 /* Dual net mode */
4332 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4333 Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
4334 }
4335 /* Single net mode */
4336 else {
4337 Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
4338 pAC->Pnmi.BufPort[1].ErrRecoveryCts;
4339 }
4340 }
4341 else {
4342 /* Dual net mode */
4343 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4344 Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
4345 }
4346 /* Single net mode */
4347 else {
4348 Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
4349 pAC->Pnmi.Port[1].ErrRecoveryCts;
4350 }
4351 }
4352 SK_PNMI_STORE_U64(pBuf, Val64);
4353 *pLen = sizeof(SK_U64);
4354 break;
4355
4356 case OID_SKGE_SYSUPTIME:
4357 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
4358 Val64 -= pAC->Pnmi.StartUpTime;
4359 SK_PNMI_STORE_U64(pBuf, Val64);
4360 *pLen = sizeof(SK_U64);
4361 break;
4362
4363 case OID_SKGE_MDB_VERSION:
4364 Val32 = SK_PNMI_MDB_VERSION;
4365 SK_PNMI_STORE_U32(pBuf, Val32);
4366 *pLen = sizeof(SK_U32);
4367 break;
4368
4369 case OID_GEN_RCV_ERROR:
4370 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4371 if (MacType == SK_MAC_XMAC) {
4372 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4373 }
4374 else {
4375 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4376 }
4377
4378 /*
4379 * by default 32bit values are evaluated
4380 */
4381 if (!Is64BitReq) {
4382 Val32 = (SK_U32)Val64;
4383 SK_PNMI_STORE_U32(pBuf, Val32);
4384 *pLen = sizeof(SK_U32);
4385 }
4386 else {
4387 SK_PNMI_STORE_U64(pBuf, Val64);
4388 *pLen = sizeof(SK_U64);
4389 }
4390 break;
4391
4392 case OID_GEN_XMIT_ERROR:
4393 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4394 if (MacType == SK_MAC_XMAC) {
4395 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4396 }
4397 else {
4398 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4399 }
4400
4401 /*
4402 * by default 32bit values are evaluated
4403 */
4404 if (!Is64BitReq) {
4405 Val32 = (SK_U32)Val64;
4406 SK_PNMI_STORE_U32(pBuf, Val32);
4407 *pLen = sizeof(SK_U32);
4408 }
4409 else {
4410 SK_PNMI_STORE_U64(pBuf, Val64);
4411 *pLen = sizeof(SK_U64);
4412 }
4413 break;
4414
4415 case OID_GEN_RCV_NO_BUFFER:
4416 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4417 if (MacType == SK_MAC_XMAC) {
4418 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4419 }
4420 else {
4421 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4422 }
4423
4424 /*
4425 * by default 32bit values are evaluated
4426 */
4427 if (!Is64BitReq) {
4428 Val32 = (SK_U32)Val64;
4429 SK_PNMI_STORE_U32(pBuf, Val32);
4430 *pLen = sizeof(SK_U32);
4431 }
4432 else {
4433 SK_PNMI_STORE_U64(pBuf, Val64);
4434 *pLen = sizeof(SK_U64);
4435 }
4436 break;
4437
4438 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
4439 Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
4440 SK_PNMI_STORE_U32(pBuf, Val32);
4441 *pLen = sizeof(SK_U32);
4442 break;
4443
4444 default:
4445 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
4446 SK_PNMI_ERR034MSG);
4447
4448 *pLen = 0;
4449 return (SK_PNMI_ERR_GENERAL);
4450 }
4451
4452 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
4453 Id == OID_SKGE_TX_HW_ERROR_CTS ||
4454 Id == OID_SKGE_IN_ERRORS_CTS ||
4455 Id == OID_SKGE_OUT_ERROR_CTS ||
4456 Id == OID_GEN_XMIT_ERROR ||
4457 Id == OID_GEN_RCV_ERROR) {
4458
4459 pAC->Pnmi.MacUpdatedFlag --;
4460 }
4461
4462 return (SK_PNMI_ERR_OK);
4463}
4464
4465/*****************************************************************************
4466 *
4467 * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
4468 *
4469 * Description:
4470 * Get/Presets/Sets the RLMT OIDs.
4471 *
4472 * Returns:
4473 * SK_PNMI_ERR_OK The request was successfully performed.
4474 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4475 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4476 * the correct data (e.g. a 32bit value is
4477 * needed, but a 16 bit value was passed).
4478 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
4479 * value range.
4480 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
4481 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4482 * exist (e.g. port instance 3 on a two port
4483 * adapter.
4484 */
4485PNMI_STATIC int Rlmt(
4486SK_AC *pAC, /* Pointer to adapter context */
4487SK_IOC IoC, /* IO context handle */
4488int Action, /* GET/PRESET/SET action */
4489SK_U32 Id, /* Object ID that is to be processed */
4490char *pBuf, /* Buffer used for the management data transfer */
4491unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4492SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4493unsigned int TableIndex, /* Index to the Id table */
4494SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
4495{
4496 int Ret;
4497 unsigned int PhysPortIndex;
4498 unsigned int PhysPortMax;
4499 SK_EVPARA EventParam;
4500 SK_U32 Val32;
4501 SK_U64 Val64;
4502
4503
4504 /*
4505 * Check instance. Only single instance OIDs are allowed here.
4506 */
4507 if (Instance != (SK_U32)(-1) && Instance != 1) {
4508
4509 *pLen = 0;
4510 return (SK_PNMI_ERR_UNKNOWN_INST);
4511 }
4512
4513 /*
4514 * Perform the requested action.
4515 */
4516 if (Action == SK_PNMI_GET) {
4517
4518 /*
4519 * Check if the buffer length is large enough.
4520 */
4521
4522 switch (Id) {
4523
4524 case OID_SKGE_RLMT_MODE:
4525 case OID_SKGE_RLMT_PORT_ACTIVE:
4526 case OID_SKGE_RLMT_PORT_PREFERRED:
4527 if (*pLen < sizeof(SK_U8)) {
4528
4529 *pLen = sizeof(SK_U8);
4530 return (SK_PNMI_ERR_TOO_SHORT);
4531 }
4532 break;
4533
4534 case OID_SKGE_RLMT_PORT_NUMBER:
4535 if (*pLen < sizeof(SK_U32)) {
4536
4537 *pLen = sizeof(SK_U32);
4538 return (SK_PNMI_ERR_TOO_SHORT);
4539 }
4540 break;
4541
4542 case OID_SKGE_RLMT_CHANGE_CTS:
4543 case OID_SKGE_RLMT_CHANGE_TIME:
4544 case OID_SKGE_RLMT_CHANGE_ESTIM:
4545 case OID_SKGE_RLMT_CHANGE_THRES:
4546 if (*pLen < sizeof(SK_U64)) {
4547
4548 *pLen = sizeof(SK_U64);
4549 return (SK_PNMI_ERR_TOO_SHORT);
4550 }
4551 break;
4552
4553 default:
4554 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
4555 SK_PNMI_ERR035MSG);
4556
4557 *pLen = 0;
4558 return (SK_PNMI_ERR_GENERAL);
4559 }
4560
4561 /*
4562 * Update RLMT statistic and increment semaphores to indicate
4563 * that an update was already done. Maybe RLMT will hold its
4564 * statistic always up to date some time. Then we can
4565 * remove this type of call.
4566 */
4567 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4568
4569 *pLen = 0;
4570 return (Ret);
4571 }
4572 pAC->Pnmi.RlmtUpdatedFlag ++;
4573
4574 /*
4575 * Retrieve Value
4576 */
4577 switch (Id) {
4578
4579 case OID_SKGE_RLMT_MODE:
4580 *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
4581 *pLen = sizeof(char);
4582 break;
4583
4584 case OID_SKGE_RLMT_PORT_NUMBER:
4585 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
4586 SK_PNMI_STORE_U32(pBuf, Val32);
4587 *pLen = sizeof(SK_U32);
4588 break;
4589
4590 case OID_SKGE_RLMT_PORT_ACTIVE:
4591 *pBuf = 0;
4592 /*
4593 * If multiple ports may become active this OID
4594 * doesn't make sense any more. A new variable in
4595 * the port structure should be created. However,
4596 * for this variable the first active port is
4597 * returned.
4598 */
4599 PhysPortMax = pAC->GIni.GIMacsFound;
4600
4601 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
4602 PhysPortIndex ++) {
4603
4604 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4605
4606 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
4607 break;
4608 }
4609 }
4610 *pLen = sizeof(char);
4611 break;
4612
4613 case OID_SKGE_RLMT_PORT_PREFERRED:
4614 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
4615 *pLen = sizeof(char);
4616 break;
4617
4618 case OID_SKGE_RLMT_CHANGE_CTS:
4619 Val64 = pAC->Pnmi.RlmtChangeCts;
4620 SK_PNMI_STORE_U64(pBuf, Val64);
4621 *pLen = sizeof(SK_U64);
4622 break;
4623
4624 case OID_SKGE_RLMT_CHANGE_TIME:
4625 Val64 = pAC->Pnmi.RlmtChangeTime;
4626 SK_PNMI_STORE_U64(pBuf, Val64);
4627 *pLen = sizeof(SK_U64);
4628 break;
4629
4630 case OID_SKGE_RLMT_CHANGE_ESTIM:
4631 Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
4632 SK_PNMI_STORE_U64(pBuf, Val64);
4633 *pLen = sizeof(SK_U64);
4634 break;
4635
4636 case OID_SKGE_RLMT_CHANGE_THRES:
4637 Val64 = pAC->Pnmi.RlmtChangeThreshold;
4638 SK_PNMI_STORE_U64(pBuf, Val64);
4639 *pLen = sizeof(SK_U64);
4640 break;
4641
4642 default:
4643 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
4644 ("Rlmt: Unknown OID should be handled before"));
4645
4646 pAC->Pnmi.RlmtUpdatedFlag --;
4647 *pLen = 0;
4648 return (SK_PNMI_ERR_GENERAL);
4649 }
4650
4651 pAC->Pnmi.RlmtUpdatedFlag --;
4652 }
4653 else {
4654 /* Perform a preset or set */
4655 switch (Id) {
4656
4657 case OID_SKGE_RLMT_MODE:
4658 /* Check if the buffer length is plausible */
4659 if (*pLen < sizeof(char)) {
4660
4661 *pLen = sizeof(char);
4662 return (SK_PNMI_ERR_TOO_SHORT);
4663 }
4664 /* Check if the value range is correct */
4665 if (*pLen != sizeof(char) ||
4666 (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
4667 *(SK_U8 *)pBuf > 15) {
4668
4669 *pLen = 0;
4670 return (SK_PNMI_ERR_BAD_VALUE);
4671 }
4672 /* The preset ends here */
4673 if (Action == SK_PNMI_PRESET) {
4674
4675 *pLen = 0;
4676 return (SK_PNMI_ERR_OK);
4677 }
4678 /* Send an event to RLMT to change the mode */
4679 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
4680 EventParam.Para32[0] |= (SK_U32)(*pBuf);
4681 EventParam.Para32[1] = 0;
4682 if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
4683 EventParam) > 0) {
4684
4685 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
4686 SK_PNMI_ERR037MSG);
4687
4688 *pLen = 0;
4689 return (SK_PNMI_ERR_GENERAL);
4690 }
4691 break;
4692
4693 case OID_SKGE_RLMT_PORT_PREFERRED:
4694 /* Check if the buffer length is plausible */
4695 if (*pLen < sizeof(char)) {
4696
4697 *pLen = sizeof(char);
4698 return (SK_PNMI_ERR_TOO_SHORT);
4699 }
4700 /* Check if the value range is correct */
4701 if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
4702 (SK_U8)pAC->GIni.GIMacsFound) {
4703
4704 *pLen = 0;
4705 return (SK_PNMI_ERR_BAD_VALUE);
4706 }
4707 /* The preset ends here */
4708 if (Action == SK_PNMI_PRESET) {
4709
4710 *pLen = 0;
4711 return (SK_PNMI_ERR_OK);
4712 }
4713
4714 /*
4715 * Send an event to RLMT change the preferred port.
4716 * A param of -1 means automatic mode. RLMT will
4717 * make the decision which is the preferred port.
4718 */
4719 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
4720 EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
4721 EventParam.Para32[1] = NetIndex;
4722 if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
4723 EventParam) > 0) {
4724
4725 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
4726 SK_PNMI_ERR038MSG);
4727
4728 *pLen = 0;
4729 return (SK_PNMI_ERR_GENERAL);
4730 }
4731 break;
4732
4733 case OID_SKGE_RLMT_CHANGE_THRES:
4734 /* Check if the buffer length is plausible */
4735 if (*pLen < sizeof(SK_U64)) {
4736
4737 *pLen = sizeof(SK_U64);
4738 return (SK_PNMI_ERR_TOO_SHORT);
4739 }
4740 /*
4741 * There are not many restrictions to the
4742 * value range.
4743 */
4744 if (*pLen != sizeof(SK_U64)) {
4745
4746 *pLen = 0;
4747 return (SK_PNMI_ERR_BAD_VALUE);
4748 }
4749 /* A preset ends here */
4750 if (Action == SK_PNMI_PRESET) {
4751
4752 *pLen = 0;
4753 return (SK_PNMI_ERR_OK);
4754 }
4755 /*
4756 * Store the new threshold, which will be taken
4757 * on the next timer event.
4758 */
4759 SK_PNMI_READ_U64(pBuf, Val64);
4760 pAC->Pnmi.RlmtChangeThreshold = Val64;
4761 break;
4762
4763 default:
4764 /* The other OIDs are not be able for set */
4765 *pLen = 0;
4766 return (SK_PNMI_ERR_READ_ONLY);
4767 }
4768 }
4769
4770 return (SK_PNMI_ERR_OK);
4771}
4772
4773/*****************************************************************************
4774 *
4775 * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
4776 *
4777 * Description:
4778 * Performs get requests on multiple instance variables.
4779 *
4780 * Returns:
4781 * SK_PNMI_ERR_OK The request was successfully performed.
4782 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4783 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4784 * the correct data (e.g. a 32bit value is
4785 * needed, but a 16 bit value was passed).
4786 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4787 * exist (e.g. port instance 3 on a two port
4788 * adapter.
4789 */
4790PNMI_STATIC int RlmtStat(
4791SK_AC *pAC, /* Pointer to adapter context */
4792SK_IOC IoC, /* IO context handle */
4793int Action, /* GET/PRESET/SET action */
4794SK_U32 Id, /* Object ID that is to be processed */
4795char *pBuf, /* Buffer used for the management data transfer */
4796unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4797SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4798unsigned int TableIndex, /* Index to the Id table */
4799SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
4800{
4801 unsigned int PhysPortMax;
4802 unsigned int PhysPortIndex;
4803 unsigned int Limit;
4804 unsigned int Offset;
4805 int Ret;
4806 SK_U32 Val32;
4807 SK_U64 Val64;
4808
4809 /*
4810 * Calculate the port indexes from the instance.
4811 */
4812 PhysPortMax = pAC->GIni.GIMacsFound;
4813
4814 if ((Instance != (SK_U32)(-1))) {
4815 /* Check instance range */
4816 if ((Instance < 1) || (Instance > PhysPortMax)) {
4817
4818 *pLen = 0;
4819 return (SK_PNMI_ERR_UNKNOWN_INST);
4820 }
4821
4822 /* Single net mode */
4823 PhysPortIndex = Instance - 1;
4824
4825 /* Dual net mode */
4826 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4827 PhysPortIndex = NetIndex;
4828 }
4829
4830 /* Both net modes */
4831 Limit = PhysPortIndex + 1;
4832 }
4833 else {
4834 /* Single net mode */
4835 PhysPortIndex = 0;
4836 Limit = PhysPortMax;
4837
4838 /* Dual net mode */
4839 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4840 PhysPortIndex = NetIndex;
4841 Limit = PhysPortIndex + 1;
4842 }
4843 }
4844
4845 /*
4846 * Currently only get requests are allowed.
4847 */
4848 if (Action != SK_PNMI_GET) {
4849
4850 *pLen = 0;
4851 return (SK_PNMI_ERR_READ_ONLY);
4852 }
4853
4854 /*
4855 * Check if the buffer length is large enough.
4856 */
4857 switch (Id) {
4858
4859 case OID_SKGE_RLMT_PORT_INDEX:
4860 case OID_SKGE_RLMT_STATUS:
4861 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
4862
4863 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
4864 return (SK_PNMI_ERR_TOO_SHORT);
4865 }
4866 break;
4867
4868 case OID_SKGE_RLMT_TX_HELLO_CTS:
4869 case OID_SKGE_RLMT_RX_HELLO_CTS:
4870 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
4871 case OID_SKGE_RLMT_RX_SP_CTS:
4872 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
4873
4874 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
4875 return (SK_PNMI_ERR_TOO_SHORT);
4876 }
4877 break;
4878
4879 default:
4880 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
4881 SK_PNMI_ERR039MSG);
4882
4883 *pLen = 0;
4884 return (SK_PNMI_ERR_GENERAL);
4885
4886 }
4887
4888 /*
4889 * Update statistic and increment semaphores to indicate that
4890 * an update was already done.
4891 */
4892 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4893
4894 *pLen = 0;
4895 return (Ret);
4896 }
4897 pAC->Pnmi.RlmtUpdatedFlag ++;
4898
4899 /*
4900 * Get value
4901 */
4902 Offset = 0;
4903 for (; PhysPortIndex < Limit; PhysPortIndex ++) {
4904
4905 switch (Id) {
4906
4907 case OID_SKGE_RLMT_PORT_INDEX:
4908 Val32 = PhysPortIndex;
4909 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4910 Offset += sizeof(SK_U32);
4911 break;
4912
4913 case OID_SKGE_RLMT_STATUS:
4914 if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
4915 SK_RLMT_PS_INIT ||
4916 pAC->Rlmt.Port[PhysPortIndex].PortState ==
4917 SK_RLMT_PS_DOWN) {
4918
4919 Val32 = SK_PNMI_RLMT_STATUS_ERROR;
4920 }
4921 else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4922
4923 Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
4924 }
4925 else {
4926 Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
4927 }
4928 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4929 Offset += sizeof(SK_U32);
4930 break;
4931
4932 case OID_SKGE_RLMT_TX_HELLO_CTS:
4933 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
4934 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4935 Offset += sizeof(SK_U64);
4936 break;
4937
4938 case OID_SKGE_RLMT_RX_HELLO_CTS:
4939 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
4940 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4941 Offset += sizeof(SK_U64);
4942 break;
4943
4944 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
4945 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
4946 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4947 Offset += sizeof(SK_U64);
4948 break;
4949
4950 case OID_SKGE_RLMT_RX_SP_CTS:
4951 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
4952 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4953 Offset += sizeof(SK_U64);
4954 break;
4955
4956 default:
4957 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
4958 ("RlmtStat: Unknown OID should be errored before"));
4959
4960 pAC->Pnmi.RlmtUpdatedFlag --;
4961 *pLen = 0;
4962 return (SK_PNMI_ERR_GENERAL);
4963 }
4964 }
4965 *pLen = Offset;
4966
4967 pAC->Pnmi.RlmtUpdatedFlag --;
4968
4969 return (SK_PNMI_ERR_OK);
4970}
4971
4972/*****************************************************************************
4973 *
4974 * MacPrivateConf - OID handler function of OIDs concerning the configuration
4975 *
4976 * Description:
4977 * Get/Presets/Sets the OIDs concerning the configuration.
4978 *
4979 * Returns:
4980 * SK_PNMI_ERR_OK The request was successfully performed.
4981 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4982 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4983 * the correct data (e.g. a 32bit value is
4984 * needed, but a 16 bit value was passed).
4985 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
4986 * value range.
4987 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
4988 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4989 * exist (e.g. port instance 3 on a two port
4990 * adapter.
4991 */
4992PNMI_STATIC int MacPrivateConf(
4993SK_AC *pAC, /* Pointer to adapter context */
4994SK_IOC IoC, /* IO context handle */
4995int Action, /* GET/PRESET/SET action */
4996SK_U32 Id, /* Object ID that is to be processed */
4997char *pBuf, /* Buffer used for the management data transfer */
4998unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4999SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5000unsigned int TableIndex, /* Index to the Id table */
5001SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
5002{
5003 unsigned int PhysPortMax;
5004 unsigned int PhysPortIndex;
5005 unsigned int LogPortMax;
5006 unsigned int LogPortIndex;
5007 unsigned int Limit;
5008 unsigned int Offset;
5009 char Val8;
5010 char *pBufPtr;
5011 int Ret;
5012 SK_EVPARA EventParam;
5013 SK_U32 Val32;
5014
5015 /*
5016 * Calculate instance if wished. MAC index 0 is the virtual MAC.
5017 */
5018 PhysPortMax = pAC->GIni.GIMacsFound;
5019 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
5020
5021 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
5022 LogPortMax--;
5023 }
5024
5025 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
5026 /* Check instance range */
5027 if ((Instance < 1) || (Instance > LogPortMax)) {
5028
5029 *pLen = 0;
5030 return (SK_PNMI_ERR_UNKNOWN_INST);
5031 }
5032 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
5033 Limit = LogPortIndex + 1;
5034 }
5035
5036 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
5037
5038 LogPortIndex = 0;
5039 Limit = LogPortMax;
5040 }
5041
5042 /*
5043 * Perform action
5044 */
5045 if (Action == SK_PNMI_GET) {
5046
5047 /* Check length */
5048 switch (Id) {
5049
5050 case OID_SKGE_PMD:
5051 case OID_SKGE_CONNECTOR:
5052 case OID_SKGE_LINK_CAP:
5053 case OID_SKGE_LINK_MODE:
5054 case OID_SKGE_LINK_MODE_STATUS:
5055 case OID_SKGE_LINK_STATUS:
5056 case OID_SKGE_FLOWCTRL_CAP:
5057 case OID_SKGE_FLOWCTRL_MODE:
5058 case OID_SKGE_FLOWCTRL_STATUS:
5059 case OID_SKGE_PHY_OPERATION_CAP:
5060 case OID_SKGE_PHY_OPERATION_MODE:
5061 case OID_SKGE_PHY_OPERATION_STATUS:
5062 case OID_SKGE_SPEED_CAP:
5063 case OID_SKGE_SPEED_MODE:
5064 case OID_SKGE_SPEED_STATUS:
5065#ifdef SK_PHY_LP_MODE
5066 case OID_SKGE_PHY_LP_MODE:
5067#endif
5068 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
5069
5070 *pLen = (Limit - LogPortIndex) * sizeof(SK_U8);
5071 return (SK_PNMI_ERR_TOO_SHORT);
5072 }
5073 break;
5074
5075 case OID_SKGE_MTU:
5076 case OID_SKGE_PHY_TYPE:
5077 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) {
5078
5079 *pLen = (Limit - LogPortIndex) * sizeof(SK_U32);
5080 return (SK_PNMI_ERR_TOO_SHORT);
5081 }
5082 break;
5083
5084 default:
5085 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
5086 SK_PNMI_ERR041MSG);
5087 *pLen = 0;
5088 return (SK_PNMI_ERR_GENERAL);
5089 }
5090
5091 /*
5092 * Update statistic and increment semaphore to indicate
5093 * that an update was already done.
5094 */
5095 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
5096
5097 *pLen = 0;
5098 return (Ret);
5099 }
5100 pAC->Pnmi.SirqUpdatedFlag ++;
5101
5102 /*
5103 * Get value
5104 */
5105 Offset = 0;
5106 for (; LogPortIndex < Limit; LogPortIndex ++) {
5107
5108 pBufPtr = pBuf + Offset;
5109
5110 switch (Id) {
5111
5112 case OID_SKGE_PMD:
5113 *pBufPtr = pAC->Pnmi.PMD;
5114 Offset += sizeof(char);
5115 break;
5116
5117 case OID_SKGE_CONNECTOR:
5118 *pBufPtr = pAC->Pnmi.Connector;
5119 Offset += sizeof(char);
5120 break;
5121
5122 case OID_SKGE_PHY_TYPE:
5123 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5124 if (LogPortIndex == 0) {
5125 continue;
5126 }
5127 else {
5128 /* Get value for physical ports */
5129 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5130 pAC, LogPortIndex);
5131 Val32 = pAC->GIni.GP[PhysPortIndex].PhyType;
5132 SK_PNMI_STORE_U32(pBufPtr, Val32);
5133 }
5134 }
5135 else { /* DualNetMode */
5136
5137 Val32 = pAC->GIni.GP[NetIndex].PhyType;
5138 SK_PNMI_STORE_U32(pBufPtr, Val32);
5139 }
5140 Offset += sizeof(SK_U32);
5141 break;
5142
5143#ifdef SK_PHY_LP_MODE
5144 case OID_SKGE_PHY_LP_MODE:
5145 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5146 if (LogPortIndex == 0) {
5147 continue;
5148 }
5149 else {
5150 /* Get value for physical ports */
5151 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
5152 Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
5153 *pBufPtr = Val8;
5154 }
5155 }
5156 else { /* DualNetMode */
5157
5158 Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
5159 *pBufPtr = Val8;
5160 }
5161 Offset += sizeof(SK_U8);
5162 break;
5163#endif
5164
5165 case OID_SKGE_LINK_CAP:
5166 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5167 if (LogPortIndex == 0) {
5168 /* Get value for virtual port */
5169 VirtualConf(pAC, IoC, Id, pBufPtr);
5170 }
5171 else {
5172 /* Get value for physical ports */
5173 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5174 pAC, LogPortIndex);
5175
5176 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkCap;
5177 }
5178 }
5179 else { /* DualNetMode */
5180
5181 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap;
5182 }
5183 Offset += sizeof(char);
5184 break;
5185
5186 case OID_SKGE_LINK_MODE:
5187 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5188 if (LogPortIndex == 0) {
5189 /* Get value for virtual port */
5190 VirtualConf(pAC, IoC, Id, pBufPtr);
5191 }
5192 else {
5193 /* Get value for physical ports */
5194 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5195 pAC, LogPortIndex);
5196
5197 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
5198 }
5199 }
5200 else { /* DualNetMode */
5201
5202 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf;
5203 }
5204 Offset += sizeof(char);
5205 break;
5206
5207 case OID_SKGE_LINK_MODE_STATUS:
5208 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5209 if (LogPortIndex == 0) {
5210 /* Get value for virtual port */
5211 VirtualConf(pAC, IoC, Id, pBufPtr);
5212 }
5213 else {
5214 /* Get value for physical port */
5215 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5216 pAC, LogPortIndex);
5217
5218 *pBufPtr =
5219 CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
5220 }
5221 }
5222 else { /* DualNetMode */
5223
5224 *pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex);
5225 }
5226 Offset += sizeof(char);
5227 break;
5228
5229 case OID_SKGE_LINK_STATUS:
5230 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5231 if (LogPortIndex == 0) {
5232 /* Get value for virtual port */
5233 VirtualConf(pAC, IoC, Id, pBufPtr);
5234 }
5235 else {
5236 /* Get value for physical ports */
5237 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5238 pAC, LogPortIndex);
5239
5240 *pBufPtr = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
5241 }
5242 }
5243 else { /* DualNetMode */
5244
5245 *pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex);
5246 }
5247 Offset += sizeof(char);
5248 break;
5249
5250 case OID_SKGE_FLOWCTRL_CAP:
5251 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5252 if (LogPortIndex == 0) {
5253 /* Get value for virtual port */
5254 VirtualConf(pAC, IoC, Id, pBufPtr);
5255 }
5256 else {
5257 /* Get value for physical ports */
5258 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5259 pAC, LogPortIndex);
5260
5261 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
5262 }
5263 }
5264 else { /* DualNetMode */
5265
5266 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
5267 }
5268 Offset += sizeof(char);
5269 break;
5270
5271 case OID_SKGE_FLOWCTRL_MODE:
5272 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5273 if (LogPortIndex == 0) {
5274 /* Get value for virtual port */
5275 VirtualConf(pAC, IoC, Id, pBufPtr);
5276 }
5277 else {
5278 /* Get value for physical port */
5279 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5280 pAC, LogPortIndex);
5281
5282 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
5283 }
5284 }
5285 else { /* DualNetMode */
5286
5287 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
5288 }
5289 Offset += sizeof(char);
5290 break;
5291
5292 case OID_SKGE_FLOWCTRL_STATUS:
5293 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5294 if (LogPortIndex == 0) {
5295 /* Get value for virtual port */
5296 VirtualConf(pAC, IoC, Id, pBufPtr);
5297 }
5298 else {
5299 /* Get value for physical port */
5300 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5301 pAC, LogPortIndex);
5302
5303 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
5304 }
5305 }
5306 else { /* DualNetMode */
5307
5308 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
5309 }
5310 Offset += sizeof(char);
5311 break;
5312
5313 case OID_SKGE_PHY_OPERATION_CAP:
5314 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5315 if (LogPortIndex == 0) {
5316 /* Get value for virtual port */
5317 VirtualConf(pAC, IoC, Id, pBufPtr);
5318 }
5319 else {
5320 /* Get value for physical ports */
5321 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5322 pAC, LogPortIndex);
5323
5324 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSCap;
5325 }
5326 }
5327 else { /* DualNetMode */
5328
5329 *pBufPtr = pAC->GIni.GP[NetIndex].PMSCap;
5330 }
5331 Offset += sizeof(char);
5332 break;
5333
5334 case OID_SKGE_PHY_OPERATION_MODE:
5335 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5336 if (LogPortIndex == 0) {
5337 /* Get value for virtual port */
5338 VirtualConf(pAC, IoC, Id, pBufPtr);
5339 }
5340 else {
5341 /* Get value for physical port */
5342 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5343 pAC, LogPortIndex);
5344
5345 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSMode;
5346 }
5347 }
5348 else { /* DualNetMode */
5349
5350 *pBufPtr = pAC->GIni.GP[NetIndex].PMSMode;
5351 }
5352 Offset += sizeof(char);
5353 break;
5354
5355 case OID_SKGE_PHY_OPERATION_STATUS:
5356 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5357 if (LogPortIndex == 0) {
5358 /* Get value for virtual port */
5359 VirtualConf(pAC, IoC, Id, pBufPtr);
5360 }
5361 else {
5362 /* Get value for physical port */
5363 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5364 pAC, LogPortIndex);
5365
5366 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSStatus;
5367 }
5368 }
5369 else {
5370
5371 *pBufPtr = pAC->GIni.GP[NetIndex].PMSStatus;
5372 }
5373 Offset += sizeof(char);
5374 break;
5375
5376 case OID_SKGE_SPEED_CAP:
5377 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5378 if (LogPortIndex == 0) {
5379 /* Get value for virtual port */
5380 VirtualConf(pAC, IoC, Id, pBufPtr);
5381 }
5382 else {
5383 /* Get value for physical ports */
5384 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5385 pAC, LogPortIndex);
5386
5387 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedCap;
5388 }
5389 }
5390 else { /* DualNetMode */
5391
5392 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
5393 }
5394 Offset += sizeof(char);
5395 break;
5396
5397 case OID_SKGE_SPEED_MODE:
5398 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5399 if (LogPortIndex == 0) {
5400 /* Get value for virtual port */
5401 VirtualConf(pAC, IoC, Id, pBufPtr);
5402 }
5403 else {
5404 /* Get value for physical port */
5405 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5406 pAC, LogPortIndex);
5407
5408 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
5409 }
5410 }
5411 else { /* DualNetMode */
5412
5413 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed;
5414 }
5415 Offset += sizeof(char);
5416 break;
5417
5418 case OID_SKGE_SPEED_STATUS:
5419 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5420 if (LogPortIndex == 0) {
5421 /* Get value for virtual port */
5422 VirtualConf(pAC, IoC, Id, pBufPtr);
5423 }
5424 else {
5425 /* Get value for physical port */
5426 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5427 pAC, LogPortIndex);
5428
5429 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
5430 }
5431 }
5432 else { /* DualNetMode */
5433
5434 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
5435 }
5436 Offset += sizeof(char);
5437 break;
5438
5439 case OID_SKGE_MTU:
5440 Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
5441 SK_PNMI_STORE_U32(pBufPtr, Val32);
5442 Offset += sizeof(SK_U32);
5443 break;
5444
5445 default:
5446 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5447 ("MacPrivateConf: Unknown OID should be handled before"));
5448
5449 pAC->Pnmi.SirqUpdatedFlag --;
5450 return (SK_PNMI_ERR_GENERAL);
5451 }
5452 }
5453 *pLen = Offset;
5454 pAC->Pnmi.SirqUpdatedFlag --;
5455
5456 return (SK_PNMI_ERR_OK);
5457 }
5458
5459 /*
5460 * From here SET or PRESET action. Check if the passed
5461 * buffer length is plausible.
5462 */
5463 switch (Id) {
5464
5465 case OID_SKGE_LINK_MODE:
5466 case OID_SKGE_FLOWCTRL_MODE:
5467 case OID_SKGE_PHY_OPERATION_MODE:
5468 case OID_SKGE_SPEED_MODE:
5469 if (*pLen < Limit - LogPortIndex) {
5470
5471 *pLen = Limit - LogPortIndex;
5472 return (SK_PNMI_ERR_TOO_SHORT);
5473 }
5474 if (*pLen != Limit - LogPortIndex) {
5475
5476 *pLen = 0;
5477 return (SK_PNMI_ERR_BAD_VALUE);
5478 }
5479 break;
5480
5481#ifdef SK_PHY_LP_MODE
5482 case OID_SKGE_PHY_LP_MODE:
5483 if (*pLen < Limit - LogPortIndex) {
5484
5485 *pLen = Limit - LogPortIndex;
5486 return (SK_PNMI_ERR_TOO_SHORT);
5487 }
5488 break;
5489#endif
5490
5491 case OID_SKGE_MTU:
5492 if (*pLen < sizeof(SK_U32)) {
5493
5494 *pLen = sizeof(SK_U32);
5495 return (SK_PNMI_ERR_TOO_SHORT);
5496 }
5497 if (*pLen != sizeof(SK_U32)) {
5498
5499 *pLen = 0;
5500 return (SK_PNMI_ERR_BAD_VALUE);
5501 }
5502 break;
5503
5504 default:
5505 *pLen = 0;
5506 return (SK_PNMI_ERR_READ_ONLY);
5507 }
5508
5509 /*
5510 * Perform preset or set
5511 */
5512 Offset = 0;
5513 for (; LogPortIndex < Limit; LogPortIndex ++) {
5514
5515 switch (Id) {
5516
5517 case OID_SKGE_LINK_MODE:
5518 /* Check the value range */
5519 Val8 = *(pBuf + Offset);
5520 if (Val8 == 0) {
5521
5522 Offset += sizeof(char);
5523 break;
5524 }
5525 if (Val8 < SK_LMODE_HALF ||
5526 (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
5527 (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
5528
5529 *pLen = 0;
5530 return (SK_PNMI_ERR_BAD_VALUE);
5531 }
5532
5533 /* The preset ends here */
5534 if (Action == SK_PNMI_PRESET) {
5535
5536 return (SK_PNMI_ERR_OK);
5537 }
5538
5539 if (LogPortIndex == 0) {
5540
5541 /*
5542 * The virtual port consists of all currently
5543 * active ports. Find them and send an event
5544 * with the new link mode to SIRQ.
5545 */
5546 for (PhysPortIndex = 0;
5547 PhysPortIndex < PhysPortMax;
5548 PhysPortIndex ++) {
5549
5550 if (!pAC->Pnmi.Port[PhysPortIndex].
5551 ActiveFlag) {
5552
5553 continue;
5554 }
5555
5556 EventParam.Para32[0] = PhysPortIndex;
5557 EventParam.Para32[1] = (SK_U32)Val8;
5558 if (SkGeSirqEvent(pAC, IoC,
5559 SK_HWEV_SET_LMODE,
5560 EventParam) > 0) {
5561
5562 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5563 SK_PNMI_ERR043,
5564 SK_PNMI_ERR043MSG);
5565
5566 *pLen = 0;
5567 return (SK_PNMI_ERR_GENERAL);
5568 }
5569 }
5570 }
5571 else {
5572 /*
5573 * Send an event with the new link mode to
5574 * the SIRQ module.
5575 */
5576 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5577 pAC, LogPortIndex);
5578 EventParam.Para32[1] = (SK_U32)Val8;
5579 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
5580 EventParam) > 0) {
5581
5582 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5583 SK_PNMI_ERR043,
5584 SK_PNMI_ERR043MSG);
5585
5586 *pLen = 0;
5587 return (SK_PNMI_ERR_GENERAL);
5588 }
5589 }
5590 Offset += sizeof(char);
5591 break;
5592
5593 case OID_SKGE_FLOWCTRL_MODE:
5594 /* Check the value range */
5595 Val8 = *(pBuf + Offset);
5596 if (Val8 == 0) {
5597
5598 Offset += sizeof(char);
5599 break;
5600 }
5601 if (Val8 < SK_FLOW_MODE_NONE ||
5602 (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
5603 (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
5604
5605 *pLen = 0;
5606 return (SK_PNMI_ERR_BAD_VALUE);
5607 }
5608
5609 /* The preset ends here */
5610 if (Action == SK_PNMI_PRESET) {
5611
5612 return (SK_PNMI_ERR_OK);
5613 }
5614
5615 if (LogPortIndex == 0) {
5616
5617 /*
5618 * The virtual port consists of all currently
5619 * active ports. Find them and send an event
5620 * with the new flow control mode to SIRQ.
5621 */
5622 for (PhysPortIndex = 0;
5623 PhysPortIndex < PhysPortMax;
5624 PhysPortIndex ++) {
5625
5626 if (!pAC->Pnmi.Port[PhysPortIndex].
5627 ActiveFlag) {
5628
5629 continue;
5630 }
5631
5632 EventParam.Para32[0] = PhysPortIndex;
5633 EventParam.Para32[1] = (SK_U32)Val8;
5634 if (SkGeSirqEvent(pAC, IoC,
5635 SK_HWEV_SET_FLOWMODE,
5636 EventParam) > 0) {
5637
5638 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5639 SK_PNMI_ERR044,
5640 SK_PNMI_ERR044MSG);
5641
5642 *pLen = 0;
5643 return (SK_PNMI_ERR_GENERAL);
5644 }
5645 }
5646 }
5647 else {
5648 /*
5649 * Send an event with the new flow control
5650 * mode to the SIRQ module.
5651 */
5652 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5653 pAC, LogPortIndex);
5654 EventParam.Para32[1] = (SK_U32)Val8;
5655 if (SkGeSirqEvent(pAC, IoC,
5656 SK_HWEV_SET_FLOWMODE, EventParam)
5657 > 0) {
5658
5659 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5660 SK_PNMI_ERR044,
5661 SK_PNMI_ERR044MSG);
5662
5663 *pLen = 0;
5664 return (SK_PNMI_ERR_GENERAL);
5665 }
5666 }
5667 Offset += sizeof(char);
5668 break;
5669
5670 case OID_SKGE_PHY_OPERATION_MODE :
5671 /* Check the value range */
5672 Val8 = *(pBuf + Offset);
5673 if (Val8 == 0) {
5674 /* mode of this port remains unchanged */
5675 Offset += sizeof(char);
5676 break;
5677 }
5678 if (Val8 < SK_MS_MODE_AUTO ||
5679 (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
5680 (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
5681
5682 *pLen = 0;
5683 return (SK_PNMI_ERR_BAD_VALUE);
5684 }
5685
5686 /* The preset ends here */
5687 if (Action == SK_PNMI_PRESET) {
5688
5689 return (SK_PNMI_ERR_OK);
5690 }
5691
5692 if (LogPortIndex == 0) {
5693
5694 /*
5695 * The virtual port consists of all currently
5696 * active ports. Find them and send an event
5697 * with new master/slave (role) mode to SIRQ.
5698 */
5699 for (PhysPortIndex = 0;
5700 PhysPortIndex < PhysPortMax;
5701 PhysPortIndex ++) {
5702
5703 if (!pAC->Pnmi.Port[PhysPortIndex].
5704 ActiveFlag) {
5705
5706 continue;
5707 }
5708
5709 EventParam.Para32[0] = PhysPortIndex;
5710 EventParam.Para32[1] = (SK_U32)Val8;
5711 if (SkGeSirqEvent(pAC, IoC,
5712 SK_HWEV_SET_ROLE,
5713 EventParam) > 0) {
5714
5715 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5716 SK_PNMI_ERR042,
5717 SK_PNMI_ERR042MSG);
5718
5719 *pLen = 0;
5720 return (SK_PNMI_ERR_GENERAL);
5721 }
5722 }
5723 }
5724 else {
5725 /*
5726 * Send an event with the new master/slave
5727 * (role) mode to the SIRQ module.
5728 */
5729 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5730 pAC, LogPortIndex);
5731 EventParam.Para32[1] = (SK_U32)Val8;
5732 if (SkGeSirqEvent(pAC, IoC,
5733 SK_HWEV_SET_ROLE, EventParam) > 0) {
5734
5735 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5736 SK_PNMI_ERR042,
5737 SK_PNMI_ERR042MSG);
5738
5739 *pLen = 0;
5740 return (SK_PNMI_ERR_GENERAL);
5741 }
5742 }
5743
5744 Offset += sizeof(char);
5745 break;
5746
5747 case OID_SKGE_SPEED_MODE:
5748 /* Check the value range */
5749 Val8 = *(pBuf + Offset);
5750 if (Val8 == 0) {
5751
5752 Offset += sizeof(char);
5753 break;
5754 }
5755 if (Val8 < (SK_LSPEED_AUTO) ||
5756 (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) ||
5757 (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) {
5758
5759 *pLen = 0;
5760 return (SK_PNMI_ERR_BAD_VALUE);
5761 }
5762
5763 /* The preset ends here */
5764 if (Action == SK_PNMI_PRESET) {
5765
5766 return (SK_PNMI_ERR_OK);
5767 }
5768
5769 if (LogPortIndex == 0) {
5770
5771 /*
5772 * The virtual port consists of all currently
5773 * active ports. Find them and send an event
5774 * with the new flow control mode to SIRQ.
5775 */
5776 for (PhysPortIndex = 0;
5777 PhysPortIndex < PhysPortMax;
5778 PhysPortIndex ++) {
5779
5780 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
5781
5782 continue;
5783 }
5784
5785 EventParam.Para32[0] = PhysPortIndex;
5786 EventParam.Para32[1] = (SK_U32)Val8;
5787 if (SkGeSirqEvent(pAC, IoC,
5788 SK_HWEV_SET_SPEED,
5789 EventParam) > 0) {
5790
5791 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5792 SK_PNMI_ERR045,
5793 SK_PNMI_ERR045MSG);
5794
5795 *pLen = 0;
5796 return (SK_PNMI_ERR_GENERAL);
5797 }
5798 }
5799 }
5800 else {
5801 /*
5802 * Send an event with the new flow control
5803 * mode to the SIRQ module.
5804 */
5805 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5806 pAC, LogPortIndex);
5807 EventParam.Para32[1] = (SK_U32)Val8;
5808 if (SkGeSirqEvent(pAC, IoC,
5809 SK_HWEV_SET_SPEED,
5810 EventParam) > 0) {
5811
5812 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5813 SK_PNMI_ERR045,
5814 SK_PNMI_ERR045MSG);
5815
5816 *pLen = 0;
5817 return (SK_PNMI_ERR_GENERAL);
5818 }
5819 }
5820 Offset += sizeof(char);
5821 break;
5822
5823 case OID_SKGE_MTU :
5824 /* Check the value range */
5825 Val32 = *(SK_U32*)(pBuf + Offset);
5826 if (Val32 == 0) {
5827 /* mtu of this port remains unchanged */
5828 Offset += sizeof(SK_U32);
5829 break;
5830 }
5831 if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
5832 *pLen = 0;
5833 return (SK_PNMI_ERR_BAD_VALUE);
5834 }
5835
5836 /* The preset ends here */
5837 if (Action == SK_PNMI_PRESET) {
5838 return (SK_PNMI_ERR_OK);
5839 }
5840
5841 if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
5842 return (SK_PNMI_ERR_GENERAL);
5843 }
5844
5845 Offset += sizeof(SK_U32);
5846 break;
5847
5848#ifdef SK_PHY_LP_MODE
5849 case OID_SKGE_PHY_LP_MODE:
5850 /* The preset ends here */
5851 if (Action == SK_PNMI_PRESET) {
5852
5853 return (SK_PNMI_ERR_OK);
5854 }
5855
5856 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5857 if (LogPortIndex == 0) {
5858 Offset = 0;
5859 continue;
5860 }
5861 else {
5862 /* Set value for physical ports */
5863 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
5864
5865 switch (*(pBuf + Offset)) {
5866 case 0:
5867 /* If LowPowerMode is active, we can leave it. */
5868 if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
5869
5870 Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex);
5871
5872 if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) {
5873
5874 SkDrvInitAdapter(pAC);
5875 }
5876 break;
5877 }
5878 else {
5879 *pLen = 0;
5880 return (SK_PNMI_ERR_GENERAL);
5881 }
5882 case 1:
5883 case 2:
5884 case 3:
5885 case 4:
5886 /* If no LowPowerMode is active, we can enter it. */
5887 if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
5888
5889 if ((*(pBuf + Offset)) < 3) {
5890
5891 SkDrvDeInitAdapter(pAC);
5892 }
5893
5894 Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf);
5895 break;
5896 }
5897 else {
5898 *pLen = 0;
5899 return (SK_PNMI_ERR_GENERAL);
5900 }
5901 default:
5902 *pLen = 0;
5903 return (SK_PNMI_ERR_BAD_VALUE);
5904 }
5905 }
5906 }
5907 else { /* DualNetMode */
5908
5909 switch (*(pBuf + Offset)) {
5910 case 0:
5911 /* If we are in a LowPowerMode, we can leave it. */
5912 if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
5913
5914 Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex);
5915
5916 if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) {
5917
5918 SkDrvInitAdapter(pAC);
5919 }
5920 break;
5921 }
5922 else {
5923 *pLen = 0;
5924 return (SK_PNMI_ERR_GENERAL);
5925 }
5926
5927 case 1:
5928 case 2:
5929 case 3:
5930 case 4:
5931 /* If we are not already in LowPowerMode, we can enter it. */
5932 if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
5933
5934 if ((*(pBuf + Offset)) < 3) {
5935
5936 SkDrvDeInitAdapter(pAC);
5937 }
5938 else {
5939
5940 Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf);
5941 }
5942 break;
5943 }
5944 else {
5945 *pLen = 0;
5946 return (SK_PNMI_ERR_GENERAL);
5947 }
5948
5949 default:
5950 *pLen = 0;
5951 return (SK_PNMI_ERR_BAD_VALUE);
5952 }
5953 }
5954 Offset += sizeof(SK_U8);
5955 break;
5956#endif
5957
5958 default:
5959 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5960 ("MacPrivateConf: Unknown OID should be handled before set"));
5961
5962 *pLen = 0;
5963 return (SK_PNMI_ERR_GENERAL);
5964 }
5965 }
5966
5967 return (SK_PNMI_ERR_OK);
5968}
5969
5970/*****************************************************************************
5971 *
5972 * Monitor - OID handler function for RLMT_MONITOR_XXX
5973 *
5974 * Description:
5975 * Because RLMT currently does not support the monitoring of
5976 * remote adapter cards, we return always an empty table.
5977 *
5978 * Returns:
5979 * SK_PNMI_ERR_OK The request was successfully performed.
5980 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
5981 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
5982 * the correct data (e.g. a 32bit value is
5983 * needed, but a 16 bit value was passed).
5984 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
5985 * value range.
5986 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
5987 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
5988 * exist (e.g. port instance 3 on a two port
5989 * adapter.
5990 */
5991PNMI_STATIC int Monitor(
5992SK_AC *pAC, /* Pointer to adapter context */
5993SK_IOC IoC, /* IO context handle */
5994int Action, /* GET/PRESET/SET action */
5995SK_U32 Id, /* Object ID that is to be processed */
5996char *pBuf, /* Buffer used for the management data transfer */
5997unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
5998SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5999unsigned int TableIndex, /* Index to the Id table */
6000SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
6001{
6002 unsigned int Index;
6003 unsigned int Limit;
6004 unsigned int Offset;
6005 unsigned int Entries;
6006
6007
6008 /*
6009 * Calculate instance if wished.
6010 */
6011 /* XXX Not yet implemented. Return always an empty table. */
6012 Entries = 0;
6013
6014 if ((Instance != (SK_U32)(-1))) {
6015
6016 if ((Instance < 1) || (Instance > Entries)) {
6017
6018 *pLen = 0;
6019 return (SK_PNMI_ERR_UNKNOWN_INST);
6020 }
6021
6022 Index = (unsigned int)Instance - 1;
6023 Limit = (unsigned int)Instance;
6024 }
6025 else {
6026 Index = 0;
6027 Limit = Entries;
6028 }
6029
6030 /*
6031 * Get/Set value
6032 */
6033 if (Action == SK_PNMI_GET) {
6034
6035 for (Offset=0; Index < Limit; Index ++) {
6036
6037 switch (Id) {
6038
6039 case OID_SKGE_RLMT_MONITOR_INDEX:
6040 case OID_SKGE_RLMT_MONITOR_ADDR:
6041 case OID_SKGE_RLMT_MONITOR_ERRS:
6042 case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
6043 case OID_SKGE_RLMT_MONITOR_ADMIN:
6044 break;
6045
6046 default:
6047 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
6048 SK_PNMI_ERR046MSG);
6049
6050 *pLen = 0;
6051 return (SK_PNMI_ERR_GENERAL);
6052 }
6053 }
6054 *pLen = Offset;
6055 }
6056 else {
6057 /* Only MONITOR_ADMIN can be set */
6058 if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
6059
6060 *pLen = 0;
6061 return (SK_PNMI_ERR_READ_ONLY);
6062 }
6063
6064 /* Check if the length is plausible */
6065 if (*pLen < (Limit - Index)) {
6066
6067 return (SK_PNMI_ERR_TOO_SHORT);
6068 }
6069 /* Okay, we have a wide value range */
6070 if (*pLen != (Limit - Index)) {
6071
6072 *pLen = 0;
6073 return (SK_PNMI_ERR_BAD_VALUE);
6074 }
6075/*
6076 for (Offset=0; Index < Limit; Index ++) {
6077 }
6078*/
6079/*
6080 * XXX Not yet implemented. Return always BAD_VALUE, because the table
6081 * is empty.
6082 */
6083 *pLen = 0;
6084 return (SK_PNMI_ERR_BAD_VALUE);
6085 }
6086
6087 return (SK_PNMI_ERR_OK);
6088}
6089
6090/*****************************************************************************
6091 *
6092 * VirtualConf - Calculates the values of configuration OIDs for virtual port
6093 *
6094 * Description:
6095 * We handle here the get of the configuration group OIDs, which are
6096 * a little bit complicated. The virtual port consists of all currently
6097 * active physical ports. If multiple ports are active and configured
6098 * differently we get in some trouble to return a single value. So we
6099 * get the value of the first active port and compare it with that of
6100 * the other active ports. If they are not the same, we return a value
6101 * that indicates that the state is indeterminated.
6102 *
6103 * Returns:
6104 * Nothing
6105 */
6106PNMI_STATIC void VirtualConf(
6107SK_AC *pAC, /* Pointer to adapter context */
6108SK_IOC IoC, /* IO context handle */
6109SK_U32 Id, /* Object ID that is to be processed */
6110char *pBuf) /* Buffer used for the management data transfer */
6111{
6112 unsigned int PhysPortMax;
6113 unsigned int PhysPortIndex;
6114 SK_U8 Val8;
6115 SK_U32 Val32;
6116 SK_BOOL PortActiveFlag;
6117 SK_GEPORT *pPrt;
6118
6119 *pBuf = 0;
6120 PortActiveFlag = SK_FALSE;
6121 PhysPortMax = pAC->GIni.GIMacsFound;
6122
6123 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
6124 PhysPortIndex ++) {
6125
6126 pPrt = &pAC->GIni.GP[PhysPortIndex];
6127
6128 /* Check if the physical port is active */
6129 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6130
6131 continue;
6132 }
6133
6134 PortActiveFlag = SK_TRUE;
6135
6136 switch (Id) {
6137
6138 case OID_SKGE_PHY_TYPE:
6139 /* Check if it is the first active port */
6140 if (*pBuf == 0) {
6141 Val32 = pPrt->PhyType;
6142 SK_PNMI_STORE_U32(pBuf, Val32);
6143 continue;
6144 }
6145
6146 case OID_SKGE_LINK_CAP:
6147
6148 /*
6149 * Different capabilities should not happen, but
6150 * in the case of the cases OR them all together.
6151 * From a curious point of view the virtual port
6152 * is capable of all found capabilities.
6153 */
6154 *pBuf |= pPrt->PLinkCap;
6155 break;
6156
6157 case OID_SKGE_LINK_MODE:
6158 /* Check if it is the first active port */
6159 if (*pBuf == 0) {
6160
6161 *pBuf = pPrt->PLinkModeConf;
6162 continue;
6163 }
6164
6165 /*
6166 * If we find an active port with a different link
6167 * mode than the first one we return a value that
6168 * indicates that the link mode is indeterminated.
6169 */
6170 if (*pBuf != pPrt->PLinkModeConf) {
6171
6172 *pBuf = SK_LMODE_INDETERMINATED;
6173 }
6174 break;
6175
6176 case OID_SKGE_LINK_MODE_STATUS:
6177 /* Get the link mode of the physical port */
6178 Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
6179
6180 /* Check if it is the first active port */
6181 if (*pBuf == 0) {
6182
6183 *pBuf = Val8;
6184 continue;
6185 }
6186
6187 /*
6188 * If we find an active port with a different link
6189 * mode status than the first one we return a value
6190 * that indicates that the link mode status is
6191 * indeterminated.
6192 */
6193 if (*pBuf != Val8) {
6194
6195 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6196 }
6197 break;
6198
6199 case OID_SKGE_LINK_STATUS:
6200 /* Get the link status of the physical port */
6201 Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
6202
6203 /* Check if it is the first active port */
6204 if (*pBuf == 0) {
6205
6206 *pBuf = Val8;
6207 continue;
6208 }
6209
6210 /*
6211 * If we find an active port with a different link
6212 * status than the first one, we return a value
6213 * that indicates that the link status is
6214 * indeterminated.
6215 */
6216 if (*pBuf != Val8) {
6217
6218 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6219 }
6220 break;
6221
6222 case OID_SKGE_FLOWCTRL_CAP:
6223 /* Check if it is the first active port */
6224 if (*pBuf == 0) {
6225
6226 *pBuf = pPrt->PFlowCtrlCap;
6227 continue;
6228 }
6229
6230 /*
6231 * From a curious point of view the virtual port
6232 * is capable of all found capabilities.
6233 */
6234 *pBuf |= pPrt->PFlowCtrlCap;
6235 break;
6236
6237 case OID_SKGE_FLOWCTRL_MODE:
6238 /* Check if it is the first active port */
6239 if (*pBuf == 0) {
6240
6241 *pBuf = pPrt->PFlowCtrlMode;
6242 continue;
6243 }
6244
6245 /*
6246 * If we find an active port with a different flow
6247 * control mode than the first one, we return a value
6248 * that indicates that the mode is indeterminated.
6249 */
6250 if (*pBuf != pPrt->PFlowCtrlMode) {
6251
6252 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6253 }
6254 break;
6255
6256 case OID_SKGE_FLOWCTRL_STATUS:
6257 /* Check if it is the first active port */
6258 if (*pBuf == 0) {
6259
6260 *pBuf = pPrt->PFlowCtrlStatus;
6261 continue;
6262 }
6263
6264 /*
6265 * If we find an active port with a different flow
6266 * control status than the first one, we return a
6267 * value that indicates that the status is
6268 * indeterminated.
6269 */
6270 if (*pBuf != pPrt->PFlowCtrlStatus) {
6271
6272 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6273 }
6274 break;
6275
6276 case OID_SKGE_PHY_OPERATION_CAP:
6277 /* Check if it is the first active port */
6278 if (*pBuf == 0) {
6279
6280 *pBuf = pPrt->PMSCap;
6281 continue;
6282 }
6283
6284 /*
6285 * From a curious point of view the virtual port
6286 * is capable of all found capabilities.
6287 */
6288 *pBuf |= pPrt->PMSCap;
6289 break;
6290
6291 case OID_SKGE_PHY_OPERATION_MODE:
6292 /* Check if it is the first active port */
6293 if (*pBuf == 0) {
6294
6295 *pBuf = pPrt->PMSMode;
6296 continue;
6297 }
6298
6299 /*
6300 * If we find an active port with a different master/
6301 * slave mode than the first one, we return a value
6302 * that indicates that the mode is indeterminated.
6303 */
6304 if (*pBuf != pPrt->PMSMode) {
6305
6306 *pBuf = SK_MS_MODE_INDETERMINATED;
6307 }
6308 break;
6309
6310 case OID_SKGE_PHY_OPERATION_STATUS:
6311 /* Check if it is the first active port */
6312 if (*pBuf == 0) {
6313
6314 *pBuf = pPrt->PMSStatus;
6315 continue;
6316 }
6317
6318 /*
6319 * If we find an active port with a different master/
6320 * slave status than the first one, we return a
6321 * value that indicates that the status is
6322 * indeterminated.
6323 */
6324 if (*pBuf != pPrt->PMSStatus) {
6325
6326 *pBuf = SK_MS_STAT_INDETERMINATED;
6327 }
6328 break;
6329
6330 case OID_SKGE_SPEED_MODE:
6331 /* Check if it is the first active port */
6332 if (*pBuf == 0) {
6333
6334 *pBuf = pPrt->PLinkSpeed;
6335 continue;
6336 }
6337
6338 /*
6339 * If we find an active port with a different flow
6340 * control mode than the first one, we return a value
6341 * that indicates that the mode is indeterminated.
6342 */
6343 if (*pBuf != pPrt->PLinkSpeed) {
6344
6345 *pBuf = SK_LSPEED_INDETERMINATED;
6346 }
6347 break;
6348
6349 case OID_SKGE_SPEED_STATUS:
6350 /* Check if it is the first active port */
6351 if (*pBuf == 0) {
6352
6353 *pBuf = pPrt->PLinkSpeedUsed;
6354 continue;
6355 }
6356
6357 /*
6358 * If we find an active port with a different flow
6359 * control status than the first one, we return a
6360 * value that indicates that the status is
6361 * indeterminated.
6362 */
6363 if (*pBuf != pPrt->PLinkSpeedUsed) {
6364
6365 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6366 }
6367 break;
6368 }
6369 }
6370
6371 /*
6372 * If no port is active return an indeterminated answer
6373 */
6374 if (!PortActiveFlag) {
6375
6376 switch (Id) {
6377
6378 case OID_SKGE_LINK_CAP:
6379 *pBuf = SK_LMODE_CAP_INDETERMINATED;
6380 break;
6381
6382 case OID_SKGE_LINK_MODE:
6383 *pBuf = SK_LMODE_INDETERMINATED;
6384 break;
6385
6386 case OID_SKGE_LINK_MODE_STATUS:
6387 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6388 break;
6389
6390 case OID_SKGE_LINK_STATUS:
6391 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6392 break;
6393
6394 case OID_SKGE_FLOWCTRL_CAP:
6395 case OID_SKGE_FLOWCTRL_MODE:
6396 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6397 break;
6398
6399 case OID_SKGE_FLOWCTRL_STATUS:
6400 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6401 break;
6402
6403 case OID_SKGE_PHY_OPERATION_CAP:
6404 *pBuf = SK_MS_CAP_INDETERMINATED;
6405 break;
6406
6407 case OID_SKGE_PHY_OPERATION_MODE:
6408 *pBuf = SK_MS_MODE_INDETERMINATED;
6409 break;
6410
6411 case OID_SKGE_PHY_OPERATION_STATUS:
6412 *pBuf = SK_MS_STAT_INDETERMINATED;
6413 break;
6414 case OID_SKGE_SPEED_CAP:
6415 *pBuf = SK_LSPEED_CAP_INDETERMINATED;
6416 break;
6417
6418 case OID_SKGE_SPEED_MODE:
6419 *pBuf = SK_LSPEED_INDETERMINATED;
6420 break;
6421
6422 case OID_SKGE_SPEED_STATUS:
6423 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6424 break;
6425 }
6426 }
6427}
6428
6429/*****************************************************************************
6430 *
6431 * CalculateLinkStatus - Determins the link status of a physical port
6432 *
6433 * Description:
6434 * Determins the link status the following way:
6435 * LSTAT_PHY_DOWN: Link is down
6436 * LSTAT_AUTONEG: Auto-negotiation failed
6437 * LSTAT_LOG_DOWN: Link is up but RLMT did not yet put the port
6438 * logically up.
6439 * LSTAT_LOG_UP: RLMT marked the port as up
6440 *
6441 * Returns:
6442 * Link status of physical port
6443 */
6444PNMI_STATIC SK_U8 CalculateLinkStatus(
6445SK_AC *pAC, /* Pointer to adapter context */
6446SK_IOC IoC, /* IO context handle */
6447unsigned int PhysPortIndex) /* Physical port index */
6448{
6449 SK_U8 Result;
6450
6451 if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
6452
6453 Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
6454 }
6455 else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
6456
6457 Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
6458 }
6459 else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
6460
6461 Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
6462 }
6463 else {
6464 Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
6465 }
6466
6467 return (Result);
6468}
6469
6470/*****************************************************************************
6471 *
6472 * CalculateLinkModeStatus - Determins the link mode status of a phys. port
6473 *
6474 * Description:
6475 * The COMMON module only tells us if the mode is half or full duplex.
6476 * But in the decade of auto sensing it is usefull for the user to
6477 * know if the mode was negotiated or forced. Therefore we have a
6478 * look to the mode, which was last used by the negotiation process.
6479 *
6480 * Returns:
6481 * The link mode status
6482 */
6483PNMI_STATIC SK_U8 CalculateLinkModeStatus(
6484SK_AC *pAC, /* Pointer to adapter context */
6485SK_IOC IoC, /* IO context handle */
6486unsigned int PhysPortIndex) /* Physical port index */
6487{
6488 SK_U8 Result;
6489
6490 /* Get the current mode, which can be full or half duplex */
6491 Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
6492
6493 /* Check if no valid mode could be found (link is down) */
6494 if (Result < SK_LMODE_STAT_HALF) {
6495
6496 Result = SK_LMODE_STAT_UNKNOWN;
6497 }
6498 else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
6499
6500 /*
6501 * Auto-negotiation was used to bring up the link. Change
6502 * the already found duplex status that it indicates
6503 * auto-negotiation was involved.
6504 */
6505 if (Result == SK_LMODE_STAT_HALF) {
6506
6507 Result = SK_LMODE_STAT_AUTOHALF;
6508 }
6509 else if (Result == SK_LMODE_STAT_FULL) {
6510
6511 Result = SK_LMODE_STAT_AUTOFULL;
6512 }
6513 }
6514
6515 return (Result);
6516}
6517
6518/*****************************************************************************
6519 *
6520 * GetVpdKeyArr - Obtain an array of VPD keys
6521 *
6522 * Description:
6523 * Read the VPD keys and build an array of VPD keys, which are
6524 * easy to access.
6525 *
6526 * Returns:
6527 * SK_PNMI_ERR_OK Task successfully performed.
6528 * SK_PNMI_ERR_GENERAL Something went wrong.
6529 */
6530PNMI_STATIC int GetVpdKeyArr(
6531SK_AC *pAC, /* Pointer to adapter context */
6532SK_IOC IoC, /* IO context handle */
6533char *pKeyArr, /* Ptr KeyArray */
6534unsigned int KeyArrLen, /* Length of array in bytes */
6535unsigned int *pKeyNo) /* Number of keys */
6536{
6537 unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE;
6538 char BufKeys[SK_PNMI_VPD_BUFSIZE];
6539 unsigned int StartOffset;
6540 unsigned int Offset;
6541 int Index;
6542 int Ret;
6543
6544
6545 SK_MEMSET(pKeyArr, 0, KeyArrLen);
6546
6547 /*
6548 * Get VPD key list
6549 */
6550 Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
6551 (int *)pKeyNo);
6552 if (Ret > 0) {
6553
6554 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
6555 SK_PNMI_ERR014MSG);
6556
6557 return (SK_PNMI_ERR_GENERAL);
6558 }
6559 /* If no keys are available return now */
6560 if (*pKeyNo == 0 || BufKeysLen == 0) {
6561
6562 return (SK_PNMI_ERR_OK);
6563 }
6564 /*
6565 * If the key list is too long for us trunc it and give a
6566 * errorlog notification. This case should not happen because
6567 * the maximum number of keys is limited due to RAM limitations
6568 */
6569 if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
6570
6571 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
6572 SK_PNMI_ERR015MSG);
6573
6574 *pKeyNo = SK_PNMI_VPD_ENTRIES;
6575 }
6576
6577 /*
6578 * Now build an array of fixed string length size and copy
6579 * the keys together.
6580 */
6581 for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
6582 Offset ++) {
6583
6584 if (BufKeys[Offset] != 0) {
6585
6586 continue;
6587 }
6588
6589 if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
6590
6591 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
6592 SK_PNMI_ERR016MSG);
6593 return (SK_PNMI_ERR_GENERAL);
6594 }
6595
6596 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6597 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6598
6599 Index ++;
6600 StartOffset = Offset + 1;
6601 }
6602
6603 /* Last key not zero terminated? Get it anyway */
6604 if (StartOffset < Offset) {
6605
6606 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6607 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6608 }
6609
6610 return (SK_PNMI_ERR_OK);
6611}
6612
6613/*****************************************************************************
6614 *
6615 * SirqUpdate - Let the SIRQ update its internal values
6616 *
6617 * Description:
6618 * Just to be sure that the SIRQ module holds its internal data
6619 * structures up to date, we send an update event before we make
6620 * any access.
6621 *
6622 * Returns:
6623 * SK_PNMI_ERR_OK Task successfully performed.
6624 * SK_PNMI_ERR_GENERAL Something went wrong.
6625 */
6626PNMI_STATIC int SirqUpdate(
6627SK_AC *pAC, /* Pointer to adapter context */
6628SK_IOC IoC) /* IO context handle */
6629{
6630 SK_EVPARA EventParam;
6631
6632
6633 /* Was the module already updated during the current PNMI call? */
6634 if (pAC->Pnmi.SirqUpdatedFlag > 0) {
6635
6636 return (SK_PNMI_ERR_OK);
6637 }
6638
6639 /* Send an synchronuous update event to the module */
6640 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6641 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
6642
6643 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
6644 SK_PNMI_ERR047MSG);
6645
6646 return (SK_PNMI_ERR_GENERAL);
6647 }
6648
6649 return (SK_PNMI_ERR_OK);
6650}
6651
6652/*****************************************************************************
6653 *
6654 * RlmtUpdate - Let the RLMT update its internal values
6655 *
6656 * Description:
6657 * Just to be sure that the RLMT module holds its internal data
6658 * structures up to date, we send an update event before we make
6659 * any access.
6660 *
6661 * Returns:
6662 * SK_PNMI_ERR_OK Task successfully performed.
6663 * SK_PNMI_ERR_GENERAL Something went wrong.
6664 */
6665PNMI_STATIC int RlmtUpdate(
6666SK_AC *pAC, /* Pointer to adapter context */
6667SK_IOC IoC, /* IO context handle */
6668SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6669{
6670 SK_EVPARA EventParam;
6671
6672
6673 /* Was the module already updated during the current PNMI call? */
6674 if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
6675
6676 return (SK_PNMI_ERR_OK);
6677 }
6678
6679 /* Send an synchronuous update event to the module */
6680 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6681 EventParam.Para32[0] = NetIndex;
6682 EventParam.Para32[1] = (SK_U32)-1;
6683 if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
6684
6685 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
6686 SK_PNMI_ERR048MSG);
6687
6688 return (SK_PNMI_ERR_GENERAL);
6689 }
6690
6691 return (SK_PNMI_ERR_OK);
6692}
6693
6694/*****************************************************************************
6695 *
6696 * MacUpdate - Force the XMAC to output the current statistic
6697 *
6698 * Description:
6699 * The XMAC holds its statistic internally. To obtain the current
6700 * values we must send a command so that the statistic data will
6701 * be written to a predefined memory area on the adapter.
6702 *
6703 * Returns:
6704 * SK_PNMI_ERR_OK Task successfully performed.
6705 * SK_PNMI_ERR_GENERAL Something went wrong.
6706 */
6707PNMI_STATIC int MacUpdate(
6708SK_AC *pAC, /* Pointer to adapter context */
6709SK_IOC IoC, /* IO context handle */
6710unsigned int FirstMac, /* Index of the first Mac to be updated */
6711unsigned int LastMac) /* Index of the last Mac to be updated */
6712{
6713 unsigned int MacIndex;
6714
6715 /*
6716 * Were the statistics already updated during the
6717 * current PNMI call?
6718 */
6719 if (pAC->Pnmi.MacUpdatedFlag > 0) {
6720
6721 return (SK_PNMI_ERR_OK);
6722 }
6723
6724 /* Send an update command to all MACs specified */
6725 for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
6726
6727 /*
6728 * 2002-09-13 pweber: Freeze the current SW counters.
6729 * (That should be done as close as
6730 * possible to the update of the
6731 * HW counters)
6732 */
6733 if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
6734 pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
6735 }
6736
6737 /* 2002-09-13 pweber: Update the HW counter */
6738 if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
6739
6740 return (SK_PNMI_ERR_GENERAL);
6741 }
6742 }
6743
6744 return (SK_PNMI_ERR_OK);
6745}
6746
6747/*****************************************************************************
6748 *
6749 * GetStatVal - Retrieve an XMAC statistic counter
6750 *
6751 * Description:
6752 * Retrieves the statistic counter of a virtual or physical port. The
6753 * virtual port is identified by the index 0. It consists of all
6754 * currently active ports. To obtain the counter value for this port
6755 * we must add the statistic counter of all active ports. To grant
6756 * continuous counter values for the virtual port even when port
6757 * switches occur we must additionally add a delta value, which was
6758 * calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
6759 *
6760 * Returns:
6761 * Requested statistic value
6762 */
6763PNMI_STATIC SK_U64 GetStatVal(
6764SK_AC *pAC, /* Pointer to adapter context */
6765SK_IOC IoC, /* IO context handle */
6766unsigned int LogPortIndex, /* Index of the logical Port to be processed */
6767unsigned int StatIndex, /* Index to statistic value */
6768SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6769{
6770 unsigned int PhysPortIndex;
6771 unsigned int PhysPortMax;
6772 SK_U64 Val = 0;
6773
6774
6775 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
6776
6777 PhysPortIndex = NetIndex;
6778
6779 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6780 }
6781 else { /* Single Net mode */
6782
6783 if (LogPortIndex == 0) {
6784
6785 PhysPortMax = pAC->GIni.GIMacsFound;
6786
6787 /* Add counter of all active ports */
6788 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
6789 PhysPortIndex ++) {
6790
6791 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6792
6793 Val += GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6794 }
6795 }
6796
6797 /* Correct value because of port switches */
6798 Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
6799 }
6800 else {
6801 /* Get counter value of physical port */
6802 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
6803
6804 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6805 }
6806 }
6807 return (Val);
6808}
6809
6810/*****************************************************************************
6811 *
6812 * GetPhysStatVal - Get counter value for physical port
6813 *
6814 * Description:
6815 * Builds a 64bit counter value. Except for the octet counters
6816 * the lower 32bit are counted in hardware and the upper 32bit
6817 * in software by monitoring counter overflow interrupts in the
6818 * event handler. To grant continous counter values during XMAC
6819 * resets (caused by a workaround) we must add a delta value.
6820 * The delta was calculated in the event handler when a
6821 * SK_PNMI_EVT_XMAC_RESET was received.
6822 *
6823 * Returns:
6824 * Counter value
6825 */
6826PNMI_STATIC SK_U64 GetPhysStatVal(
6827SK_AC *pAC, /* Pointer to adapter context */
6828SK_IOC IoC, /* IO context handle */
6829unsigned int PhysPortIndex, /* Index of the logical Port to be processed */
6830unsigned int StatIndex) /* Index to statistic value */
6831{
6832 SK_U64 Val = 0;
6833 SK_U32 LowVal = 0;
6834 SK_U32 HighVal = 0;
6835 SK_U16 Word;
6836 int MacType;
6837 unsigned int HelpIndex;
6838 SK_GEPORT *pPrt;
6839
6840 SK_PNMI_PORT *pPnmiPrt;
6841 SK_GEMACFUNC *pFnMac;
6842
6843 pPrt = &pAC->GIni.GP[PhysPortIndex];
6844
6845 MacType = pAC->GIni.GIMacType;
6846
6847 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
6848 if (MacType == SK_MAC_XMAC) {
6849 pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
6850 }
6851 else {
6852 pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex];
6853 }
6854
6855 pFnMac = &pAC->GIni.GIFunc;
6856
6857 switch (StatIndex) {
6858 case SK_PNMI_HTX:
6859 if (MacType == SK_MAC_GMAC) {
6860 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6861 StatAddr[SK_PNMI_HTX_BROADCAST][MacType].Reg,
6862 &LowVal);
6863 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6864 StatAddr[SK_PNMI_HTX_MULTICAST][MacType].Reg,
6865 &HighVal);
6866 LowVal += HighVal;
6867 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6868 StatAddr[SK_PNMI_HTX_UNICAST][MacType].Reg,
6869 &HighVal);
6870 LowVal += HighVal;
6871 }
6872 else {
6873 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6874 StatAddr[StatIndex][MacType].Reg,
6875 &LowVal);
6876 }
6877 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6878 break;
6879
6880 case SK_PNMI_HRX:
6881 if (MacType == SK_MAC_GMAC) {
6882 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6883 StatAddr[SK_PNMI_HRX_BROADCAST][MacType].Reg,
6884 &LowVal);
6885 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6886 StatAddr[SK_PNMI_HRX_MULTICAST][MacType].Reg,
6887 &HighVal);
6888 LowVal += HighVal;
6889 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6890 StatAddr[SK_PNMI_HRX_UNICAST][MacType].Reg,
6891 &HighVal);
6892 LowVal += HighVal;
6893 }
6894 else {
6895 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6896 StatAddr[StatIndex][MacType].Reg,
6897 &LowVal);
6898 }
6899 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6900 break;
6901
6902 case SK_PNMI_HTX_OCTET:
6903 case SK_PNMI_HRX_OCTET:
6904 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6905 StatAddr[StatIndex][MacType].Reg,
6906 &HighVal);
6907 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6908 StatAddr[StatIndex + 1][MacType].Reg,
6909 &LowVal);
6910 break;
6911
6912 case SK_PNMI_HTX_BURST:
6913 case SK_PNMI_HTX_EXCESS_DEF:
6914 case SK_PNMI_HTX_CARRIER:
6915 /* Not supported by GMAC */
6916 if (MacType == SK_MAC_GMAC) {
6917 return (Val);
6918 }
6919
6920 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6921 StatAddr[StatIndex][MacType].Reg,
6922 &LowVal);
6923 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6924 break;
6925
6926 case SK_PNMI_HTX_MACC:
6927 /* GMAC only supports PAUSE MAC control frames */
6928 if (MacType == SK_MAC_GMAC) {
6929 HelpIndex = SK_PNMI_HTX_PMACC;
6930 }
6931 else {
6932 HelpIndex = StatIndex;
6933 }
6934
6935 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6936 StatAddr[HelpIndex][MacType].Reg,
6937 &LowVal);
6938
6939 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6940 break;
6941
6942 case SK_PNMI_HTX_COL:
6943 case SK_PNMI_HRX_UNDERSIZE:
6944 /* Not supported by XMAC */
6945 if (MacType == SK_MAC_XMAC) {
6946 return (Val);
6947 }
6948
6949 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6950 StatAddr[StatIndex][MacType].Reg,
6951 &LowVal);
6952 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6953 break;
6954
6955 case SK_PNMI_HTX_DEFFERAL:
6956 /* Not supported by GMAC */
6957 if (MacType == SK_MAC_GMAC) {
6958 return (Val);
6959 }
6960
6961 /*
6962 * XMAC counts frames with deferred transmission
6963 * even in full-duplex mode.
6964 *
6965 * In full-duplex mode the counter remains constant!
6966 */
6967 if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) ||
6968 (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL)) {
6969
6970 LowVal = 0;
6971 HighVal = 0;
6972 }
6973 else {
6974 /* Otherwise get contents of hardware register */
6975 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6976 StatAddr[StatIndex][MacType].Reg,
6977 &LowVal);
6978 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6979 }
6980 break;
6981
6982 case SK_PNMI_HRX_BADOCTET:
6983 /* Not supported by XMAC */
6984 if (MacType == SK_MAC_XMAC) {
6985 return (Val);
6986 }
6987
6988 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6989 StatAddr[StatIndex][MacType].Reg,
6990 &HighVal);
6991 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6992 StatAddr[StatIndex + 1][MacType].Reg,
6993 &LowVal);
6994 break;
6995
6996 case SK_PNMI_HTX_OCTETLOW:
6997 case SK_PNMI_HRX_OCTETLOW:
6998 case SK_PNMI_HRX_BADOCTETLOW:
6999 return (Val);
7000
7001 case SK_PNMI_HRX_LONGFRAMES:
7002 /* For XMAC the SW counter is managed by PNMI */
7003 if (MacType == SK_MAC_XMAC) {
7004 return (pPnmiPrt->StatRxLongFrameCts);
7005 }
7006
7007 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7008 StatAddr[StatIndex][MacType].Reg,
7009 &LowVal);
7010 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7011 break;
7012
7013 case SK_PNMI_HRX_TOO_LONG:
7014 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7015 StatAddr[StatIndex][MacType].Reg,
7016 &LowVal);
7017 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7018
7019 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7020
7021 if (MacType == SK_MAC_GMAC) {
7022 /* For GMAC the SW counter is additionally managed by PNMI */
7023 Val += pPnmiPrt->StatRxFrameTooLongCts;
7024 }
7025 else {
7026 /*
7027 * Frames longer than IEEE 802.3 frame max size are counted
7028 * by XMAC in frame_too_long counter even reception of long
7029 * frames was enabled and the frame was correct.
7030 * So correct the value by subtracting RxLongFrame counter.
7031 */
7032 Val -= pPnmiPrt->StatRxLongFrameCts;
7033 }
7034
7035 LowVal = (SK_U32)Val;
7036 HighVal = (SK_U32)(Val >> 32);
7037 break;
7038
7039 case SK_PNMI_HRX_SHORTS:
7040 /* Not supported by GMAC */
7041 if (MacType == SK_MAC_GMAC) {
7042 /* GM_RXE_FRAG?? */
7043 return (Val);
7044 }
7045
7046 /*
7047 * XMAC counts short frame errors even if link down (#10620)
7048 *
7049 * If link-down the counter remains constant
7050 */
7051 if (pPrt->PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
7052
7053 /* Otherwise get incremental difference */
7054 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7055 StatAddr[StatIndex][MacType].Reg,
7056 &LowVal);
7057 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7058
7059 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7060 Val -= pPnmiPrt->RxShortZeroMark;
7061
7062 LowVal = (SK_U32)Val;
7063 HighVal = (SK_U32)(Val >> 32);
7064 }
7065 break;
7066
7067 case SK_PNMI_HRX_MACC:
7068 case SK_PNMI_HRX_MACC_UNKWN:
7069 case SK_PNMI_HRX_BURST:
7070 case SK_PNMI_HRX_MISSED:
7071 case SK_PNMI_HRX_FRAMING:
7072 case SK_PNMI_HRX_CARRIER:
7073 case SK_PNMI_HRX_IRLENGTH:
7074 case SK_PNMI_HRX_SYMBOL:
7075 case SK_PNMI_HRX_CEXT:
7076 /* Not supported by GMAC */
7077 if (MacType == SK_MAC_GMAC) {
7078 return (Val);
7079 }
7080
7081 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7082 StatAddr[StatIndex][MacType].Reg,
7083 &LowVal);
7084 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7085 break;
7086
7087 case SK_PNMI_HRX_PMACC_ERR:
7088 /* For GMAC the SW counter is managed by PNMI */
7089 if (MacType == SK_MAC_GMAC) {
7090 return (pPnmiPrt->StatRxPMaccErr);
7091 }
7092
7093 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7094 StatAddr[StatIndex][MacType].Reg,
7095 &LowVal);
7096 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7097 break;
7098
7099 /* SW counter managed by PNMI */
7100 case SK_PNMI_HTX_SYNC:
7101 LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
7102 HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
7103 break;
7104
7105 /* SW counter managed by PNMI */
7106 case SK_PNMI_HTX_SYNC_OCTET:
7107 LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
7108 HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
7109 break;
7110
7111 case SK_PNMI_HRX_FCS:
7112 /*
7113 * Broadcom filters FCS errors and counts it in
7114 * Receive Error Counter register
7115 */
7116 if (pPrt->PhyType == SK_PHY_BCOM) {
7117 /* do not read while not initialized (PHY_READ hangs!)*/
7118 if (pPrt->PState != SK_PRT_RESET) {
7119 SkXmPhyRead(pAC, IoC, PhysPortIndex, PHY_BCOM_RE_CTR, &Word);
7120
7121 LowVal = Word;
7122 }
7123 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7124 }
7125 else {
7126 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7127 StatAddr[StatIndex][MacType].Reg,
7128 &LowVal);
7129 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7130 }
7131 break;
7132
7133 default:
7134 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7135 StatAddr[StatIndex][MacType].Reg,
7136 &LowVal);
7137 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7138 break;
7139 }
7140
7141 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7142
7143 /* Correct value because of possible XMAC reset. XMAC Errata #2 */
7144 Val += pPnmiPrt->CounterOffset[StatIndex];
7145
7146 return (Val);
7147}
7148
7149/*****************************************************************************
7150 *
7151 * ResetCounter - Set all counters and timestamps to zero
7152 *
7153 * Description:
7154 * Notifies other common modules which store statistic data to
7155 * reset their counters and finally reset our own counters.
7156 *
7157 * Returns:
7158 * Nothing
7159 */
7160PNMI_STATIC void ResetCounter(
7161SK_AC *pAC, /* Pointer to adapter context */
7162SK_IOC IoC, /* IO context handle */
7163SK_U32 NetIndex)
7164{
7165 unsigned int PhysPortIndex;
7166 SK_EVPARA EventParam;
7167
7168
7169 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
7170
7171 /* Notify sensor module */
7172 SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
7173
7174 /* Notify RLMT module */
7175 EventParam.Para32[0] = NetIndex;
7176 EventParam.Para32[1] = (SK_U32)-1;
7177 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
7178 EventParam.Para32[1] = 0;
7179
7180 /* Notify SIRQ module */
7181 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
7182
7183 /* Notify CSUM module */
7184#ifdef SK_USE_CSUM
7185 EventParam.Para32[0] = NetIndex;
7186 EventParam.Para32[1] = (SK_U32)-1;
7187 SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
7188 EventParam);
7189#endif /* SK_USE_CSUM */
7190
7191 /* Clear XMAC statistic */
7192 for (PhysPortIndex = 0; PhysPortIndex <
7193 (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
7194
7195 (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex);
7196
7197 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
7198 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
7199 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7200 CounterOffset, 0, sizeof(pAC->Pnmi.Port[
7201 PhysPortIndex].CounterOffset));
7202 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
7203 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
7204 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7205 StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
7206 PhysPortIndex].StatSyncOctetsCts));
7207 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7208 StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
7209 PhysPortIndex].StatRxLongFrameCts));
7210 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7211 StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[
7212 PhysPortIndex].StatRxFrameTooLongCts));
7213 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7214 StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[
7215 PhysPortIndex].StatRxPMaccErr));
7216 }
7217
7218 /*
7219 * Clear local statistics
7220 */
7221 SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
7222 sizeof(pAC->Pnmi.VirtualCounterOffset));
7223 pAC->Pnmi.RlmtChangeCts = 0;
7224 pAC->Pnmi.RlmtChangeTime = 0;
7225 SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
7226 sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
7227 pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
7228 pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
7229 pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
7230 pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
7231 pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
7232 pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
7233 pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
7234 pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
7235 pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
7236 pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
7237 pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
7238 pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
7239}
7240
7241/*****************************************************************************
7242 *
7243 * GetTrapEntry - Get an entry in the trap buffer
7244 *
7245 * Description:
7246 * The trap buffer stores various events. A user application somehow
7247 * gets notified that an event occured and retrieves the trap buffer
7248 * contens (or simply polls the buffer). The buffer is organized as
7249 * a ring which stores the newest traps at the beginning. The oldest
7250 * traps are overwritten by the newest ones. Each trap entry has a
7251 * unique number, so that applications may detect new trap entries.
7252 *
7253 * Returns:
7254 * A pointer to the trap entry
7255 */
7256PNMI_STATIC char* GetTrapEntry(
7257SK_AC *pAC, /* Pointer to adapter context */
7258SK_U32 TrapId, /* SNMP ID of the trap */
7259unsigned int Size) /* Space needed for trap entry */
7260{
7261 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7262 unsigned int BufFree = pAC->Pnmi.TrapBufFree;
7263 unsigned int Beg = pAC->Pnmi.TrapQueueBeg;
7264 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7265 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7266 int Wrap;
7267 unsigned int NeededSpace;
7268 unsigned int EntrySize;
7269 SK_U32 Val32;
7270 SK_U64 Val64;
7271
7272
7273 /* Last byte of entry will get a copy of the entry length */
7274 Size ++;
7275
7276 /*
7277 * Calculate needed buffer space */
7278 if (Beg >= Size) {
7279
7280 NeededSpace = Size;
7281 Wrap = SK_FALSE;
7282 }
7283 else {
7284 NeededSpace = Beg + Size;
7285 Wrap = SK_TRUE;
7286 }
7287
7288 /*
7289 * Check if enough buffer space is provided. Otherwise
7290 * free some entries. Leave one byte space between begin
7291 * and end of buffer to make it possible to detect whether
7292 * the buffer is full or empty
7293 */
7294 while (BufFree < NeededSpace + 1) {
7295
7296 if (End == 0) {
7297
7298 End = SK_PNMI_TRAP_QUEUE_LEN;
7299 }
7300
7301 EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
7302 BufFree += EntrySize;
7303 End -= EntrySize;
7304#ifdef DEBUG
7305 SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
7306#endif /* DEBUG */
7307 if (End == BufPad) {
7308#ifdef DEBUG
7309 SK_MEMSET(pBuf, (char)(-1), End);
7310#endif /* DEBUG */
7311 BufFree += End;
7312 End = 0;
7313 BufPad = 0;
7314 }
7315 }
7316
7317 /*
7318 * Insert new entry as first entry. Newest entries are
7319 * stored at the beginning of the queue.
7320 */
7321 if (Wrap) {
7322
7323 BufPad = Beg;
7324 Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
7325 }
7326 else {
7327 Beg = Beg - Size;
7328 }
7329 BufFree -= NeededSpace;
7330
7331 /* Save the current offsets */
7332 pAC->Pnmi.TrapQueueBeg = Beg;
7333 pAC->Pnmi.TrapQueueEnd = End;
7334 pAC->Pnmi.TrapBufPad = BufPad;
7335 pAC->Pnmi.TrapBufFree = BufFree;
7336
7337 /* Initialize the trap entry */
7338 *(pBuf + Beg + Size - 1) = (char)Size;
7339 *(pBuf + Beg) = (char)Size;
7340 Val32 = (pAC->Pnmi.TrapUnique) ++;
7341 SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
7342 SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
7343 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
7344 SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
7345
7346 return (pBuf + Beg);
7347}
7348
7349/*****************************************************************************
7350 *
7351 * CopyTrapQueue - Copies the trap buffer for the TRAP OID
7352 *
7353 * Description:
7354 * On a query of the TRAP OID the trap buffer contents will be
7355 * copied continuously to the request buffer, which must be large
7356 * enough. No length check is performed.
7357 *
7358 * Returns:
7359 * Nothing
7360 */
7361PNMI_STATIC void CopyTrapQueue(
7362SK_AC *pAC, /* Pointer to adapter context */
7363char *pDstBuf) /* Buffer to which the queued traps will be copied */
7364{
7365 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7366 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7367 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7368 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7369 unsigned int Len;
7370 unsigned int DstOff = 0;
7371
7372
7373 while (Trap != End) {
7374
7375 Len = (unsigned int)*(pBuf + Trap);
7376
7377 /*
7378 * Last byte containing a copy of the length will
7379 * not be copied.
7380 */
7381 *(pDstBuf + DstOff) = (char)(Len - 1);
7382 SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
7383 DstOff += Len - 1;
7384
7385 Trap += Len;
7386 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7387
7388 Trap = BufPad;
7389 }
7390 }
7391}
7392
7393/*****************************************************************************
7394 *
7395 * GetTrapQueueLen - Get the length of the trap buffer
7396 *
7397 * Description:
7398 * Evaluates the number of currently stored traps and the needed
7399 * buffer size to retrieve them.
7400 *
7401 * Returns:
7402 * Nothing
7403 */
7404PNMI_STATIC void GetTrapQueueLen(
7405SK_AC *pAC, /* Pointer to adapter context */
7406unsigned int *pLen, /* Length in Bytes of all queued traps */
7407unsigned int *pEntries) /* Returns number of trapes stored in queue */
7408{
7409 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7410 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7411 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7412 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7413 unsigned int Len;
7414 unsigned int Entries = 0;
7415 unsigned int TotalLen = 0;
7416
7417
7418 while (Trap != End) {
7419
7420 Len = (unsigned int)*(pBuf + Trap);
7421 TotalLen += Len - 1;
7422 Entries ++;
7423
7424 Trap += Len;
7425 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7426
7427 Trap = BufPad;
7428 }
7429 }
7430
7431 *pEntries = Entries;
7432 *pLen = TotalLen;
7433}
7434
7435/*****************************************************************************
7436 *
7437 * QueueSimpleTrap - Store a simple trap to the trap buffer
7438 *
7439 * Description:
7440 * A simple trap is a trap with now additional data. It consists
7441 * simply of a trap code.
7442 *
7443 * Returns:
7444 * Nothing
7445 */
7446PNMI_STATIC void QueueSimpleTrap(
7447SK_AC *pAC, /* Pointer to adapter context */
7448SK_U32 TrapId) /* Type of sensor trap */
7449{
7450 GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
7451}
7452
7453/*****************************************************************************
7454 *
7455 * QueueSensorTrap - Stores a sensor trap in the trap buffer
7456 *
7457 * Description:
7458 * Gets an entry in the trap buffer and fills it with sensor related
7459 * data.
7460 *
7461 * Returns:
7462 * Nothing
7463 */
7464PNMI_STATIC void QueueSensorTrap(
7465SK_AC *pAC, /* Pointer to adapter context */
7466SK_U32 TrapId, /* Type of sensor trap */
7467unsigned int SensorIndex) /* Index of sensor which caused the trap */
7468{
7469 char *pBuf;
7470 unsigned int Offset;
7471 unsigned int DescrLen;
7472 SK_U32 Val32;
7473
7474
7475 /* Get trap buffer entry */
7476 DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
7477 pBuf = GetTrapEntry(pAC, TrapId,
7478 SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
7479 Offset = SK_PNMI_TRAP_SIMPLE_LEN;
7480
7481 /* Store additionally sensor trap related data */
7482 Val32 = OID_SKGE_SENSOR_INDEX;
7483 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7484 *(pBuf + Offset + 4) = 4;
7485 Val32 = (SK_U32)SensorIndex;
7486 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7487 Offset += 9;
7488
7489 Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
7490 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7491 *(pBuf + Offset + 4) = (char)DescrLen;
7492 SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
7493 DescrLen);
7494 Offset += DescrLen + 5;
7495
7496 Val32 = OID_SKGE_SENSOR_TYPE;
7497 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7498 *(pBuf + Offset + 4) = 1;
7499 *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
7500 Offset += 6;
7501
7502 Val32 = OID_SKGE_SENSOR_VALUE;
7503 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7504 *(pBuf + Offset + 4) = 4;
7505 Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
7506 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7507}
7508
7509/*****************************************************************************
7510 *
7511 * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
7512 *
7513 * Description:
7514 * Nothing further to explain.
7515 *
7516 * Returns:
7517 * Nothing
7518 */
7519PNMI_STATIC void QueueRlmtNewMacTrap(
7520SK_AC *pAC, /* Pointer to adapter context */
7521unsigned int ActiveMac) /* Index (0..n) of the currently active port */
7522{
7523 char *pBuf;
7524 SK_U32 Val32;
7525
7526
7527 pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
7528 SK_PNMI_TRAP_RLMT_CHANGE_LEN);
7529
7530 Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
7531 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7532 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7533 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
7534}
7535
7536/*****************************************************************************
7537 *
7538 * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
7539 *
7540 * Description:
7541 * Nothing further to explain.
7542 *
7543 * Returns:
7544 * Nothing
7545 */
7546PNMI_STATIC void QueueRlmtPortTrap(
7547SK_AC *pAC, /* Pointer to adapter context */
7548SK_U32 TrapId, /* Type of RLMT port trap */
7549unsigned int PortIndex) /* Index of the port, which changed its state */
7550{
7551 char *pBuf;
7552 SK_U32 Val32;
7553
7554
7555 pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
7556
7557 Val32 = OID_SKGE_RLMT_PORT_INDEX;
7558 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7559 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7560 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
7561}
7562
7563/*****************************************************************************
7564 *
7565 * CopyMac - Copies a MAC address
7566 *
7567 * Description:
7568 * Nothing further to explain.
7569 *
7570 * Returns:
7571 * Nothing
7572 */
7573PNMI_STATIC void CopyMac(
7574char *pDst, /* Pointer to destination buffer */
7575SK_MAC_ADDR *pMac) /* Pointer of Source */
7576{
7577 int i;
7578
7579
7580 for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
7581
7582 *(pDst + i) = pMac->a[i];
7583 }
7584}
7585
7586#ifdef SK_POWER_MGMT
7587/*****************************************************************************
7588 *
7589 * PowerManagement - OID handler function of PowerManagement OIDs
7590 *
7591 * Description:
7592 * The code is simple. No description necessary.
7593 *
7594 * Returns:
7595 * SK_PNMI_ERR_OK The request was successfully performed.
7596 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7597 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7598 * the correct data (e.g. a 32bit value is
7599 * needed, but a 16 bit value was passed).
7600 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7601 * exist (e.g. port instance 3 on a two port
7602 * adapter.
7603 */
7604
7605PNMI_STATIC int PowerManagement(
7606SK_AC *pAC, /* Pointer to adapter context */
7607SK_IOC IoC, /* IO context handle */
7608int Action, /* Get/PreSet/Set action */
7609SK_U32 Id, /* Object ID that is to be processed */
7610char *pBuf, /* Buffer to which to mgmt data will be retrieved */
7611unsigned int *pLen, /* On call: buffer length. On return: used buffer */
7612SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7613unsigned int TableIndex, /* Index to the Id table */
7614SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
7615{
7616
7617 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7618
7619 /*
7620 * Check instance. We only handle single instance variables
7621 */
7622 if (Instance != (SK_U32)(-1) && Instance != 1) {
7623
7624 *pLen = 0;
7625 return (SK_PNMI_ERR_UNKNOWN_INST);
7626 }
7627
7628
7629 /* Check length */
7630 switch (Id) {
7631
7632 case OID_PNP_CAPABILITIES:
7633 if (*pLen < sizeof(SK_PNP_CAPABILITIES)) {
7634
7635 *pLen = sizeof(SK_PNP_CAPABILITIES);
7636 return (SK_PNMI_ERR_TOO_SHORT);
7637 }
7638 break;
7639
7640 case OID_PNP_SET_POWER:
7641 case OID_PNP_QUERY_POWER:
7642 if (*pLen < sizeof(SK_DEVICE_POWER_STATE))
7643 {
7644 *pLen = sizeof(SK_DEVICE_POWER_STATE);
7645 return (SK_PNMI_ERR_TOO_SHORT);
7646 }
7647 break;
7648
7649 case OID_PNP_ADD_WAKE_UP_PATTERN:
7650 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7651 if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) {
7652
7653 *pLen = sizeof(SK_PM_PACKET_PATTERN);
7654 return (SK_PNMI_ERR_TOO_SHORT);
7655 }
7656 break;
7657
7658 case OID_PNP_ENABLE_WAKE_UP:
7659 if (*pLen < sizeof(SK_U32)) {
7660
7661 *pLen = sizeof(SK_U32);
7662 return (SK_PNMI_ERR_TOO_SHORT);
7663 }
7664 break;
7665 }
7666
7667 /*
7668 * Perform action
7669 */
7670 if (Action == SK_PNMI_GET) {
7671
7672 /*
7673 * Get value
7674 */
7675 switch (Id) {
7676
7677 case OID_PNP_CAPABILITIES:
7678 RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen);
7679 break;
7680
7681 case OID_PNP_QUERY_POWER:
7682 /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
7683 the miniport to indicate whether it can transition its NIC
7684 to the low-power state.
7685 A miniport driver must always return NDIS_STATUS_SUCCESS
7686 to a query of OID_PNP_QUERY_POWER. */
7687 *pLen = sizeof(SK_DEVICE_POWER_STATE);
7688 RetCode = SK_PNMI_ERR_OK;
7689 break;
7690
7691 /* NDIS handles these OIDs as write-only.
7692 * So in case of get action the buffer with written length = 0
7693 * is returned
7694 */
7695 case OID_PNP_SET_POWER:
7696 case OID_PNP_ADD_WAKE_UP_PATTERN:
7697 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7698 *pLen = 0;
7699 RetCode = SK_PNMI_ERR_NOT_SUPPORTED;
7700 break;
7701
7702 case OID_PNP_ENABLE_WAKE_UP:
7703 RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen);
7704 break;
7705
7706 default:
7707 RetCode = SK_PNMI_ERR_GENERAL;
7708 break;
7709 }
7710
7711 return (RetCode);
7712 }
7713
7714
7715 /*
7716 * Perform preset or set
7717 */
7718
7719 /* POWER module does not support PRESET action */
7720 if (Action == SK_PNMI_PRESET) {
7721 return (SK_PNMI_ERR_OK);
7722 }
7723
7724 switch (Id) {
7725 case OID_PNP_SET_POWER:
7726 RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen);
7727 break;
7728
7729 case OID_PNP_ADD_WAKE_UP_PATTERN:
7730 RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen);
7731 break;
7732
7733 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7734 RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen);
7735 break;
7736
7737 case OID_PNP_ENABLE_WAKE_UP:
7738 RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen);
7739 break;
7740
7741 default:
7742 RetCode = SK_PNMI_ERR_READ_ONLY;
7743 }
7744
7745 return (RetCode);
7746}
7747#endif /* SK_POWER_MGMT */
7748
7749#ifdef SK_DIAG_SUPPORT
7750/*****************************************************************************
7751 *
7752 * DiagActions - OID handler function of Diagnostic driver
7753 *
7754 * Description:
7755 * The code is simple. No description necessary.
7756 *
7757 * Returns:
7758 * SK_PNMI_ERR_OK The request was successfully performed.
7759 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7760 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7761 * the correct data (e.g. a 32bit value is
7762 * needed, but a 16 bit value was passed).
7763 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7764 * exist (e.g. port instance 3 on a two port
7765 * adapter.
7766 */
7767
7768PNMI_STATIC int DiagActions(
7769SK_AC *pAC, /* Pointer to adapter context */
7770SK_IOC IoC, /* IO context handle */
7771int Action, /* GET/PRESET/SET action */
7772SK_U32 Id, /* Object ID that is to be processed */
7773char *pBuf, /* Buffer used for the management data transfer */
7774unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
7775SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7776unsigned int TableIndex, /* Index to the Id table */
7777SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
7778{
7779
7780 SK_U32 DiagStatus;
7781 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7782
7783 /*
7784 * Check instance. We only handle single instance variables.
7785 */
7786 if (Instance != (SK_U32)(-1) && Instance != 1) {
7787
7788 *pLen = 0;
7789 return (SK_PNMI_ERR_UNKNOWN_INST);
7790 }
7791
7792 /*
7793 * Check length.
7794 */
7795 switch (Id) {
7796
7797 case OID_SKGE_DIAG_MODE:
7798 if (*pLen < sizeof(SK_U32)) {
7799
7800 *pLen = sizeof(SK_U32);
7801 return (SK_PNMI_ERR_TOO_SHORT);
7802 }
7803 break;
7804
7805 default:
7806 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040, SK_PNMI_ERR040MSG);
7807 *pLen = 0;
7808 return (SK_PNMI_ERR_GENERAL);
7809 }
7810
7811 /* Perform action. */
7812
7813 /* GET value. */
7814 if (Action == SK_PNMI_GET) {
7815
7816 switch (Id) {
7817
7818 case OID_SKGE_DIAG_MODE:
7819 DiagStatus = pAC->Pnmi.DiagAttached;
7820 SK_PNMI_STORE_U32(pBuf, DiagStatus);
7821 *pLen = sizeof(SK_U32);
7822 RetCode = SK_PNMI_ERR_OK;
7823 break;
7824
7825 default:
7826 *pLen = 0;
7827 RetCode = SK_PNMI_ERR_GENERAL;
7828 break;
7829 }
7830 return (RetCode);
7831 }
7832
7833 /* From here SET or PRESET value. */
7834
7835 /* PRESET value is not supported. */
7836 if (Action == SK_PNMI_PRESET) {
7837 return (SK_PNMI_ERR_OK);
7838 }
7839
7840 /* SET value. */
7841 switch (Id) {
7842 case OID_SKGE_DIAG_MODE:
7843
7844 /* Handle the SET. */
7845 switch (*pBuf) {
7846
7847 /* Attach the DIAG to this adapter. */
7848 case SK_DIAG_ATTACHED:
7849 /* Check if we come from running */
7850 if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
7851
7852 RetCode = SkDrvLeaveDiagMode(pAC);
7853
7854 }
7855 else if (pAC->Pnmi.DiagAttached == SK_DIAG_IDLE) {
7856
7857 RetCode = SK_PNMI_ERR_OK;
7858 }
7859
7860 else {
7861
7862 RetCode = SK_PNMI_ERR_GENERAL;
7863
7864 }
7865
7866 if (RetCode == SK_PNMI_ERR_OK) {
7867
7868 pAC->Pnmi.DiagAttached = SK_DIAG_ATTACHED;
7869 }
7870 break;
7871
7872 /* Enter the DIAG mode in the driver. */
7873 case SK_DIAG_RUNNING:
7874 RetCode = SK_PNMI_ERR_OK;
7875
7876 /*
7877 * If DiagAttached is set, we can tell the driver
7878 * to enter the DIAG mode.
7879 */
7880 if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
7881 /* If DiagMode is not active, we can enter it. */
7882 if (!pAC->DiagModeActive) {
7883
7884 RetCode = SkDrvEnterDiagMode(pAC);
7885 }
7886 else {
7887
7888 RetCode = SK_PNMI_ERR_GENERAL;
7889 }
7890 }
7891 else {
7892
7893 RetCode = SK_PNMI_ERR_GENERAL;
7894 }
7895
7896 if (RetCode == SK_PNMI_ERR_OK) {
7897
7898 pAC->Pnmi.DiagAttached = SK_DIAG_RUNNING;
7899 }
7900 break;
7901
7902 case SK_DIAG_IDLE:
7903 /* Check if we come from running */
7904 if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
7905
7906 RetCode = SkDrvLeaveDiagMode(pAC);
7907
7908 }
7909 else if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
7910
7911 RetCode = SK_PNMI_ERR_OK;
7912 }
7913
7914 else {
7915
7916 RetCode = SK_PNMI_ERR_GENERAL;
7917
7918 }
7919
7920 if (RetCode == SK_PNMI_ERR_OK) {
7921
7922 pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
7923 }
7924 break;
7925
7926 default:
7927 RetCode = SK_PNMI_ERR_BAD_VALUE;
7928 break;
7929 }
7930 break;
7931
7932 default:
7933 RetCode = SK_PNMI_ERR_GENERAL;
7934 }
7935
7936 if (RetCode == SK_PNMI_ERR_OK) {
7937 *pLen = sizeof(SK_U32);
7938 }
7939 else {
7940
7941 *pLen = 0;
7942 }
7943 return (RetCode);
7944}
7945#endif /* SK_DIAG_SUPPORT */
7946
7947/*****************************************************************************
7948 *
7949 * Vct - OID handler function of OIDs
7950 *
7951 * Description:
7952 * The code is simple. No description necessary.
7953 *
7954 * Returns:
7955 * SK_PNMI_ERR_OK The request was performed successfully.
7956 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7957 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7958 * the correct data (e.g. a 32bit value is
7959 * needed, but a 16 bit value was passed).
7960 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7961 * exist (e.g. port instance 3 on a two port
7962 * adapter).
7963 * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed.
7964 *
7965 */
7966
7967PNMI_STATIC int Vct(
7968SK_AC *pAC, /* Pointer to adapter context */
7969SK_IOC IoC, /* IO context handle */
7970int Action, /* GET/PRESET/SET action */
7971SK_U32 Id, /* Object ID that is to be processed */
7972char *pBuf, /* Buffer used for the management data transfer */
7973unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
7974SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */
7975unsigned int TableIndex, /* Index to the Id table */
7976SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
7977{
7978 SK_GEPORT *pPrt;
7979 SK_PNMI_VCT *pVctBackupData;
7980 SK_U32 LogPortMax;
7981 SK_U32 PhysPortMax;
7982 SK_U32 PhysPortIndex;
7983 SK_U32 Limit;
7984 SK_U32 Offset;
7985 SK_BOOL Link;
7986 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7987 int i;
7988 SK_EVPARA Para;
7989 SK_U32 CableLength;
7990
7991 /*
7992 * Calculate the port indexes from the instance.
7993 */
7994 PhysPortMax = pAC->GIni.GIMacsFound;
7995 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
7996
7997 /* Dual net mode? */
7998 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
7999 LogPortMax--;
8000 }
8001
8002 if ((Instance != (SK_U32) (-1))) {
8003 /* Check instance range. */
8004 if ((Instance < 2) || (Instance > LogPortMax)) {
8005 *pLen = 0;
8006 return (SK_PNMI_ERR_UNKNOWN_INST);
8007 }
8008
8009 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
8010 PhysPortIndex = NetIndex;
8011 }
8012 else {
8013 PhysPortIndex = Instance - 2;
8014 }
8015 Limit = PhysPortIndex + 1;
8016 }
8017 else {
8018 /*
8019 * Instance == (SK_U32) (-1), get all Instances of that OID.
8020 *
8021 * Not implemented yet. May be used in future releases.
8022 */
8023 PhysPortIndex = 0;
8024 Limit = PhysPortMax;
8025 }
8026
8027 pPrt = &pAC->GIni.GP[PhysPortIndex];
8028 if (pPrt->PHWLinkUp) {
8029 Link = SK_TRUE;
8030 }
8031 else {
8032 Link = SK_FALSE;
8033 }
8034
8035 /* Check MAC type */
8036 if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
8037 *pLen = 0;
8038 return (SK_PNMI_ERR_GENERAL);
8039 }
8040
8041 /* Initialize backup data pointer. */
8042 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
8043
8044 /* Check action type */
8045 if (Action == SK_PNMI_GET) {
8046 /* Check length */
8047 switch (Id) {
8048
8049 case OID_SKGE_VCT_GET:
8050 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
8051 *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
8052 return (SK_PNMI_ERR_TOO_SHORT);
8053 }
8054 break;
8055
8056 case OID_SKGE_VCT_STATUS:
8057 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
8058 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
8059 return (SK_PNMI_ERR_TOO_SHORT);
8060 }
8061 break;
8062
8063 default:
8064 *pLen = 0;
8065 return (SK_PNMI_ERR_GENERAL);
8066 }
8067
8068 /* Get value */
8069 Offset = 0;
8070 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8071 switch (Id) {
8072
8073 case OID_SKGE_VCT_GET:
8074 if ((Link == SK_FALSE) &&
8075 (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
8076 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
8077 if (RetCode == 0) {
8078 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
8079 pAC->Pnmi.VctStatus[PhysPortIndex] |=
8080 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
8081
8082 /* Copy results for later use to PNMI struct. */
8083 for (i = 0; i < 4; i++) {
8084 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
8085 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
8086 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
8087 }
8088 }
8089 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
8090 CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
8091 }
8092 else {
8093 CableLength = 0;
8094 }
8095 pVctBackupData->PMdiPairLen[i] = CableLength;
8096 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
8097 }
8098
8099 Para.Para32[0] = PhysPortIndex;
8100 Para.Para32[1] = -1;
8101 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
8102 SkEventDispatcher(pAC, IoC);
8103 }
8104 else {
8105 ; /* VCT test is running. */
8106 }
8107 }
8108
8109 /* Get all results. */
8110 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
8111 Offset += sizeof(SK_U8);
8112 *(pBuf + Offset) = pPrt->PCableLen;
8113 Offset += sizeof(SK_U8);
8114 for (i = 0; i < 4; i++) {
8115 SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
8116 Offset += sizeof(SK_U32);
8117 }
8118 for (i = 0; i < 4; i++) {
8119 *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
8120 Offset += sizeof(SK_U8);
8121 }
8122
8123 RetCode = SK_PNMI_ERR_OK;
8124 break;
8125
8126 case OID_SKGE_VCT_STATUS:
8127 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
8128 Offset += sizeof(SK_U8);
8129 RetCode = SK_PNMI_ERR_OK;
8130 break;
8131
8132 default:
8133 *pLen = 0;
8134 return (SK_PNMI_ERR_GENERAL);
8135 }
8136 } /* for */
8137 *pLen = Offset;
8138 return (RetCode);
8139
8140 } /* if SK_PNMI_GET */
8141
8142 /*
8143 * From here SET or PRESET action. Check if the passed
8144 * buffer length is plausible.
8145 */
8146
8147 /* Check length */
8148 switch (Id) {
8149 case OID_SKGE_VCT_SET:
8150 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
8151 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
8152 return (SK_PNMI_ERR_TOO_SHORT);
8153 }
8154 break;
8155
8156 default:
8157 *pLen = 0;
8158 return (SK_PNMI_ERR_GENERAL);
8159 }
8160
8161 /*
8162 * Perform preset or set.
8163 */
8164
8165 /* VCT does not support PRESET action. */
8166 if (Action == SK_PNMI_PRESET) {
8167 return (SK_PNMI_ERR_OK);
8168 }
8169
8170 Offset = 0;
8171 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8172 switch (Id) {
8173 case OID_SKGE_VCT_SET: /* Start VCT test. */
8174 if (Link == SK_FALSE) {
8175 SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
8176
8177 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
8178 if (RetCode == 0) { /* RetCode: 0 => Start! */
8179 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
8180 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8181 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
8182
8183 /*
8184 * Start VCT timer counter.
8185 */
8186 SK_MEMSET((char *) &Para, 0, sizeof(Para));
8187 Para.Para32[0] = PhysPortIndex;
8188 Para.Para32[1] = -1;
8189 SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
8190 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
8191 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8192 RetCode = SK_PNMI_ERR_OK;
8193 }
8194 else { /* RetCode: 2 => Running! */
8195 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8196 RetCode = SK_PNMI_ERR_OK;
8197 }
8198 }
8199 else { /* RetCode: 4 => Link! */
8200 RetCode = 4;
8201 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8202 RetCode = SK_PNMI_ERR_OK;
8203 }
8204 Offset += sizeof(SK_U32);
8205 break;
8206
8207 default:
8208 *pLen = 0;
8209 return (SK_PNMI_ERR_GENERAL);
8210 }
8211 } /* for */
8212 *pLen = Offset;
8213 return (RetCode);
8214
8215} /* Vct */
8216
8217
8218PNMI_STATIC void CheckVctStatus(
8219SK_AC *pAC,
8220SK_IOC IoC,
8221char *pBuf,
8222SK_U32 Offset,
8223SK_U32 PhysPortIndex)
8224{
8225 SK_GEPORT *pPrt;
8226 SK_PNMI_VCT *pVctData;
8227 SK_U32 RetCode;
8228
8229 pPrt = &pAC->GIni.GP[PhysPortIndex];
8230
8231 pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
8232 pVctData->VctStatus = SK_PNMI_VCT_NONE;
8233
8234 if (!pPrt->PHWLinkUp) {
8235
8236 /* Was a VCT test ever made before? */
8237 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8238 if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
8239 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8240 }
8241 else {
8242 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8243 }
8244 }
8245
8246 /* Check VCT test status. */
8247 RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
8248 if (RetCode == 2) { /* VCT test is running. */
8249 pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
8250 }
8251 else { /* VCT data was copied to pAC here. Check PENDING state. */
8252 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
8253 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8254 }
8255 }
8256
8257 if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
8258 pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
8259 }
8260 }
8261 else {
8262
8263 /* Was a VCT test ever made before? */
8264 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8265 pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8266 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8267 }
8268
8269 /* DSP only valid in 100/1000 modes. */
8270 if (pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed !=
8271 SK_LSPEED_STAT_10MBPS) {
8272 pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
8273 }
8274 }
8275} /* CheckVctStatus */
8276
8277
8278/*****************************************************************************
8279 *
8280 * SkPnmiGenIoctl - Handles new generic PNMI IOCTL, calls the needed
8281 * PNMI function depending on the subcommand and
8282 * returns all data belonging to the complete database
8283 * or OID request.
8284 *
8285 * Description:
8286 * Looks up the requested subcommand, calls the corresponding handler
8287 * function and passes all required parameters to it.
8288 * The function is called by the driver. It is needed to handle the new
8289 * generic PNMI IOCTL. This IOCTL is given to the driver and contains both
8290 * the OID and a subcommand to decide what kind of request has to be done.
8291 *
8292 * Returns:
8293 * SK_PNMI_ERR_OK The request was successfully performed
8294 * SK_PNMI_ERR_GENERAL A general severe internal error occured
8295 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
8296 * the data.
8297 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
8298 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
8299 * exist (e.g. port instance 3 on a two port
8300 * adapter.
8301 */
8302int SkPnmiGenIoctl(
8303SK_AC *pAC, /* Pointer to adapter context struct */
8304SK_IOC IoC, /* I/O context */
8305void *pBuf, /* Buffer used for the management data transfer */
8306unsigned int *pLen, /* Length of buffer */
8307SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
8308{
8309SK_I32 Mode; /* Store value of subcommand. */
8310SK_U32 Oid; /* Store value of OID. */
8311int ReturnCode; /* Store return value to show status of PNMI action. */
8312int HeaderLength; /* Length of desired action plus OID. */
8313
8314 ReturnCode = SK_PNMI_ERR_GENERAL;
8315
8316 SK_MEMCPY(&Mode, pBuf, sizeof(SK_I32));
8317 SK_MEMCPY(&Oid, (char *) pBuf + sizeof(SK_I32), sizeof(SK_U32));
8318 HeaderLength = sizeof(SK_I32) + sizeof(SK_U32);
8319 *pLen = *pLen - HeaderLength;
8320 SK_MEMCPY((char *) pBuf + sizeof(SK_I32), (char *) pBuf + HeaderLength, *pLen);
8321
8322 switch(Mode) {
8323 case SK_GET_SINGLE_VAR:
8324 ReturnCode = SkPnmiGetVar(pAC, IoC, Oid,
8325 (char *) pBuf + sizeof(SK_I32), pLen,
8326 ((SK_U32) (-1)), NetIndex);
8327 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8328 *pLen = *pLen + sizeof(SK_I32);
8329 break;
8330 case SK_PRESET_SINGLE_VAR:
8331 ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid,
8332 (char *) pBuf + sizeof(SK_I32), pLen,
8333 ((SK_U32) (-1)), NetIndex);
8334 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8335 *pLen = *pLen + sizeof(SK_I32);
8336 break;
8337 case SK_SET_SINGLE_VAR:
8338 ReturnCode = SkPnmiSetVar(pAC, IoC, Oid,
8339 (char *) pBuf + sizeof(SK_I32), pLen,
8340 ((SK_U32) (-1)), NetIndex);
8341 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8342 *pLen = *pLen + sizeof(SK_I32);
8343 break;
8344 case SK_GET_FULL_MIB:
8345 ReturnCode = SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8346 break;
8347 case SK_PRESET_FULL_MIB:
8348 ReturnCode = SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8349 break;
8350 case SK_SET_FULL_MIB:
8351 ReturnCode = SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8352 break;
8353 default:
8354 break;
8355 }
8356
8357 return (ReturnCode);
8358
8359} /* SkGeIocGen */
diff --git a/drivers/net/sk98lin/skgesirq.c b/drivers/net/sk98lin/skgesirq.c
new file mode 100644
index 000000000000..87520f0057d7
--- /dev/null
+++ b/drivers/net/sk98lin/skgesirq.c
@@ -0,0 +1,2251 @@
1/******************************************************************************
2 *
3 * Name: skgesirq.c
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.92 $
6 * Date: $Date: 2003/09/16 14:37:07 $
7 * Purpose: Special IRQ module
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * Special Interrupt handler
27 *
28 * The following abstract should show how this module is included
29 * in the driver path:
30 *
31 * In the ISR of the driver the bits for frame transmission complete and
32 * for receive complete are checked and handled by the driver itself.
33 * The bits of the slow path mask are checked after that and then the
34 * entry into the so-called "slow path" is prepared. It is an implementors
35 * decision whether this is executed directly or just scheduled by
36 * disabling the mask. In the interrupt service routine some events may be
37 * generated, so it would be a good idea to call the EventDispatcher
38 * right after this ISR.
39 *
40 * The Interrupt source register of the adapter is NOT read by this module.
41 * SO if the drivers implementor needs a while loop around the
42 * slow data paths interrupt bits, he needs to call the SkGeSirqIsr() for
43 * each loop entered.
44 *
45 * However, the MAC Interrupt status registers are read in a while loop.
46 *
47 */
48
49#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
50static const char SysKonnectFileId[] =
51 "@(#) $Id: skgesirq.c,v 1.92 2003/09/16 14:37:07 rschmidt Exp $ (C) Marvell.";
52#endif
53
54#include "h/skdrv1st.h" /* Driver Specific Definitions */
55#ifndef SK_SLIM
56#include "h/skgepnmi.h" /* PNMI Definitions */
57#include "h/skrlmt.h" /* RLMT Definitions */
58#endif
59#include "h/skdrv2nd.h" /* Adapter Control and Driver specific Def. */
60
61/* local function prototypes */
62#ifdef GENESIS
63static int SkGePortCheckUpXmac(SK_AC*, SK_IOC, int, SK_BOOL);
64static int SkGePortCheckUpBcom(SK_AC*, SK_IOC, int, SK_BOOL);
65static void SkPhyIsrBcom(SK_AC*, SK_IOC, int, SK_U16);
66#endif /* GENESIS */
67#ifdef YUKON
68static int SkGePortCheckUpGmac(SK_AC*, SK_IOC, int, SK_BOOL);
69static void SkPhyIsrGmac(SK_AC*, SK_IOC, int, SK_U16);
70#endif /* YUKON */
71#ifdef OTHER_PHY
72static int SkGePortCheckUpLone(SK_AC*, SK_IOC, int, SK_BOOL);
73static int SkGePortCheckUpNat(SK_AC*, SK_IOC, int, SK_BOOL);
74static void SkPhyIsrLone(SK_AC*, SK_IOC, int, SK_U16);
75#endif /* OTHER_PHY */
76
77#ifdef GENESIS
78/*
79 * array of Rx counter from XMAC which are checked
80 * in AutoSense mode to check whether a link is not able to auto-negotiate.
81 */
82static const SK_U16 SkGeRxRegs[]= {
83 XM_RXF_64B,
84 XM_RXF_127B,
85 XM_RXF_255B,
86 XM_RXF_511B,
87 XM_RXF_1023B,
88 XM_RXF_MAX_SZ
89} ;
90#endif /* GENESIS */
91
92#ifdef __C2MAN__
93/*
94 * Special IRQ function
95 *
96 * General Description:
97 *
98 */
99intro()
100{}
101#endif
102
103/******************************************************************************
104 *
105 * SkHWInitDefSense() - Default Autosensing mode initialization
106 *
107 * Description: sets the PLinkMode for HWInit
108 *
109 * Returns: N/A
110 */
111static void SkHWInitDefSense(
112SK_AC *pAC, /* adapter context */
113SK_IOC IoC, /* IO context */
114int Port) /* Port Index (MAC_1 + n) */
115{
116 SK_GEPORT *pPrt; /* GIni Port struct pointer */
117
118 pPrt = &pAC->GIni.GP[Port];
119
120 pPrt->PAutoNegTimeOut = 0;
121
122 if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) {
123 pPrt->PLinkMode = pPrt->PLinkModeConf;
124 return;
125 }
126
127 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
128 ("AutoSensing: First mode %d on Port %d\n",
129 (int)SK_LMODE_AUTOFULL, Port));
130
131 pPrt->PLinkMode = (SK_U8)SK_LMODE_AUTOFULL;
132
133 return;
134} /* SkHWInitDefSense */
135
136
137#ifdef GENESIS
138/******************************************************************************
139 *
140 * SkHWSenseGetNext() - Get Next Autosensing Mode
141 *
142 * Description: gets the appropriate next mode
143 *
144 * Note:
145 *
146 */
147static SK_U8 SkHWSenseGetNext(
148SK_AC *pAC, /* adapter context */
149SK_IOC IoC, /* IO context */
150int Port) /* Port Index (MAC_1 + n) */
151{
152 SK_GEPORT *pPrt; /* GIni Port struct pointer */
153
154 pPrt = &pAC->GIni.GP[Port];
155
156 pPrt->PAutoNegTimeOut = 0;
157
158 if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) {
159 /* Leave all as configured */
160 return(pPrt->PLinkModeConf);
161 }
162
163 if (pPrt->PLinkMode == (SK_U8)SK_LMODE_AUTOFULL) {
164 /* Return next mode AUTOBOTH */
165 return ((SK_U8)SK_LMODE_AUTOBOTH);
166 }
167
168 /* Return default autofull */
169 return ((SK_U8)SK_LMODE_AUTOFULL);
170} /* SkHWSenseGetNext */
171
172
173/******************************************************************************
174 *
175 * SkHWSenseSetNext() - Autosensing Set next mode
176 *
177 * Description: sets the appropriate next mode
178 *
179 * Returns: N/A
180 */
181static void SkHWSenseSetNext(
182SK_AC *pAC, /* adapter context */
183SK_IOC IoC, /* IO context */
184int Port, /* Port Index (MAC_1 + n) */
185SK_U8 NewMode) /* New Mode to be written in sense mode */
186{
187 SK_GEPORT *pPrt; /* GIni Port struct pointer */
188
189 pPrt = &pAC->GIni.GP[Port];
190
191 pPrt->PAutoNegTimeOut = 0;
192
193 if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) {
194 return;
195 }
196
197 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
198 ("AutoSensing: next mode %d on Port %d\n",
199 (int)NewMode, Port));
200
201 pPrt->PLinkMode = NewMode;
202
203 return;
204} /* SkHWSenseSetNext */
205#endif /* GENESIS */
206
207
208/******************************************************************************
209 *
210 * SkHWLinkDown() - Link Down handling
211 *
212 * Description: handles the hardware link down signal
213 *
214 * Returns: N/A
215 */
216void SkHWLinkDown(
217SK_AC *pAC, /* adapter context */
218SK_IOC IoC, /* IO context */
219int Port) /* Port Index (MAC_1 + n) */
220{
221 SK_GEPORT *pPrt; /* GIni Port struct pointer */
222
223 pPrt = &pAC->GIni.GP[Port];
224
225 /* Disable all MAC interrupts */
226 SkMacIrqDisable(pAC, IoC, Port);
227
228 /* Disable Receiver and Transmitter */
229 SkMacRxTxDisable(pAC, IoC, Port);
230
231 /* Init default sense mode */
232 SkHWInitDefSense(pAC, IoC, Port);
233
234 if (pPrt->PHWLinkUp == SK_FALSE) {
235 return;
236 }
237
238 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
239 ("Link down Port %d\n", Port));
240
241 /* Set Link to DOWN */
242 pPrt->PHWLinkUp = SK_FALSE;
243
244 /* Reset Port stati */
245 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
246 pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
247 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_INDETERMINATED;
248
249 /* Re-init Phy especially when the AutoSense default is set now */
250 SkMacInitPhy(pAC, IoC, Port, SK_FALSE);
251
252 /* GP0: used for workaround of Rev. C Errata 2 */
253
254 /* Do NOT signal to RLMT */
255
256 /* Do NOT start the timer here */
257} /* SkHWLinkDown */
258
259
260/******************************************************************************
261 *
262 * SkHWLinkUp() - Link Up handling
263 *
264 * Description: handles the hardware link up signal
265 *
266 * Returns: N/A
267 */
268void SkHWLinkUp(
269SK_AC *pAC, /* adapter context */
270SK_IOC IoC, /* IO context */
271int Port) /* Port Index (MAC_1 + n) */
272{
273 SK_GEPORT *pPrt; /* GIni Port struct pointer */
274
275 pPrt = &pAC->GIni.GP[Port];
276
277 if (pPrt->PHWLinkUp) {
278 /* We do NOT need to proceed on active link */
279 return;
280 }
281
282 pPrt->PHWLinkUp = SK_TRUE;
283 pPrt->PAutoNegFail = SK_FALSE;
284 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
285
286 if (pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOHALF &&
287 pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOFULL &&
288 pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOBOTH) {
289 /* Link is up and no Auto-negotiation should be done */
290
291 /* Link speed should be the configured one */
292 switch (pPrt->PLinkSpeed) {
293 case SK_LSPEED_AUTO:
294 /* default is 1000 Mbps */
295 case SK_LSPEED_1000MBPS:
296 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
297 break;
298 case SK_LSPEED_100MBPS:
299 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS;
300 break;
301 case SK_LSPEED_10MBPS:
302 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS;
303 break;
304 }
305
306 /* Set Link Mode Status */
307 if (pPrt->PLinkMode == SK_LMODE_FULL) {
308 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_FULL;
309 }
310 else {
311 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_HALF;
312 }
313
314 /* No flow control without auto-negotiation */
315 pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
316
317 /* enable Rx/Tx */
318 (void)SkMacRxTxEnable(pAC, IoC, Port);
319 }
320} /* SkHWLinkUp */
321
322
323/******************************************************************************
324 *
325 * SkMacParity() - MAC parity workaround
326 *
327 * Description: handles MAC parity errors correctly
328 *
329 * Returns: N/A
330 */
331static void SkMacParity(
332SK_AC *pAC, /* adapter context */
333SK_IOC IoC, /* IO context */
334int Port) /* Port Index of the port failed */
335{
336 SK_EVPARA Para;
337 SK_GEPORT *pPrt; /* GIni Port struct pointer */
338 SK_U32 TxMax; /* Tx Max Size Counter */
339
340 pPrt = &pAC->GIni.GP[Port];
341
342 /* Clear IRQ Tx Parity Error */
343#ifdef GENESIS
344 if (pAC->GIni.GIGenesis) {
345
346 SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_PERR);
347 }
348#endif /* GENESIS */
349
350#ifdef YUKON
351 if (pAC->GIni.GIYukon) {
352 /* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */
353 SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T),
354 (SK_U8)((pAC->GIni.GIChipId == CHIP_ID_YUKON &&
355 pAC->GIni.GIChipRev == 0) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE));
356 }
357#endif /* YUKON */
358
359 if (pPrt->PCheckPar) {
360
361 if (Port == MAC_1) {
362 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E016, SKERR_SIRQ_E016MSG);
363 }
364 else {
365 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E017, SKERR_SIRQ_E017MSG);
366 }
367 Para.Para64 = Port;
368 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
369
370 Para.Para32[0] = Port;
371 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
372
373 return;
374 }
375
376 /* Check whether frames with a size of 1k were sent */
377#ifdef GENESIS
378 if (pAC->GIni.GIGenesis) {
379 /* Snap statistic counters */
380 (void)SkXmUpdateStats(pAC, IoC, Port);
381
382 (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXF_MAX_SZ, &TxMax);
383 }
384#endif /* GENESIS */
385
386#ifdef YUKON
387 if (pAC->GIni.GIYukon) {
388
389 (void)SkGmMacStatistic(pAC, IoC, Port, GM_TXF_1518B, &TxMax);
390 }
391#endif /* YUKON */
392
393 if (TxMax > 0) {
394 /* From now on check the parity */
395 pPrt->PCheckPar = SK_TRUE;
396 }
397} /* SkMacParity */
398
399
400/******************************************************************************
401 *
402 * SkGeHwErr() - Hardware Error service routine
403 *
404 * Description: handles all HW Error interrupts
405 *
406 * Returns: N/A
407 */
408static void SkGeHwErr(
409SK_AC *pAC, /* adapter context */
410SK_IOC IoC, /* IO context */
411SK_U32 HwStatus) /* Interrupt status word */
412{
413 SK_EVPARA Para;
414 SK_U16 Word;
415
416 if ((HwStatus & (IS_IRQ_MST_ERR | IS_IRQ_STAT)) != 0) {
417 /* PCI Errors occured */
418 if ((HwStatus & IS_IRQ_STAT) != 0) {
419 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E013, SKERR_SIRQ_E013MSG);
420 }
421 else {
422 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E012, SKERR_SIRQ_E012MSG);
423 }
424
425 /* Reset all bits in the PCI STATUS register */
426 SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
427
428 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
429 SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
430 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
431
432 Para.Para64 = 0;
433 SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
434 }
435
436#ifdef GENESIS
437 if (pAC->GIni.GIGenesis) {
438
439 if ((HwStatus & IS_NO_STAT_M1) != 0) {
440 /* Ignore it */
441 /* This situation is also indicated in the descriptor */
442 SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INSTAT);
443 }
444
445 if ((HwStatus & IS_NO_STAT_M2) != 0) {
446 /* Ignore it */
447 /* This situation is also indicated in the descriptor */
448 SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INSTAT);
449 }
450
451 if ((HwStatus & IS_NO_TIST_M1) != 0) {
452 /* Ignore it */
453 /* This situation is also indicated in the descriptor */
454 SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INTIST);
455 }
456
457 if ((HwStatus & IS_NO_TIST_M2) != 0) {
458 /* Ignore it */
459 /* This situation is also indicated in the descriptor */
460 SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INTIST);
461 }
462 }
463#endif /* GENESIS */
464
465#ifdef YUKON
466 if (pAC->GIni.GIYukon) {
467 /* This is necessary only for Rx timing measurements */
468 if ((HwStatus & IS_IRQ_TIST_OV) != 0) {
469 /* increment Time Stamp Timer counter (high) */
470 pAC->GIni.GITimeStampCnt++;
471
472 /* Clear Time Stamp Timer IRQ */
473 SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_CLR_IRQ);
474 }
475
476 if ((HwStatus & IS_IRQ_SENSOR) != 0) {
477 /* no sensors on 32-bit Yukon */
478 if (pAC->GIni.GIYukon32Bit) {
479 /* disable HW Error IRQ */
480 pAC->GIni.GIValIrqMask &= ~IS_HW_ERR;
481 }
482 }
483 }
484#endif /* YUKON */
485
486 if ((HwStatus & IS_RAM_RD_PAR) != 0) {
487 SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_RD_PERR);
488 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E014, SKERR_SIRQ_E014MSG);
489 Para.Para64 = 0;
490 SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
491 }
492
493 if ((HwStatus & IS_RAM_WR_PAR) != 0) {
494 SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_WR_PERR);
495 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E015, SKERR_SIRQ_E015MSG);
496 Para.Para64 = 0;
497 SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
498 }
499
500 if ((HwStatus & IS_M1_PAR_ERR) != 0) {
501 SkMacParity(pAC, IoC, MAC_1);
502 }
503
504 if ((HwStatus & IS_M2_PAR_ERR) != 0) {
505 SkMacParity(pAC, IoC, MAC_2);
506 }
507
508 if ((HwStatus & IS_R1_PAR_ERR) != 0) {
509 /* Clear IRQ */
510 SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_P);
511
512 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG);
513 Para.Para64 = MAC_1;
514 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
515
516 Para.Para32[0] = MAC_1;
517 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
518 }
519
520 if ((HwStatus & IS_R2_PAR_ERR) != 0) {
521 /* Clear IRQ */
522 SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_P);
523
524 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG);
525 Para.Para64 = MAC_2;
526 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
527
528 Para.Para32[0] = MAC_2;
529 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
530 }
531} /* SkGeHwErr */
532
533
534/******************************************************************************
535 *
536 * SkGeSirqIsr() - Special Interrupt Service Routine
537 *
538 * Description: handles all non data transfer specific interrupts (slow path)
539 *
540 * Returns: N/A
541 */
542void SkGeSirqIsr(
543SK_AC *pAC, /* adapter context */
544SK_IOC IoC, /* IO context */
545SK_U32 Istatus) /* Interrupt status word */
546{
547 SK_EVPARA Para;
548 SK_U32 RegVal32; /* Read register value */
549 SK_GEPORT *pPrt; /* GIni Port struct pointer */
550 SK_U16 PhyInt;
551 int i;
552
553 if (((Istatus & IS_HW_ERR) & pAC->GIni.GIValIrqMask) != 0) {
554 /* read the HW Error Interrupt source */
555 SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
556
557 SkGeHwErr(pAC, IoC, RegVal32);
558 }
559
560 /*
561 * Packet Timeout interrupts
562 */
563 /* Check whether MACs are correctly initialized */
564 if (((Istatus & (IS_PA_TO_RX1 | IS_PA_TO_TX1)) != 0) &&
565 pAC->GIni.GP[MAC_1].PState == SK_PRT_RESET) {
566 /* MAC 1 was not initialized but Packet timeout occured */
567 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E004,
568 SKERR_SIRQ_E004MSG);
569 }
570
571 if (((Istatus & (IS_PA_TO_RX2 | IS_PA_TO_TX2)) != 0) &&
572 pAC->GIni.GP[MAC_2].PState == SK_PRT_RESET) {
573 /* MAC 2 was not initialized but Packet timeout occured */
574 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E005,
575 SKERR_SIRQ_E005MSG);
576 }
577
578 if ((Istatus & IS_PA_TO_RX1) != 0) {
579 /* Means network is filling us up */
580 SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E002,
581 SKERR_SIRQ_E002MSG);
582 SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX1);
583 }
584
585 if ((Istatus & IS_PA_TO_RX2) != 0) {
586 /* Means network is filling us up */
587 SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E003,
588 SKERR_SIRQ_E003MSG);
589 SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX2);
590 }
591
592 if ((Istatus & IS_PA_TO_TX1) != 0) {
593
594 pPrt = &pAC->GIni.GP[0];
595
596 /* May be a normal situation in a server with a slow network */
597 SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX1);
598
599#ifdef GENESIS
600 if (pAC->GIni.GIGenesis) {
601 /*
602 * workaround: if in half duplex mode, check for Tx hangup.
603 * Read number of TX'ed bytes, wait for 10 ms, then compare
604 * the number with current value. If nothing changed, we assume
605 * that Tx is hanging and do a FIFO flush (see event routine).
606 */
607 if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
608 pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
609 !pPrt->HalfDupTimerActive) {
610 /*
611 * many more pack. arb. timeouts may come in between,
612 * we ignore those
613 */
614 pPrt->HalfDupTimerActive = SK_TRUE;
615#ifdef XXX
616 Len = sizeof(SK_U64);
617 SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets,
618 &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, 0),
619 pAC->Rlmt.Port[0].Net->NetNumber);
620
621 pPrt->LastOctets = Octets;
622#endif /* XXX */
623 /* Snap statistic counters */
624 (void)SkXmUpdateStats(pAC, IoC, 0);
625
626 (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_HI, &RegVal32);
627
628 pPrt->LastOctets = (SK_U64)RegVal32 << 32;
629
630 (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_LO, &RegVal32);
631
632 pPrt->LastOctets += RegVal32;
633
634 Para.Para32[0] = 0;
635 SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
636 SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
637 }
638 }
639#endif /* GENESIS */
640 }
641
642 if ((Istatus & IS_PA_TO_TX2) != 0) {
643
644 pPrt = &pAC->GIni.GP[1];
645
646 /* May be a normal situation in a server with a slow network */
647 SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX2);
648
649#ifdef GENESIS
650 if (pAC->GIni.GIGenesis) {
651 /* workaround: see above */
652 if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
653 pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
654 !pPrt->HalfDupTimerActive) {
655 pPrt->HalfDupTimerActive = SK_TRUE;
656#ifdef XXX
657 Len = sizeof(SK_U64);
658 SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets,
659 &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, 1),
660 pAC->Rlmt.Port[1].Net->NetNumber);
661
662 pPrt->LastOctets = Octets;
663#endif /* XXX */
664 /* Snap statistic counters */
665 (void)SkXmUpdateStats(pAC, IoC, 1);
666
667 (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_HI, &RegVal32);
668
669 pPrt->LastOctets = (SK_U64)RegVal32 << 32;
670
671 (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_LO, &RegVal32);
672
673 pPrt->LastOctets += RegVal32;
674
675 Para.Para32[0] = 1;
676 SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
677 SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
678 }
679 }
680#endif /* GENESIS */
681 }
682
683 /* Check interrupts of the particular queues */
684 if ((Istatus & IS_R1_C) != 0) {
685 /* Clear IRQ */
686 SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_C);
687 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E006,
688 SKERR_SIRQ_E006MSG);
689 Para.Para64 = MAC_1;
690 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
691 Para.Para32[0] = MAC_1;
692 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
693 }
694
695 if ((Istatus & IS_R2_C) != 0) {
696 /* Clear IRQ */
697 SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_C);
698 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E007,
699 SKERR_SIRQ_E007MSG);
700 Para.Para64 = MAC_2;
701 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
702 Para.Para32[0] = MAC_2;
703 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
704 }
705
706 if ((Istatus & IS_XS1_C) != 0) {
707 /* Clear IRQ */
708 SK_OUT32(IoC, B0_XS1_CSR, CSR_IRQ_CL_C);
709 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E008,
710 SKERR_SIRQ_E008MSG);
711 Para.Para64 = MAC_1;
712 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
713 Para.Para32[0] = MAC_1;
714 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
715 }
716
717 if ((Istatus & IS_XA1_C) != 0) {
718 /* Clear IRQ */
719 SK_OUT32(IoC, B0_XA1_CSR, CSR_IRQ_CL_C);
720 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E009,
721 SKERR_SIRQ_E009MSG);
722 Para.Para64 = MAC_1;
723 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
724 Para.Para32[0] = MAC_1;
725 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
726 }
727
728 if ((Istatus & IS_XS2_C) != 0) {
729 /* Clear IRQ */
730 SK_OUT32(IoC, B0_XS2_CSR, CSR_IRQ_CL_C);
731 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E010,
732 SKERR_SIRQ_E010MSG);
733 Para.Para64 = MAC_2;
734 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
735 Para.Para32[0] = MAC_2;
736 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
737 }
738
739 if ((Istatus & IS_XA2_C) != 0) {
740 /* Clear IRQ */
741 SK_OUT32(IoC, B0_XA2_CSR, CSR_IRQ_CL_C);
742 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E011,
743 SKERR_SIRQ_E011MSG);
744 Para.Para64 = MAC_2;
745 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
746 Para.Para32[0] = MAC_2;
747 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
748 }
749
750 /* External reg interrupt */
751 if ((Istatus & IS_EXT_REG) != 0) {
752 /* Test IRQs from PHY */
753 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
754
755 pPrt = &pAC->GIni.GP[i];
756
757 if (pPrt->PState == SK_PRT_RESET) {
758 continue;
759 }
760
761#ifdef GENESIS
762 if (pAC->GIni.GIGenesis) {
763
764 switch (pPrt->PhyType) {
765
766 case SK_PHY_XMAC:
767 break;
768
769 case SK_PHY_BCOM:
770 SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_STAT, &PhyInt);
771
772 if ((PhyInt & ~PHY_B_DEF_MSK) != 0) {
773 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
774 ("Port %d Bcom Int: 0x%04X\n",
775 i, PhyInt));
776 SkPhyIsrBcom(pAC, IoC, i, PhyInt);
777 }
778 break;
779#ifdef OTHER_PHY
780 case SK_PHY_LONE:
781 SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_STAT, &PhyInt);
782
783 if ((PhyInt & PHY_L_DEF_MSK) != 0) {
784 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
785 ("Port %d Lone Int: %x\n",
786 i, PhyInt));
787 SkPhyIsrLone(pAC, IoC, i, PhyInt);
788 }
789 break;
790#endif /* OTHER_PHY */
791 }
792 }
793#endif /* GENESIS */
794
795#ifdef YUKON
796 if (pAC->GIni.GIYukon) {
797 /* Read PHY Interrupt Status */
798 SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_STAT, &PhyInt);
799
800 if ((PhyInt & PHY_M_DEF_MSK) != 0) {
801 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
802 ("Port %d Marv Int: 0x%04X\n",
803 i, PhyInt));
804 SkPhyIsrGmac(pAC, IoC, i, PhyInt);
805 }
806 }
807#endif /* YUKON */
808 }
809 }
810
811 /* I2C Ready interrupt */
812 if ((Istatus & IS_I2C_READY) != 0) {
813#ifdef SK_SLIM
814 SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
815#else
816 SkI2cIsr(pAC, IoC);
817#endif
818 }
819
820 /* SW forced interrupt */
821 if ((Istatus & IS_IRQ_SW) != 0) {
822 /* clear the software IRQ */
823 SK_OUT8(IoC, B0_CTST, CS_CL_SW_IRQ);
824 }
825
826 if ((Istatus & IS_LNK_SYNC_M1) != 0) {
827 /*
828 * We do NOT need the Link Sync interrupt, because it shows
829 * us only a link going down.
830 */
831 /* clear interrupt */
832 SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LED_CLR_IRQ);
833 }
834
835 /* Check MAC after link sync counter */
836 if ((Istatus & IS_MAC1) != 0) {
837 /* IRQ from MAC 1 */
838 SkMacIrq(pAC, IoC, MAC_1);
839 }
840
841 if ((Istatus & IS_LNK_SYNC_M2) != 0) {
842 /*
843 * We do NOT need the Link Sync interrupt, because it shows
844 * us only a link going down.
845 */
846 /* clear interrupt */
847 SK_OUT8(IoC, MR_ADDR(MAC_2, LNK_SYNC_CTRL), LED_CLR_IRQ);
848 }
849
850 /* Check MAC after link sync counter */
851 if ((Istatus & IS_MAC2) != 0) {
852 /* IRQ from MAC 2 */
853 SkMacIrq(pAC, IoC, MAC_2);
854 }
855
856 /* Timer interrupt (served last) */
857 if ((Istatus & IS_TIMINT) != 0) {
858 /* check for HW Errors */
859 if (((Istatus & IS_HW_ERR) & ~pAC->GIni.GIValIrqMask) != 0) {
860 /* read the HW Error Interrupt source */
861 SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
862
863 SkGeHwErr(pAC, IoC, RegVal32);
864 }
865
866 SkHwtIsr(pAC, IoC);
867 }
868
869} /* SkGeSirqIsr */
870
871
872#ifdef GENESIS
873/******************************************************************************
874 *
875 * SkGePortCheckShorts() - Implementing XMAC Workaround Errata # 2
876 *
877 * return:
878 * 0 o.k. nothing needed
879 * 1 Restart needed on this port
880 */
881static int SkGePortCheckShorts(
882SK_AC *pAC, /* Adapter Context */
883SK_IOC IoC, /* IO Context */
884int Port) /* Which port should be checked */
885{
886 SK_U32 Shorts; /* Short Event Counter */
887 SK_U32 CheckShorts; /* Check value for Short Event Counter */
888 SK_U64 RxCts; /* Rx Counter (packets on network) */
889 SK_U32 RxTmp; /* Rx temp. Counter */
890 SK_U32 FcsErrCts; /* FCS Error Counter */
891 SK_GEPORT *pPrt; /* GIni Port struct pointer */
892 int Rtv; /* Return value */
893 int i;
894
895 pPrt = &pAC->GIni.GP[Port];
896
897 /* Default: no action */
898 Rtv = SK_HW_PS_NONE;
899
900 (void)SkXmUpdateStats(pAC, IoC, Port);
901
902 /* Extra precaution: check for short Event counter */
903 (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);
904
905 /*
906 * Read Rx counters (packets seen on the network and not necessarily
907 * really received.
908 */
909 RxCts = 0;
910
911 for (i = 0; i < sizeof(SkGeRxRegs)/sizeof(SkGeRxRegs[0]); i++) {
912
913 (void)SkXmMacStatistic(pAC, IoC, Port, SkGeRxRegs[i], &RxTmp);
914
915 RxCts += (SK_U64)RxTmp;
916 }
917
918 /* On default: check shorts against zero */
919 CheckShorts = 0;
920
921 /* Extra precaution on active links */
922 if (pPrt->PHWLinkUp) {
923 /* Reset Link Restart counter */
924 pPrt->PLinkResCt = 0;
925 pPrt->PAutoNegTOCt = 0;
926
927 /* If link is up check for 2 */
928 CheckShorts = 2;
929
930 (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXF_FCS_ERR, &FcsErrCts);
931
932 if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
933 pPrt->PLipaAutoNeg == SK_LIPA_UNKNOWN &&
934 (pPrt->PLinkMode == SK_LMODE_HALF ||
935 pPrt->PLinkMode == SK_LMODE_FULL)) {
936 /*
937 * This is autosensing and we are in the fallback
938 * manual full/half duplex mode.
939 */
940 if (RxCts == pPrt->PPrevRx) {
941 /* Nothing received, restart link */
942 pPrt->PPrevFcs = FcsErrCts;
943 pPrt->PPrevShorts = Shorts;
944
945 return(SK_HW_PS_RESTART);
946 }
947 else {
948 pPrt->PLipaAutoNeg = SK_LIPA_MANUAL;
949 }
950 }
951
952 if (((RxCts - pPrt->PPrevRx) > pPrt->PRxLim) ||
953 (!(FcsErrCts - pPrt->PPrevFcs))) {
954 /*
955 * Note: The compare with zero above has to be done the way shown,
956 * otherwise the Linux driver will have a problem.
957 */
958 /*
959 * We received a bunch of frames or no CRC error occured on the
960 * network -> ok.
961 */
962 pPrt->PPrevRx = RxCts;
963 pPrt->PPrevFcs = FcsErrCts;
964 pPrt->PPrevShorts = Shorts;
965
966 return(SK_HW_PS_NONE);
967 }
968
969 pPrt->PPrevFcs = FcsErrCts;
970 }
971
972
973 if ((Shorts - pPrt->PPrevShorts) > CheckShorts) {
974 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
975 ("Short Event Count Restart Port %d \n", Port));
976 Rtv = SK_HW_PS_RESTART;
977 }
978
979 pPrt->PPrevShorts = Shorts;
980 pPrt->PPrevRx = RxCts;
981
982 return(Rtv);
983} /* SkGePortCheckShorts */
984#endif /* GENESIS */
985
986
987/******************************************************************************
988 *
989 * SkGePortCheckUp() - Check if the link is up
990 *
991 * return:
992 * 0 o.k. nothing needed
993 * 1 Restart needed on this port
994 * 2 Link came up
995 */
996static int SkGePortCheckUp(
997SK_AC *pAC, /* Adapter Context */
998SK_IOC IoC, /* IO Context */
999int Port) /* Which port should be checked */
1000{
1001 SK_GEPORT *pPrt; /* GIni Port struct pointer */
1002 SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */
1003 int Rtv; /* Return value */
1004
1005 Rtv = SK_HW_PS_NONE;
1006
1007 pPrt = &pAC->GIni.GP[Port];
1008
1009 if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
1010 AutoNeg = SK_FALSE;
1011 }
1012 else {
1013 AutoNeg = SK_TRUE;
1014 }
1015
1016#ifdef GENESIS
1017 if (pAC->GIni.GIGenesis) {
1018
1019 switch (pPrt->PhyType) {
1020
1021 case SK_PHY_XMAC:
1022 Rtv = SkGePortCheckUpXmac(pAC, IoC, Port, AutoNeg);
1023 break;
1024 case SK_PHY_BCOM:
1025 Rtv = SkGePortCheckUpBcom(pAC, IoC, Port, AutoNeg);
1026 break;
1027#ifdef OTHER_PHY
1028 case SK_PHY_LONE:
1029 Rtv = SkGePortCheckUpLone(pAC, IoC, Port, AutoNeg);
1030 break;
1031 case SK_PHY_NAT:
1032 Rtv = SkGePortCheckUpNat(pAC, IoC, Port, AutoNeg);
1033 break;
1034#endif /* OTHER_PHY */
1035 }
1036 }
1037#endif /* GENESIS */
1038
1039#ifdef YUKON
1040 if (pAC->GIni.GIYukon) {
1041
1042 Rtv = SkGePortCheckUpGmac(pAC, IoC, Port, AutoNeg);
1043 }
1044#endif /* YUKON */
1045
1046 return(Rtv);
1047} /* SkGePortCheckUp */
1048
1049
1050#ifdef GENESIS
1051/******************************************************************************
1052 *
1053 * SkGePortCheckUpXmac() - Implementing of the Workaround Errata # 2
1054 *
1055 * return:
1056 * 0 o.k. nothing needed
1057 * 1 Restart needed on this port
1058 * 2 Link came up
1059 */
1060static int SkGePortCheckUpXmac(
1061SK_AC *pAC, /* Adapter Context */
1062SK_IOC IoC, /* IO Context */
1063int Port, /* Which port should be checked */
1064SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
1065{
1066 SK_U32 Shorts; /* Short Event Counter */
1067 SK_GEPORT *pPrt; /* GIni Port struct pointer */
1068 int Done;
1069 SK_U32 GpReg; /* General Purpose register value */
1070 SK_U16 Isrc; /* Interrupt source register */
1071 SK_U16 IsrcSum; /* Interrupt source register sum */
1072 SK_U16 LpAb; /* Link Partner Ability */
1073 SK_U16 ResAb; /* Resolved Ability */
1074 SK_U16 ExtStat; /* Extended Status Register */
1075 SK_U8 NextMode; /* Next AutoSensing Mode */
1076
1077 pPrt = &pAC->GIni.GP[Port];
1078
1079 if (pPrt->PHWLinkUp) {
1080 if (pPrt->PhyType != SK_PHY_XMAC) {
1081 return(SK_HW_PS_NONE);
1082 }
1083 else {
1084 return(SkGePortCheckShorts(pAC, IoC, Port));
1085 }
1086 }
1087
1088 IsrcSum = pPrt->PIsave;
1089 pPrt->PIsave = 0;
1090
1091 /* Now wait for each port's link */
1092 if (pPrt->PLinkBroken) {
1093 /* Link was broken */
1094 XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);
1095
1096 if ((GpReg & XM_GP_INP_ASS) == 0) {
1097 /* The Link is in sync */
1098 XM_IN16(IoC, Port, XM_ISRC, &Isrc);
1099 IsrcSum |= Isrc;
1100 SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
1101
1102 if ((Isrc & XM_IS_INP_ASS) == 0) {
1103 /* It has been in sync since last time */
1104 /* Restart the PORT */
1105 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1106 ("Link in sync Restart Port %d\n", Port));
1107
1108 (void)SkXmUpdateStats(pAC, IoC, Port);
1109
1110 /* We now need to reinitialize the PrevShorts counter */
1111 (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);
1112 pPrt->PPrevShorts = Shorts;
1113
1114 pPrt->PLinkBroken = SK_FALSE;
1115
1116 /*
1117 * Link Restart Workaround:
1118 * it may be possible that the other Link side
1119 * restarts its link as well an we detect
1120 * another LinkBroken. To prevent this
1121 * happening we check for a maximum number
1122 * of consecutive restart. If those happens,
1123 * we do NOT restart the active link and
1124 * check whether the link is now o.k.
1125 */
1126 pPrt->PLinkResCt++;
1127
1128 pPrt->PAutoNegTimeOut = 0;
1129
1130 if (pPrt->PLinkResCt < SK_MAX_LRESTART) {
1131 return(SK_HW_PS_RESTART);
1132 }
1133
1134 pPrt->PLinkResCt = 0;
1135
1136 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1137 ("Do NOT restart on Port %d %x %x\n", Port, Isrc, IsrcSum));
1138 }
1139 else {
1140 pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
1141
1142 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1143 ("Save Sync/nosync Port %d %x %x\n", Port, Isrc, IsrcSum));
1144
1145 /* Do nothing more if link is broken */
1146 return(SK_HW_PS_NONE);
1147 }
1148 }
1149 else {
1150 /* Do nothing more if link is broken */
1151 return(SK_HW_PS_NONE);
1152 }
1153
1154 }
1155 else {
1156 /* Link was not broken, check if it is */
1157 XM_IN16(IoC, Port, XM_ISRC, &Isrc);
1158 IsrcSum |= Isrc;
1159 if ((Isrc & XM_IS_INP_ASS) != 0) {
1160 XM_IN16(IoC, Port, XM_ISRC, &Isrc);
1161 IsrcSum |= Isrc;
1162 if ((Isrc & XM_IS_INP_ASS) != 0) {
1163 XM_IN16(IoC, Port, XM_ISRC, &Isrc);
1164 IsrcSum |= Isrc;
1165 if ((Isrc & XM_IS_INP_ASS) != 0) {
1166 pPrt->PLinkBroken = SK_TRUE;
1167 /* Re-Init Link partner Autoneg flag */
1168 pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
1169 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1170 ("Link broken Port %d\n", Port));
1171
1172 /* Cable removed-> reinit sense mode */
1173 SkHWInitDefSense(pAC, IoC, Port);
1174
1175 return(SK_HW_PS_RESTART);
1176 }
1177 }
1178 }
1179 else {
1180 SkXmAutoNegLipaXmac(pAC, IoC, Port, Isrc);
1181
1182 if (SkGePortCheckShorts(pAC, IoC, Port) == SK_HW_PS_RESTART) {
1183 return(SK_HW_PS_RESTART);
1184 }
1185 }
1186 }
1187
1188 /*
1189 * here we usually can check whether the link is in sync and
1190 * auto-negotiation is done.
1191 */
1192 XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);
1193 XM_IN16(IoC, Port, XM_ISRC, &Isrc);
1194 IsrcSum |= Isrc;
1195
1196 SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
1197
1198 if ((GpReg & XM_GP_INP_ASS) != 0 || (IsrcSum & XM_IS_INP_ASS) != 0) {
1199 if ((GpReg & XM_GP_INP_ASS) == 0) {
1200 /* Save Auto-negotiation Done interrupt only if link is in sync */
1201 pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
1202 }
1203#ifdef DEBUG
1204 if ((pPrt->PIsave & XM_IS_AND) != 0) {
1205 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1206 ("AutoNeg done rescheduled Port %d\n", Port));
1207 }
1208#endif /* DEBUG */
1209 return(SK_HW_PS_NONE);
1210 }
1211
1212 if (AutoNeg) {
1213 if ((IsrcSum & XM_IS_AND) != 0) {
1214 SkHWLinkUp(pAC, IoC, Port);
1215 Done = SkMacAutoNegDone(pAC, IoC, Port);
1216 if (Done != SK_AND_OK) {
1217 /* Get PHY parameters, for debugging only */
1218 SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LpAb);
1219 SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb);
1220 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1221 ("AutoNeg FAIL Port %d (LpAb %x, ResAb %x)\n",
1222 Port, LpAb, ResAb));
1223
1224 /* Try next possible mode */
1225 NextMode = SkHWSenseGetNext(pAC, IoC, Port);
1226 SkHWLinkDown(pAC, IoC, Port);
1227 if (Done == SK_AND_DUP_CAP) {
1228 /* GoTo next mode */
1229 SkHWSenseSetNext(pAC, IoC, Port, NextMode);
1230 }
1231
1232 return(SK_HW_PS_RESTART);
1233 }
1234 /*
1235 * Dummy Read extended status to prevent extra link down/ups
1236 * (clear Page Received bit if set)
1237 */
1238 SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_EXP, &ExtStat);
1239
1240 return(SK_HW_PS_LINK);
1241 }
1242
1243 /* AutoNeg not done, but HW link is up. Check for timeouts */
1244 pPrt->PAutoNegTimeOut++;
1245 if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
1246 /* Increase the Timeout counter */
1247 pPrt->PAutoNegTOCt++;
1248
1249 /* Timeout occured */
1250 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1251 ("AutoNeg timeout Port %d\n", Port));
1252 if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
1253 pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
1254 /* Set Link manually up */
1255 SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
1256 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1257 ("Set manual full duplex Port %d\n", Port));
1258 }
1259
1260 if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
1261 pPrt->PLipaAutoNeg == SK_LIPA_AUTO &&
1262 pPrt->PAutoNegTOCt >= SK_MAX_ANEG_TO) {
1263 /*
1264 * This is rather complicated.
1265 * we need to check here whether the LIPA_AUTO
1266 * we saw before is false alert. We saw at one
1267 * switch ( SR8800) that on boot time it sends
1268 * just one auto-neg packet and does no further
1269 * auto-negotiation.
1270 * Solution: we restart the autosensing after
1271 * a few timeouts.
1272 */
1273 pPrt->PAutoNegTOCt = 0;
1274 pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
1275 SkHWInitDefSense(pAC, IoC, Port);
1276 }
1277
1278 /* Do the restart */
1279 return(SK_HW_PS_RESTART);
1280 }
1281 }
1282 else {
1283 /* Link is up and we don't need more */
1284#ifdef DEBUG
1285 if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
1286 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1287 ("ERROR: Lipa auto detected on port %d\n", Port));
1288 }
1289#endif /* DEBUG */
1290 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1291 ("Link sync(GP), Port %d\n", Port));
1292 SkHWLinkUp(pAC, IoC, Port);
1293
1294 /*
1295 * Link sync (GP) and so assume a good connection. But if not received
1296 * a bunch of frames received in a time slot (maybe broken tx cable)
1297 * the port is restart.
1298 */
1299 return(SK_HW_PS_LINK);
1300 }
1301
1302 return(SK_HW_PS_NONE);
1303} /* SkGePortCheckUpXmac */
1304
1305
1306/******************************************************************************
1307 *
1308 * SkGePortCheckUpBcom() - Check if the link is up on Bcom PHY
1309 *
1310 * return:
1311 * 0 o.k. nothing needed
1312 * 1 Restart needed on this port
1313 * 2 Link came up
1314 */
1315static int SkGePortCheckUpBcom(
1316SK_AC *pAC, /* Adapter Context */
1317SK_IOC IoC, /* IO Context */
1318int Port, /* Which port should be checked */
1319SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
1320{
1321 SK_GEPORT *pPrt; /* GIni Port struct pointer */
1322 int Done;
1323 SK_U16 Isrc; /* Interrupt source register */
1324 SK_U16 PhyStat; /* Phy Status Register */
1325 SK_U16 ResAb; /* Master/Slave resolution */
1326 SK_U16 Ctrl; /* Broadcom control flags */
1327#ifdef DEBUG
1328 SK_U16 LpAb;
1329 SK_U16 ExtStat;
1330#endif /* DEBUG */
1331
1332 pPrt = &pAC->GIni.GP[Port];
1333
1334 /* Check for No HCD Link events (#10523) */
1335 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &Isrc);
1336
1337#ifdef xDEBUG
1338 if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT) ==
1339 (PHY_B_IS_SCR_S_ER | PHY_B_IS_RRS_CHANGE | PHY_B_IS_LRS_CHANGE)) {
1340
1341 SK_U32 Stat1, Stat2, Stat3;
1342
1343 Stat1 = 0;
1344 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
1345 CMSMPrintString(
1346 pAC->pConfigTable,
1347 MSG_TYPE_RUNTIME_INFO,
1348 "CheckUp1 - Stat: %x, Mask: %x",
1349 (void *)Isrc,
1350 (void *)Stat1);
1351
1352 Stat1 = 0;
1353 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
1354 Stat2 = 0;
1355 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &Stat2);
1356 Stat1 = Stat1 << 16 | Stat2;
1357 Stat2 = 0;
1358 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
1359 Stat3 = 0;
1360 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
1361 Stat2 = Stat2 << 16 | Stat3;
1362 CMSMPrintString(
1363 pAC->pConfigTable,
1364 MSG_TYPE_RUNTIME_INFO,
1365 "Ctrl/Stat: %x, AN Adv/LP: %x",
1366 (void *)Stat1,
1367 (void *)Stat2);
1368
1369 Stat1 = 0;
1370 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
1371 Stat2 = 0;
1372 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
1373 Stat1 = Stat1 << 16 | Stat2;
1374 Stat2 = 0;
1375 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
1376 Stat3 = 0;
1377 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &Stat3);
1378 Stat2 = Stat2 << 16 | Stat3;
1379 CMSMPrintString(
1380 pAC->pConfigTable,
1381 MSG_TYPE_RUNTIME_INFO,
1382 "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
1383 (void *)Stat1,
1384 (void *)Stat2);
1385
1386 Stat1 = 0;
1387 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
1388 Stat2 = 0;
1389 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
1390 Stat1 = Stat1 << 16 | Stat2;
1391 Stat2 = 0;
1392 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
1393 Stat3 = 0;
1394 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
1395 Stat2 = Stat2 << 16 | Stat3;
1396 CMSMPrintString(
1397 pAC->pConfigTable,
1398 MSG_TYPE_RUNTIME_INFO,
1399 "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
1400 (void *)Stat1,
1401 (void *)Stat2);
1402 }
1403#endif /* DEBUG */
1404
1405 if ((Isrc & (PHY_B_IS_NO_HDCL /* | PHY_B_IS_NO_HDC */)) != 0) {
1406 /*
1407 * Workaround BCom Errata:
1408 * enable and disable loopback mode if "NO HCD" occurs.
1409 */
1410 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Ctrl);
1411 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL,
1412 (SK_U16)(Ctrl | PHY_CT_LOOP));
1413 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL,
1414 (SK_U16)(Ctrl & ~PHY_CT_LOOP));
1415 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1416 ("No HCD Link event, Port %d\n", Port));
1417#ifdef xDEBUG
1418 CMSMPrintString(
1419 pAC->pConfigTable,
1420 MSG_TYPE_RUNTIME_INFO,
1421 "No HCD link event, port %d.",
1422 (void *)Port,
1423 (void *)NULL);
1424#endif /* DEBUG */
1425 }
1426
1427 /* Not obsolete: link status bit is latched to 0 and autoclearing! */
1428 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
1429
1430 if (pPrt->PHWLinkUp) {
1431 return(SK_HW_PS_NONE);
1432 }
1433
1434#ifdef xDEBUG
1435 {
1436 SK_U32 Stat1, Stat2, Stat3;
1437
1438 Stat1 = 0;
1439 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
1440 CMSMPrintString(
1441 pAC->pConfigTable,
1442 MSG_TYPE_RUNTIME_INFO,
1443 "CheckUp1a - Stat: %x, Mask: %x",
1444 (void *)Isrc,
1445 (void *)Stat1);
1446
1447 Stat1 = 0;
1448 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
1449 Stat2 = 0;
1450 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
1451 Stat1 = Stat1 << 16 | PhyStat;
1452 Stat2 = 0;
1453 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
1454 Stat3 = 0;
1455 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
1456 Stat2 = Stat2 << 16 | Stat3;
1457 CMSMPrintString(
1458 pAC->pConfigTable,
1459 MSG_TYPE_RUNTIME_INFO,
1460 "Ctrl/Stat: %x, AN Adv/LP: %x",
1461 (void *)Stat1,
1462 (void *)Stat2);
1463
1464 Stat1 = 0;
1465 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
1466 Stat2 = 0;
1467 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
1468 Stat1 = Stat1 << 16 | Stat2;
1469 Stat2 = 0;
1470 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
1471 Stat3 = 0;
1472 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
1473 Stat2 = Stat2 << 16 | ResAb;
1474 CMSMPrintString(
1475 pAC->pConfigTable,
1476 MSG_TYPE_RUNTIME_INFO,
1477 "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
1478 (void *)Stat1,
1479 (void *)Stat2);
1480
1481 Stat1 = 0;
1482 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
1483 Stat2 = 0;
1484 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
1485 Stat1 = Stat1 << 16 | Stat2;
1486 Stat2 = 0;
1487 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
1488 Stat3 = 0;
1489 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
1490 Stat2 = Stat2 << 16 | Stat3;
1491 CMSMPrintString(
1492 pAC->pConfigTable,
1493 MSG_TYPE_RUNTIME_INFO,
1494 "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
1495 (void *)Stat1,
1496 (void *)Stat2);
1497 }
1498#endif /* DEBUG */
1499
1500 /*
1501 * Here we usually can check whether the link is in sync and
1502 * auto-negotiation is done.
1503 */
1504
1505 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
1506
1507 SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
1508
1509 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1510 ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat));
1511
1512 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
1513
1514 if ((ResAb & PHY_B_1000S_MSF) != 0) {
1515 /* Error */
1516 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1517 ("Master/Slave Fault port %d\n", Port));
1518
1519 pPrt->PAutoNegFail = SK_TRUE;
1520 pPrt->PMSStatus = SK_MS_STAT_FAULT;
1521
1522 return(SK_HW_PS_RESTART);
1523 }
1524
1525 if ((PhyStat & PHY_ST_LSYNC) == 0) {
1526 return(SK_HW_PS_NONE);
1527 }
1528
1529 pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
1530 SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
1531
1532 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1533 ("Port %d, ResAb: 0x%04X\n", Port, ResAb));
1534
1535 if (AutoNeg) {
1536 if ((PhyStat & PHY_ST_AN_OVER) != 0) {
1537
1538 SkHWLinkUp(pAC, IoC, Port);
1539
1540 Done = SkMacAutoNegDone(pAC, IoC, Port);
1541
1542 if (Done != SK_AND_OK) {
1543#ifdef DEBUG
1544 /* Get PHY parameters, for debugging only */
1545 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LpAb);
1546 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ExtStat);
1547 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1548 ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
1549 Port, LpAb, ExtStat));
1550#endif /* DEBUG */
1551 return(SK_HW_PS_RESTART);
1552 }
1553 else {
1554#ifdef xDEBUG
1555 /* Dummy read ISR to prevent extra link downs/ups */
1556 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
1557
1558 if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
1559 CMSMPrintString(
1560 pAC->pConfigTable,
1561 MSG_TYPE_RUNTIME_INFO,
1562 "CheckUp2 - Stat: %x",
1563 (void *)ExtStat,
1564 (void *)NULL);
1565 }
1566#endif /* DEBUG */
1567 return(SK_HW_PS_LINK);
1568 }
1569 }
1570 }
1571 else { /* !AutoNeg */
1572 /* Link is up and we don't need more. */
1573#ifdef DEBUG
1574 if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
1575 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1576 ("ERROR: Lipa auto detected on port %d\n", Port));
1577 }
1578#endif /* DEBUG */
1579
1580#ifdef xDEBUG
1581 /* Dummy read ISR to prevent extra link downs/ups */
1582 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
1583
1584 if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
1585 CMSMPrintString(
1586 pAC->pConfigTable,
1587 MSG_TYPE_RUNTIME_INFO,
1588 "CheckUp3 - Stat: %x",
1589 (void *)ExtStat,
1590 (void *)NULL);
1591 }
1592#endif /* DEBUG */
1593
1594 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1595 ("Link sync(GP), Port %d\n", Port));
1596 SkHWLinkUp(pAC, IoC, Port);
1597
1598 return(SK_HW_PS_LINK);
1599 }
1600
1601 return(SK_HW_PS_NONE);
1602} /* SkGePortCheckUpBcom */
1603#endif /* GENESIS */
1604
1605
1606#ifdef YUKON
1607/******************************************************************************
1608 *
1609 * SkGePortCheckUpGmac() - Check if the link is up on Marvell PHY
1610 *
1611 * return:
1612 * 0 o.k. nothing needed
1613 * 1 Restart needed on this port
1614 * 2 Link came up
1615 */
1616static int SkGePortCheckUpGmac(
1617SK_AC *pAC, /* Adapter Context */
1618SK_IOC IoC, /* IO Context */
1619int Port, /* Which port should be checked */
1620SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
1621{
1622 SK_GEPORT *pPrt; /* GIni Port struct pointer */
1623 int Done;
1624 SK_U16 PhyIsrc; /* PHY Interrupt source */
1625 SK_U16 PhyStat; /* PPY Status */
1626 SK_U16 PhySpecStat;/* PHY Specific Status */
1627 SK_U16 ResAb; /* Master/Slave resolution */
1628 SK_EVPARA Para;
1629#ifdef DEBUG
1630 SK_U16 Word; /* I/O helper */
1631#endif /* DEBUG */
1632
1633 pPrt = &pAC->GIni.GP[Port];
1634
1635 if (pPrt->PHWLinkUp) {
1636 return(SK_HW_PS_NONE);
1637 }
1638
1639 /* Read PHY Status */
1640 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
1641
1642 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1643 ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat));
1644
1645 /* Read PHY Interrupt Status */
1646 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &PhyIsrc);
1647
1648 if ((PhyIsrc & PHY_M_IS_AN_COMPL) != 0) {
1649 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1650 ("Auto-Negotiation Completed, PhyIsrc: 0x%04X\n", PhyIsrc));
1651 }
1652
1653 if ((PhyIsrc & PHY_M_IS_LSP_CHANGE) != 0) {
1654 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1655 ("Link Speed Changed, PhyIsrc: 0x%04X\n", PhyIsrc));
1656 }
1657
1658 SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
1659
1660 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
1661
1662 if ((ResAb & PHY_B_1000S_MSF) != 0) {
1663 /* Error */
1664 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1665 ("Master/Slave Fault port %d\n", Port));
1666
1667 pPrt->PAutoNegFail = SK_TRUE;
1668 pPrt->PMSStatus = SK_MS_STAT_FAULT;
1669
1670 return(SK_HW_PS_RESTART);
1671 }
1672
1673 /* Read PHY Specific Status */
1674 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
1675
1676 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1677 ("Phy1000BT: 0x%04X, PhySpecStat: 0x%04X\n", ResAb, PhySpecStat));
1678
1679#ifdef DEBUG
1680 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_EXP, &Word);
1681
1682 if ((PhyIsrc & PHY_M_IS_AN_PR) != 0 || (Word & PHY_ANE_RX_PG) != 0 ||
1683 (PhySpecStat & PHY_M_PS_PAGE_REC) != 0) {
1684 /* Read PHY Next Page Link Partner */
1685 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_NEPG_LP, &Word);
1686
1687 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1688 ("Page Received, NextPage: 0x%04X\n", Word));
1689 }
1690#endif /* DEBUG */
1691
1692 if ((PhySpecStat & PHY_M_PS_LINK_UP) == 0) {
1693 return(SK_HW_PS_NONE);
1694 }
1695
1696 if ((PhySpecStat & PHY_M_PS_DOWNS_STAT) != 0 ||
1697 (PhyIsrc & PHY_M_IS_DOWNSH_DET) != 0) {
1698 /* Downshift detected */
1699 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E025, SKERR_SIRQ_E025MSG);
1700
1701 Para.Para64 = Port;
1702 SkEventQueue(pAC, SKGE_DRV, SK_DRV_DOWNSHIFT_DET, Para);
1703
1704 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1705 ("Downshift detected, PhyIsrc: 0x%04X\n", PhyIsrc));
1706 }
1707
1708 pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
1709 SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
1710
1711 pPrt->PCableLen = (SK_U8)((PhySpecStat & PHY_M_PS_CABLE_MSK) >> 7);
1712
1713 if (AutoNeg) {
1714 /* Auto-Negotiation Over ? */
1715 if ((PhyStat & PHY_ST_AN_OVER) != 0) {
1716
1717 SkHWLinkUp(pAC, IoC, Port);
1718
1719 Done = SkMacAutoNegDone(pAC, IoC, Port);
1720
1721 if (Done != SK_AND_OK) {
1722 return(SK_HW_PS_RESTART);
1723 }
1724
1725 return(SK_HW_PS_LINK);
1726 }
1727 }
1728 else { /* !AutoNeg */
1729 /* Link is up and we don't need more */
1730#ifdef DEBUG
1731 if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
1732 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1733 ("ERROR: Lipa auto detected on port %d\n", Port));
1734 }
1735#endif /* DEBUG */
1736
1737 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1738 ("Link sync, Port %d\n", Port));
1739 SkHWLinkUp(pAC, IoC, Port);
1740
1741 return(SK_HW_PS_LINK);
1742 }
1743
1744 return(SK_HW_PS_NONE);
1745} /* SkGePortCheckUpGmac */
1746#endif /* YUKON */
1747
1748
1749#ifdef OTHER_PHY
1750/******************************************************************************
1751 *
1752 * SkGePortCheckUpLone() - Check if the link is up on Level One PHY
1753 *
1754 * return:
1755 * 0 o.k. nothing needed
1756 * 1 Restart needed on this port
1757 * 2 Link came up
1758 */
1759static int SkGePortCheckUpLone(
1760SK_AC *pAC, /* Adapter Context */
1761SK_IOC IoC, /* IO Context */
1762int Port, /* Which port should be checked */
1763SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
1764{
1765 SK_GEPORT *pPrt; /* GIni Port struct pointer */
1766 int Done;
1767 SK_U16 Isrc; /* Interrupt source register */
1768 SK_U16 LpAb; /* Link Partner Ability */
1769 SK_U16 ExtStat; /* Extended Status Register */
1770 SK_U16 PhyStat; /* Phy Status Register */
1771 SK_U16 StatSum;
1772 SK_U8 NextMode; /* Next AutoSensing Mode */
1773
1774 pPrt = &pAC->GIni.GP[Port];
1775
1776 if (pPrt->PHWLinkUp) {
1777 return(SK_HW_PS_NONE);
1778 }
1779
1780 StatSum = pPrt->PIsave;
1781 pPrt->PIsave = 0;
1782
1783 /*
1784 * here we usually can check whether the link is in sync and
1785 * auto-negotiation is done.
1786 */
1787 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_STAT, &PhyStat);
1788 StatSum |= PhyStat;
1789
1790 SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
1791
1792 if ((PhyStat & PHY_ST_LSYNC) == 0) {
1793 /* Save Auto-negotiation Done bit */
1794 pPrt->PIsave = (SK_U16)(StatSum & PHY_ST_AN_OVER);
1795#ifdef DEBUG
1796 if ((pPrt->PIsave & PHY_ST_AN_OVER) != 0) {
1797 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1798 ("AutoNeg done rescheduled Port %d\n", Port));
1799 }
1800#endif /* DEBUG */
1801 return(SK_HW_PS_NONE);
1802 }
1803
1804 if (AutoNeg) {
1805 if ((StatSum & PHY_ST_AN_OVER) != 0) {
1806 SkHWLinkUp(pAC, IoC, Port);
1807 Done = SkMacAutoNegDone(pAC, IoC, Port);
1808 if (Done != SK_AND_OK) {
1809 /* Get PHY parameters, for debugging only */
1810 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LpAb);
1811 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ExtStat);
1812 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1813 ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
1814 Port, LpAb, ExtStat));
1815
1816 /* Try next possible mode */
1817 NextMode = SkHWSenseGetNext(pAC, IoC, Port);
1818 SkHWLinkDown(pAC, IoC, Port);
1819 if (Done == SK_AND_DUP_CAP) {
1820 /* GoTo next mode */
1821 SkHWSenseSetNext(pAC, IoC, Port, NextMode);
1822 }
1823
1824 return(SK_HW_PS_RESTART);
1825
1826 }
1827 else {
1828 /*
1829 * Dummy Read interrupt status to prevent
1830 * extra link down/ups
1831 */
1832 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
1833 return(SK_HW_PS_LINK);
1834 }
1835 }
1836
1837 /* AutoNeg not done, but HW link is up. Check for timeouts */
1838 pPrt->PAutoNegTimeOut++;
1839 if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
1840 /* Timeout occured */
1841 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1842 ("AutoNeg timeout Port %d\n", Port));
1843 if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
1844 pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
1845 /* Set Link manually up */
1846 SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
1847 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1848 ("Set manual full duplex Port %d\n", Port));
1849 }
1850
1851 /* Do the restart */
1852 return(SK_HW_PS_RESTART);
1853 }
1854 }
1855 else {
1856 /* Link is up and we don't need more */
1857#ifdef DEBUG
1858 if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
1859 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1860 ("ERROR: Lipa auto detected on port %d\n", Port));
1861 }
1862#endif /* DEBUG */
1863
1864 /*
1865 * Dummy Read interrupt status to prevent
1866 * extra link down/ups
1867 */
1868 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
1869
1870 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1871 ("Link sync(GP), Port %d\n", Port));
1872 SkHWLinkUp(pAC, IoC, Port);
1873
1874 return(SK_HW_PS_LINK);
1875 }
1876
1877 return(SK_HW_PS_NONE);
1878} /* SkGePortCheckUpLone */
1879
1880
1881/******************************************************************************
1882 *
1883 * SkGePortCheckUpNat() - Check if the link is up on National PHY
1884 *
1885 * return:
1886 * 0 o.k. nothing needed
1887 * 1 Restart needed on this port
1888 * 2 Link came up
1889 */
1890static int SkGePortCheckUpNat(
1891SK_AC *pAC, /* Adapter Context */
1892SK_IOC IoC, /* IO Context */
1893int Port, /* Which port should be checked */
1894SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
1895{
1896 /* todo: National */
1897 return(SK_HW_PS_NONE);
1898} /* SkGePortCheckUpNat */
1899#endif /* OTHER_PHY */
1900
1901
1902/******************************************************************************
1903 *
1904 * SkGeSirqEvent() - Event Service Routine
1905 *
1906 * Description:
1907 *
1908 * Notes:
1909 */
1910int SkGeSirqEvent(
1911SK_AC *pAC, /* Adapter Context */
1912SK_IOC IoC, /* Io Context */
1913SK_U32 Event, /* Module specific Event */
1914SK_EVPARA Para) /* Event specific Parameter */
1915{
1916 SK_GEPORT *pPrt; /* GIni Port struct pointer */
1917 SK_U32 Port;
1918 SK_U32 Val32;
1919 int PortStat;
1920 SK_U8 Val8;
1921#ifdef GENESIS
1922 SK_U64 Octets;
1923#endif /* GENESIS */
1924
1925 Port = Para.Para32[0];
1926 pPrt = &pAC->GIni.GP[Port];
1927
1928 switch (Event) {
1929 case SK_HWEV_WATIM:
1930 if (pPrt->PState == SK_PRT_RESET) {
1931
1932 PortStat = SK_HW_PS_NONE;
1933 }
1934 else {
1935 /* Check whether port came up */
1936 PortStat = SkGePortCheckUp(pAC, IoC, (int)Port);
1937 }
1938
1939 switch (PortStat) {
1940 case SK_HW_PS_RESTART:
1941 if (pPrt->PHWLinkUp) {
1942 /* Set Link to down */
1943 SkHWLinkDown(pAC, IoC, (int)Port);
1944
1945 /*
1946 * Signal directly to RLMT to ensure correct
1947 * sequence of SWITCH and RESET event.
1948 */
1949 SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
1950 }
1951
1952 /* Restart needed */
1953 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
1954 break;
1955
1956 case SK_HW_PS_LINK:
1957 /* Signal to RLMT */
1958 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_UP, Para);
1959 break;
1960 }
1961
1962 /* Start again the check Timer */
1963 if (pPrt->PHWLinkUp) {
1964 Val32 = SK_WA_ACT_TIME;
1965 }
1966 else {
1967 Val32 = SK_WA_INA_TIME;
1968 }
1969
1970 /* Todo: still needed for non-XMAC PHYs??? */
1971 /* Start workaround Errata #2 timer */
1972 SkTimerStart(pAC, IoC, &pPrt->PWaTimer, Val32,
1973 SKGE_HWAC, SK_HWEV_WATIM, Para);
1974 break;
1975
1976 case SK_HWEV_PORT_START:
1977 if (pPrt->PHWLinkUp) {
1978 /*
1979 * Signal directly to RLMT to ensure correct
1980 * sequence of SWITCH and RESET event.
1981 */
1982 SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
1983 }
1984
1985 SkHWLinkDown(pAC, IoC, (int)Port);
1986
1987 /* Schedule Port RESET */
1988 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
1989
1990 /* Start workaround Errata #2 timer */
1991 SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
1992 SKGE_HWAC, SK_HWEV_WATIM, Para);
1993 break;
1994
1995 case SK_HWEV_PORT_STOP:
1996 if (pPrt->PHWLinkUp) {
1997 /*
1998 * Signal directly to RLMT to ensure correct
1999 * sequence of SWITCH and RESET event.
2000 */
2001 SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
2002 }
2003
2004 /* Stop Workaround Timer */
2005 SkTimerStop(pAC, IoC, &pPrt->PWaTimer);
2006
2007 SkHWLinkDown(pAC, IoC, (int)Port);
2008 break;
2009
2010 case SK_HWEV_UPDATE_STAT:
2011 /* We do NOT need to update any statistics */
2012 break;
2013
2014 case SK_HWEV_CLEAR_STAT:
2015 /* We do NOT need to clear any statistics */
2016 for (Port = 0; Port < (SK_U32)pAC->GIni.GIMacsFound; Port++) {
2017 pPrt->PPrevRx = 0;
2018 pPrt->PPrevFcs = 0;
2019 pPrt->PPrevShorts = 0;
2020 }
2021 break;
2022
2023 case SK_HWEV_SET_LMODE:
2024 Val8 = (SK_U8)Para.Para32[1];
2025 if (pPrt->PLinkModeConf != Val8) {
2026 /* Set New link mode */
2027 pPrt->PLinkModeConf = Val8;
2028
2029 /* Restart Port */
2030 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
2031 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
2032 }
2033 break;
2034
2035 case SK_HWEV_SET_FLOWMODE:
2036 Val8 = (SK_U8)Para.Para32[1];
2037 if (pPrt->PFlowCtrlMode != Val8) {
2038 /* Set New Flow Control mode */
2039 pPrt->PFlowCtrlMode = Val8;
2040
2041 /* Restart Port */
2042 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
2043 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
2044 }
2045 break;
2046
2047 case SK_HWEV_SET_ROLE:
2048 /* not possible for fiber */
2049 if (!pAC->GIni.GICopperType) {
2050 break;
2051 }
2052 Val8 = (SK_U8)Para.Para32[1];
2053 if (pPrt->PMSMode != Val8) {
2054 /* Set New Role (Master/Slave) mode */
2055 pPrt->PMSMode = Val8;
2056
2057 /* Restart Port */
2058 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
2059 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
2060 }
2061 break;
2062
2063 case SK_HWEV_SET_SPEED:
2064 if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
2065 break;
2066 }
2067 Val8 = (SK_U8)Para.Para32[1];
2068 if (pPrt->PLinkSpeed != Val8) {
2069 /* Set New Speed parameter */
2070 pPrt->PLinkSpeed = Val8;
2071
2072 /* Restart Port */
2073 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
2074 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
2075 }
2076 break;
2077
2078#ifdef GENESIS
2079 case SK_HWEV_HALFDUP_CHK:
2080 if (pAC->GIni.GIGenesis) {
2081 /*
2082 * half duplex hangup workaround.
2083 * See packet arbiter timeout interrupt for description
2084 */
2085 pPrt->HalfDupTimerActive = SK_FALSE;
2086 if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
2087 pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) {
2088#ifdef XXX
2089 Len = sizeof(SK_U64);
2090 SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets,
2091 &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port),
2092 pAC->Rlmt.Port[Port].Net->NetNumber);
2093#endif /* XXX */
2094 /* Snap statistic counters */
2095 (void)SkXmUpdateStats(pAC, IoC, Port);
2096
2097 (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_HI, &Val32);
2098
2099 Octets = (SK_U64)Val32 << 32;
2100
2101 (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_LO, &Val32);
2102
2103 Octets += Val32;
2104
2105 if (pPrt->LastOctets == Octets) {
2106 /* Tx hanging, a FIFO flush restarts it */
2107 SkMacFlushTxFifo(pAC, IoC, Port);
2108 }
2109 }
2110 }
2111 break;
2112#endif /* GENESIS */
2113
2114 default:
2115 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_SIRQ_E001, SKERR_SIRQ_E001MSG);
2116 break;
2117 }
2118
2119 return(0);
2120} /* SkGeSirqEvent */
2121
2122
2123#ifdef GENESIS
2124/******************************************************************************
2125 *
2126 * SkPhyIsrBcom() - PHY interrupt service routine
2127 *
2128 * Description: handles all interrupts from BCom PHY
2129 *
2130 * Returns: N/A
2131 */
2132static void SkPhyIsrBcom(
2133SK_AC *pAC, /* Adapter Context */
2134SK_IOC IoC, /* Io Context */
2135int Port, /* Port Num = PHY Num */
2136SK_U16 IStatus) /* Interrupt Status */
2137{
2138 SK_GEPORT *pPrt; /* GIni Port struct pointer */
2139 SK_EVPARA Para;
2140
2141 pPrt = &pAC->GIni.GP[Port];
2142
2143 if ((IStatus & PHY_B_IS_PSE) != 0) {
2144 /* Incorrectable pair swap error */
2145 SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E022,
2146 SKERR_SIRQ_E022MSG);
2147 }
2148
2149 if ((IStatus & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) != 0) {
2150
2151 SkHWLinkDown(pAC, IoC, Port);
2152
2153 Para.Para32[0] = (SK_U32)Port;
2154 /* Signal to RLMT */
2155 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
2156
2157 /* Start workaround Errata #2 timer */
2158 SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
2159 SKGE_HWAC, SK_HWEV_WATIM, Para);
2160 }
2161
2162} /* SkPhyIsrBcom */
2163#endif /* GENESIS */
2164
2165
2166#ifdef YUKON
2167/******************************************************************************
2168 *
2169 * SkPhyIsrGmac() - PHY interrupt service routine
2170 *
2171 * Description: handles all interrupts from Marvell PHY
2172 *
2173 * Returns: N/A
2174 */
2175static void SkPhyIsrGmac(
2176SK_AC *pAC, /* Adapter Context */
2177SK_IOC IoC, /* Io Context */
2178int Port, /* Port Num = PHY Num */
2179SK_U16 IStatus) /* Interrupt Status */
2180{
2181 SK_GEPORT *pPrt; /* GIni Port struct pointer */
2182 SK_EVPARA Para;
2183 SK_U16 Word;
2184
2185 pPrt = &pAC->GIni.GP[Port];
2186
2187 if ((IStatus & (PHY_M_IS_AN_PR | PHY_M_IS_LST_CHANGE)) != 0) {
2188
2189 SkHWLinkDown(pAC, IoC, Port);
2190
2191 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &Word);
2192
2193 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2194 ("AutoNeg.Adv: 0x%04X\n", Word));
2195
2196 /* Set Auto-negotiation advertisement */
2197 if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) {
2198 /* restore Asymmetric Pause bit */
2199 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV,
2200 (SK_U16)(Word | PHY_M_AN_ASP));
2201 }
2202
2203 Para.Para32[0] = (SK_U32)Port;
2204 /* Signal to RLMT */
2205 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
2206 }
2207
2208 if ((IStatus & PHY_M_IS_AN_ERROR) != 0) {
2209 /* Auto-Negotiation Error */
2210 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E023, SKERR_SIRQ_E023MSG);
2211 }
2212
2213 if ((IStatus & PHY_M_IS_FIFO_ERROR) != 0) {
2214 /* FIFO Overflow/Underrun Error */
2215 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E024, SKERR_SIRQ_E024MSG);
2216 }
2217
2218} /* SkPhyIsrGmac */
2219#endif /* YUKON */
2220
2221
2222#ifdef OTHER_PHY
2223/******************************************************************************
2224 *
2225 * SkPhyIsrLone() - PHY interrupt service routine
2226 *
2227 * Description: handles all interrupts from LONE PHY
2228 *
2229 * Returns: N/A
2230 */
2231static void SkPhyIsrLone(
2232SK_AC *pAC, /* Adapter Context */
2233SK_IOC IoC, /* Io Context */
2234int Port, /* Port Num = PHY Num */
2235SK_U16 IStatus) /* Interrupt Status */
2236{
2237 SK_EVPARA Para;
2238
2239 if (IStatus & (PHY_L_IS_DUP | PHY_L_IS_ISOL)) {
2240
2241 SkHWLinkDown(pAC, IoC, Port);
2242
2243 Para.Para32[0] = (SK_U32)Port;
2244 /* Signal to RLMT */
2245 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
2246 }
2247
2248} /* SkPhyIsrLone */
2249#endif /* OTHER_PHY */
2250
2251/* End of File */
diff --git a/drivers/net/sk98lin/ski2c.c b/drivers/net/sk98lin/ski2c.c
new file mode 100644
index 000000000000..075a0464e56b
--- /dev/null
+++ b/drivers/net/sk98lin/ski2c.c
@@ -0,0 +1,1296 @@
1/******************************************************************************
2 *
3 * Name: ski2c.c
4 * Project: Gigabit Ethernet Adapters, TWSI-Module
5 * Version: $Revision: 1.59 $
6 * Date: $Date: 2003/10/20 09:07:25 $
7 * Purpose: Functions to access Voltage and Temperature Sensor
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * I2C Protocol
27 */
28#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
29static const char SysKonnectFileId[] =
30 "@(#) $Id: ski2c.c,v 1.59 2003/10/20 09:07:25 rschmidt Exp $ (C) Marvell. ";
31#endif
32
33#include "h/skdrv1st.h" /* Driver Specific Definitions */
34#include "h/lm80.h"
35#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
36
37#ifdef __C2MAN__
38/*
39 I2C protocol implementation.
40
41 General Description:
42
43 The I2C protocol is used for the temperature sensors and for
44 the serial EEPROM which hold the configuration.
45
46 This file covers functions that allow to read write and do
47 some bulk requests a specified I2C address.
48
49 The Genesis has 2 I2C buses. One for the EEPROM which holds
50 the VPD Data and one for temperature and voltage sensor.
51 The following picture shows the I2C buses, I2C devices and
52 their control registers.
53
54 Note: The VPD functions are in skvpd.c
55.
56. PCI Config I2C Bus for VPD Data:
57.
58. +------------+
59. | VPD EEPROM |
60. +------------+
61. |
62. | <-- I2C
63. |
64. +-----------+-----------+
65. | |
66. +-----------------+ +-----------------+
67. | PCI_VPD_ADR_REG | | PCI_VPD_DAT_REG |
68. +-----------------+ +-----------------+
69.
70.
71. I2C Bus for LM80 sensor:
72.
73. +-----------------+
74. | Temperature and |
75. | Voltage Sensor |
76. | LM80 |
77. +-----------------+
78. |
79. |
80. I2C --> |
81. |
82. +----+
83. +-------------->| OR |<--+
84. | +----+ |
85. +------+------+ |
86. | | |
87. +--------+ +--------+ +----------+
88. | B2_I2C | | B2_I2C | | B2_I2C |
89. | _CTRL | | _DATA | | _SW |
90. +--------+ +--------+ +----------+
91.
92 The I2C bus may be driven by the B2_I2C_SW or by the B2_I2C_CTRL
93 and B2_I2C_DATA registers.
94 For driver software it is recommended to use the I2C control and
95 data register, because I2C bus timing is done by the ASIC and
96 an interrupt may be received when the I2C request is completed.
97
98 Clock Rate Timing: MIN MAX generated by
99 VPD EEPROM: 50 kHz 100 kHz HW
100 LM80 over I2C Ctrl/Data reg. 50 kHz 100 kHz HW
101 LM80 over B2_I2C_SW register 0 400 kHz SW
102
103 Note: The clock generated by the hardware is dependend on the
104 PCI clock. If the PCI bus clock is 33 MHz, the I2C/VPD
105 clock is 50 kHz.
106 */
107intro()
108{}
109#endif
110
111#ifdef SK_DIAG
112/*
113 * I2C Fast Mode timing values used by the LM80.
114 * If new devices are added to the I2C bus the timing values have to be checked.
115 */
116#ifndef I2C_SLOW_TIMING
117#define T_CLK_LOW 1300L /* clock low time in ns */
118#define T_CLK_HIGH 600L /* clock high time in ns */
119#define T_DATA_IN_SETUP 100L /* data in Set-up Time */
120#define T_START_HOLD 600L /* start condition hold time */
121#define T_START_SETUP 600L /* start condition Set-up time */
122#define T_STOP_SETUP 600L /* stop condition Set-up time */
123#define T_BUS_IDLE 1300L /* time the bus must free after Tx */
124#define T_CLK_2_DATA_OUT 900L /* max. clock low to data output valid */
125#else /* I2C_SLOW_TIMING */
126/* I2C Standard Mode Timing */
127#define T_CLK_LOW 4700L /* clock low time in ns */
128#define T_CLK_HIGH 4000L /* clock high time in ns */
129#define T_DATA_IN_SETUP 250L /* data in Set-up Time */
130#define T_START_HOLD 4000L /* start condition hold time */
131#define T_START_SETUP 4700L /* start condition Set-up time */
132#define T_STOP_SETUP 4000L /* stop condition Set-up time */
133#define T_BUS_IDLE 4700L /* time the bus must free after Tx */
134#endif /* !I2C_SLOW_TIMING */
135
136#define NS2BCLK(x) (((x)*125)/10000)
137
138/*
139 * I2C Wire Operations
140 *
141 * About I2C_CLK_LOW():
142 *
143 * The Data Direction bit (I2C_DATA_DIR) has to be set to input when setting
144 * clock to low, to prevent the ASIC and the I2C data client from driving the
145 * serial data line simultaneously (ASIC: last bit of a byte = '1', I2C client
146 * send an 'ACK'). See also Concentrator Bugreport No. 10192.
147 */
148#define I2C_DATA_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA)
149#define I2C_DATA_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA)
150#define I2C_DATA_OUT(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA_DIR)
151#define I2C_DATA_IN(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA)
152#define I2C_CLK_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_CLK)
153#define I2C_CLK_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK | I2C_DATA_DIR)
154#define I2C_START_COND(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK)
155
156#define NS2CLKT(x) ((x*125L)/10000)
157
158/*--------------- I2C Interface Register Functions --------------- */
159
160/*
161 * sending one bit
162 */
163void SkI2cSndBit(
164SK_IOC IoC, /* I/O Context */
165SK_U8 Bit) /* Bit to send */
166{
167 I2C_DATA_OUT(IoC);
168 if (Bit) {
169 I2C_DATA_HIGH(IoC);
170 }
171 else {
172 I2C_DATA_LOW(IoC);
173 }
174 SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP));
175 I2C_CLK_HIGH(IoC);
176 SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
177 I2C_CLK_LOW(IoC);
178} /* SkI2cSndBit*/
179
180
181/*
182 * Signal a start to the I2C Bus.
183 *
184 * A start is signaled when data goes to low in a high clock cycle.
185 *
186 * Ends with Clock Low.
187 *
188 * Status: not tested
189 */
190void SkI2cStart(
191SK_IOC IoC) /* I/O Context */
192{
193 /* Init data and Clock to output lines */
194 /* Set Data high */
195 I2C_DATA_OUT(IoC);
196 I2C_DATA_HIGH(IoC);
197 /* Set Clock high */
198 I2C_CLK_HIGH(IoC);
199
200 SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP));
201
202 /* Set Data Low */
203 I2C_DATA_LOW(IoC);
204
205 SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD));
206
207 /* Clock low without Data to Input */
208 I2C_START_COND(IoC);
209
210 SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW));
211} /* SkI2cStart */
212
213
214void SkI2cStop(
215SK_IOC IoC) /* I/O Context */
216{
217 /* Init data and Clock to output lines */
218 /* Set Data low */
219 I2C_DATA_OUT(IoC);
220 I2C_DATA_LOW(IoC);
221
222 SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
223
224 /* Set Clock high */
225 I2C_CLK_HIGH(IoC);
226
227 SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP));
228
229 /*
230 * Set Data High: Do it by setting the Data Line to Input.
231 * Because of a pull up resistor the Data Line
232 * floods to high.
233 */
234 I2C_DATA_IN(IoC);
235
236 /*
237 * When I2C activity is stopped
238 * o DATA should be set to input and
239 * o CLOCK should be set to high!
240 */
241 SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE));
242} /* SkI2cStop */
243
244
245/*
246 * Receive just one bit via the I2C bus.
247 *
248 * Note: Clock must be set to LOW before calling this function.
249 *
250 * Returns The received bit.
251 */
252int SkI2cRcvBit(
253SK_IOC IoC) /* I/O Context */
254{
255 int Bit;
256 SK_U8 I2cSwCtrl;
257
258 /* Init data as input line */
259 I2C_DATA_IN(IoC);
260
261 SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
262
263 I2C_CLK_HIGH(IoC);
264
265 SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
266
267 SK_I2C_GET_SW(IoC, &I2cSwCtrl);
268
269 Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0;
270
271 I2C_CLK_LOW(IoC);
272 SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT));
273
274 return(Bit);
275} /* SkI2cRcvBit */
276
277
278/*
279 * Receive an ACK.
280 *
281 * returns 0 If acknowledged
282 * 1 in case of an error
283 */
284int SkI2cRcvAck(
285SK_IOC IoC) /* I/O Context */
286{
287 /*
288 * Received bit must be zero.
289 */
290 return(SkI2cRcvBit(IoC) != 0);
291} /* SkI2cRcvAck */
292
293
294/*
295 * Send an NACK.
296 */
297void SkI2cSndNAck(
298SK_IOC IoC) /* I/O Context */
299{
300 /*
301 * Received bit must be zero.
302 */
303 SkI2cSndBit(IoC, 1);
304} /* SkI2cSndNAck */
305
306
307/*
308 * Send an ACK.
309 */
310void SkI2cSndAck(
311SK_IOC IoC) /* I/O Context */
312{
313 /*
314 * Received bit must be zero.
315 */
316 SkI2cSndBit(IoC, 0);
317} /* SkI2cSndAck */
318
319
320/*
321 * Send one byte to the I2C device and wait for ACK.
322 *
323 * Return acknowleged status.
324 */
325int SkI2cSndByte(
326SK_IOC IoC, /* I/O Context */
327int Byte) /* byte to send */
328{
329 int i;
330
331 for (i = 0; i < 8; i++) {
332 if (Byte & (1<<(7-i))) {
333 SkI2cSndBit(IoC, 1);
334 }
335 else {
336 SkI2cSndBit(IoC, 0);
337 }
338 }
339
340 return(SkI2cRcvAck(IoC));
341} /* SkI2cSndByte */
342
343
344/*
345 * Receive one byte and ack it.
346 *
347 * Return byte.
348 */
349int SkI2cRcvByte(
350SK_IOC IoC, /* I/O Context */
351int Last) /* Last Byte Flag */
352{
353 int i;
354 int Byte = 0;
355
356 for (i = 0; i < 8; i++) {
357 Byte <<= 1;
358 Byte |= SkI2cRcvBit(IoC);
359 }
360
361 if (Last) {
362 SkI2cSndNAck(IoC);
363 }
364 else {
365 SkI2cSndAck(IoC);
366 }
367
368 return(Byte);
369} /* SkI2cRcvByte */
370
371
372/*
373 * Start dialog and send device address
374 *
375 * Return 0 if acknowleged, 1 in case of an error
376 */
377int SkI2cSndDev(
378SK_IOC IoC, /* I/O Context */
379int Addr, /* Device Address */
380int Rw) /* Read / Write Flag */
381{
382 SkI2cStart(IoC);
383 Rw = ~Rw;
384 Rw &= I2C_WRITE;
385 return(SkI2cSndByte(IoC, (Addr<<1) | Rw));
386} /* SkI2cSndDev */
387
388#endif /* SK_DIAG */
389
390/*----------------- I2C CTRL Register Functions ----------*/
391
392/*
393 * waits for a completion of an I2C transfer
394 *
395 * returns 0: success, transfer completes
396 * 1: error, transfer does not complete, I2C transfer
397 * killed, wait loop terminated.
398 */
399int SkI2cWait(
400SK_AC *pAC, /* Adapter Context */
401SK_IOC IoC, /* I/O Context */
402int Event) /* complete event to wait for (I2C_READ or I2C_WRITE) */
403{
404 SK_U64 StartTime;
405 SK_U64 CurrentTime;
406 SK_U32 I2cCtrl;
407
408 StartTime = SkOsGetTime(pAC);
409
410 do {
411 CurrentTime = SkOsGetTime(pAC);
412
413 if (CurrentTime - StartTime > SK_TICKS_PER_SEC / 8) {
414
415 SK_I2C_STOP(IoC);
416#ifndef SK_DIAG
417 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG);
418#endif /* !SK_DIAG */
419 return(1);
420 }
421
422 SK_I2C_GET_CTL(IoC, &I2cCtrl);
423
424#ifdef xYUKON_DBG
425 printf("StartTime=%lu, CurrentTime=%lu\n",
426 StartTime, CurrentTime);
427 if (kbhit()) {
428 return(1);
429 }
430#endif /* YUKON_DBG */
431
432 } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31);
433
434 return(0);
435} /* SkI2cWait */
436
437
438/*
439 * waits for a completion of an I2C transfer
440 *
441 * Returns
442 * Nothing
443 */
444void SkI2cWaitIrq(
445SK_AC *pAC, /* Adapter Context */
446SK_IOC IoC) /* I/O Context */
447{
448 SK_SENSOR *pSen;
449 SK_U64 StartTime;
450 SK_U32 IrqSrc;
451
452 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
453
454 if (pSen->SenState == SK_SEN_IDLE) {
455 return;
456 }
457
458 StartTime = SkOsGetTime(pAC);
459
460 do {
461 if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) {
462
463 SK_I2C_STOP(IoC);
464#ifndef SK_DIAG
465 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG);
466#endif /* !SK_DIAG */
467 return;
468 }
469
470 SK_IN32(IoC, B0_ISRC, &IrqSrc);
471
472 } while ((IrqSrc & IS_I2C_READY) == 0);
473
474 pSen->SenState = SK_SEN_IDLE;
475 return;
476} /* SkI2cWaitIrq */
477
478/*
479 * writes a single byte or 4 bytes into the I2C device
480 *
481 * returns 0: success
482 * 1: error
483 */
484int SkI2cWrite(
485SK_AC *pAC, /* Adapter Context */
486SK_IOC IoC, /* I/O Context */
487SK_U32 I2cData, /* I2C Data to write */
488int I2cDev, /* I2C Device Address */
489int I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
490int I2cReg, /* I2C Device Register Address */
491int I2cBurst) /* I2C Burst Flag */
492{
493 SK_OUT32(IoC, B2_I2C_DATA, I2cData);
494
495 SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cDevSize, I2cReg, I2cBurst);
496
497 return(SkI2cWait(pAC, IoC, I2C_WRITE));
498} /* SkI2cWrite*/
499
500
501#ifdef SK_DIAG
502/*
503 * reads a single byte or 4 bytes from the I2C device
504 *
505 * returns the word read
506 */
507SK_U32 SkI2cRead(
508SK_AC *pAC, /* Adapter Context */
509SK_IOC IoC, /* I/O Context */
510int I2cDev, /* I2C Device Address */
511int I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
512int I2cReg, /* I2C Device Register Address */
513int I2cBurst) /* I2C Burst Flag */
514{
515 SK_U32 Data;
516
517 SK_OUT32(IoC, B2_I2C_DATA, 0);
518 SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cDevSize, I2cReg, I2cBurst);
519
520 if (SkI2cWait(pAC, IoC, I2C_READ) != 0) {
521 w_print("%s\n", SKERR_I2C_E002MSG);
522 }
523
524 SK_IN32(IoC, B2_I2C_DATA, &Data);
525
526 return(Data);
527} /* SkI2cRead */
528#endif /* SK_DIAG */
529
530
531/*
532 * read a sensor's value
533 *
534 * This function reads a sensor's value from the I2C sensor chip. The sensor
535 * is defined by its index into the sensors database in the struct pAC points
536 * to.
537 * Returns
538 * 1 if the read is completed
539 * 0 if the read must be continued (I2C Bus still allocated)
540 */
541int SkI2cReadSensor(
542SK_AC *pAC, /* Adapter Context */
543SK_IOC IoC, /* I/O Context */
544SK_SENSOR *pSen) /* Sensor to be read */
545{
546 if (pSen->SenRead != NULL) {
547 return((*pSen->SenRead)(pAC, IoC, pSen));
548 }
549 else {
550 return(0); /* no success */
551 }
552} /* SkI2cReadSensor */
553
554/*
555 * Do the Init state 0 initialization
556 */
557static int SkI2cInit0(
558SK_AC *pAC) /* Adapter Context */
559{
560 int i;
561
562 /* Begin with first sensor */
563 pAC->I2c.CurrSens = 0;
564
565 /* Begin with timeout control for state machine */
566 pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
567
568 /* Set sensor number to zero */
569 pAC->I2c.MaxSens = 0;
570
571#ifndef SK_DIAG
572 /* Initialize Number of Dummy Reads */
573 pAC->I2c.DummyReads = SK_MAX_SENSORS;
574#endif
575
576 for (i = 0; i < SK_MAX_SENSORS; i++) {
577 pAC->I2c.SenTable[i].SenDesc = "unknown";
578 pAC->I2c.SenTable[i].SenType = SK_SEN_UNKNOWN;
579 pAC->I2c.SenTable[i].SenThreErrHigh = 0;
580 pAC->I2c.SenTable[i].SenThreErrLow = 0;
581 pAC->I2c.SenTable[i].SenThreWarnHigh = 0;
582 pAC->I2c.SenTable[i].SenThreWarnLow = 0;
583 pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
584 pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_NONE;
585 pAC->I2c.SenTable[i].SenValue = 0;
586 pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_NOT_PRESENT;
587 pAC->I2c.SenTable[i].SenErrCts = 0;
588 pAC->I2c.SenTable[i].SenBegErrTS = 0;
589 pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
590 pAC->I2c.SenTable[i].SenRead = NULL;
591 pAC->I2c.SenTable[i].SenDev = 0;
592 }
593
594 /* Now we are "INIT data"ed */
595 pAC->I2c.InitLevel = SK_INIT_DATA;
596 return(0);
597} /* SkI2cInit0*/
598
599
600/*
601 * Do the init state 1 initialization
602 *
603 * initialize the following register of the LM80:
604 * Configuration register:
605 * - START, noINT, activeLOW, noINT#Clear, noRESET, noCI, noGPO#, noINIT
606 *
607 * Interrupt Mask Register 1:
608 * - all interrupts are Disabled (0xff)
609 *
610 * Interrupt Mask Register 2:
611 * - all interrupts are Disabled (0xff) Interrupt modi doesn't matter.
612 *
613 * Fan Divisor/RST_OUT register:
614 * - Divisors set to 1 (bits 00), all others 0s.
615 *
616 * OS# Configuration/Temperature resolution Register:
617 * - all 0s
618 *
619 */
620static int SkI2cInit1(
621SK_AC *pAC, /* Adapter Context */
622SK_IOC IoC) /* I/O Context */
623{
624 int i;
625 SK_U8 I2cSwCtrl;
626 SK_GEPORT *pPrt; /* GIni Port struct pointer */
627
628 if (pAC->I2c.InitLevel != SK_INIT_DATA) {
629 /* ReInit not needed in I2C module */
630 return(0);
631 }
632
633 /* Set the Direction of I2C-Data Pin to IN */
634 SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA);
635 /* Check for 32-Bit Yukon with Low at I2C-Data Pin */
636 SK_I2C_GET_SW(IoC, &I2cSwCtrl);
637
638 if ((I2cSwCtrl & I2C_DATA) == 0) {
639 /* this is a 32-Bit board */
640 pAC->GIni.GIYukon32Bit = SK_TRUE;
641 return(0);
642 }
643
644 /* Check for 64 Bit Yukon without sensors */
645 if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_CFG, 0) != 0) {
646 return(0);
647 }
648
649 (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_1, 0);
650
651 (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_2, 0);
652
653 (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_FAN_CTRL, 0);
654
655 (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_TEMP_CTRL, 0);
656
657 (void)SkI2cWrite(pAC, IoC, (SK_U32)LM80_CFG_START, LM80_ADDR, I2C_025K_DEV,
658 LM80_CFG, 0);
659
660 /*
661 * MaxSens has to be updated here, because PhyType is not
662 * set when performing Init Level 0
663 */
664 pAC->I2c.MaxSens = 5;
665
666 pPrt = &pAC->GIni.GP[0];
667
668 if (pAC->GIni.GIGenesis) {
669 if (pPrt->PhyType == SK_PHY_BCOM) {
670 if (pAC->GIni.GIMacsFound == 1) {
671 pAC->I2c.MaxSens += 1;
672 }
673 else {
674 pAC->I2c.MaxSens += 3;
675 }
676 }
677 }
678 else {
679 pAC->I2c.MaxSens += 3;
680 }
681
682 for (i = 0; i < pAC->I2c.MaxSens; i++) {
683 switch (i) {
684 case 0:
685 pAC->I2c.SenTable[i].SenDesc = "Temperature";
686 pAC->I2c.SenTable[i].SenType = SK_SEN_TEMP;
687 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_TEMP_HIGH_ERR;
688 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_TEMP_HIGH_WARN;
689 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_TEMP_LOW_WARN;
690 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_TEMP_LOW_ERR;
691 pAC->I2c.SenTable[i].SenReg = LM80_TEMP_IN;
692 break;
693 case 1:
694 pAC->I2c.SenTable[i].SenDesc = "Voltage PCI";
695 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
696 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_5V_HIGH_ERR;
697 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_5V_HIGH_WARN;
698 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_5V_LOW_WARN;
699 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_5V_LOW_ERR;
700 pAC->I2c.SenTable[i].SenReg = LM80_VT0_IN;
701 break;
702 case 2:
703 pAC->I2c.SenTable[i].SenDesc = "Voltage PCI-IO";
704 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
705 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_IO_5V_HIGH_ERR;
706 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_IO_5V_HIGH_WARN;
707 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_IO_3V3_LOW_WARN;
708 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_IO_3V3_LOW_ERR;
709 pAC->I2c.SenTable[i].SenReg = LM80_VT1_IN;
710 pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_PCI_IO;
711 break;
712 case 3:
713 pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC";
714 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
715 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VDD_HIGH_ERR;
716 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VDD_HIGH_WARN;
717 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VDD_LOW_WARN;
718 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VDD_LOW_ERR;
719 pAC->I2c.SenTable[i].SenReg = LM80_VT2_IN;
720 break;
721 case 4:
722 if (pAC->GIni.GIGenesis) {
723 if (pPrt->PhyType == SK_PHY_BCOM) {
724 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY A PLL";
725 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
726 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
727 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
728 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
729 }
730 else {
731 pAC->I2c.SenTable[i].SenDesc = "Voltage PMA";
732 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
733 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
734 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
735 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
736 }
737 }
738 else {
739 pAC->I2c.SenTable[i].SenDesc = "Voltage VAUX";
740 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VAUX_3V3_HIGH_ERR;
741 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VAUX_3V3_HIGH_WARN;
742 if (pAC->GIni.GIVauxAvail) {
743 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
744 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
745 }
746 else {
747 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_0V_WARN_ERR;
748 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_0V_WARN_ERR;
749 }
750 }
751 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
752 pAC->I2c.SenTable[i].SenReg = LM80_VT3_IN;
753 break;
754 case 5:
755 if (pAC->GIni.GIGenesis) {
756 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
757 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
758 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
759 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
760 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
761 }
762 else {
763 pAC->I2c.SenTable[i].SenDesc = "Voltage Core 1V5";
764 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR;
765 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN;
766 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN;
767 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR;
768 }
769 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
770 pAC->I2c.SenTable[i].SenReg = LM80_VT4_IN;
771 break;
772 case 6:
773 if (pAC->GIni.GIGenesis) {
774 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY B PLL";
775 }
776 else {
777 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 3V3";
778 }
779 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
780 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
781 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
782 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
783 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
784 pAC->I2c.SenTable[i].SenReg = LM80_VT5_IN;
785 break;
786 case 7:
787 if (pAC->GIni.GIGenesis) {
788 pAC->I2c.SenTable[i].SenDesc = "Speed Fan";
789 pAC->I2c.SenTable[i].SenType = SK_SEN_FAN;
790 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_FAN_HIGH_ERR;
791 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_FAN_HIGH_WARN;
792 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_FAN_LOW_WARN;
793 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_FAN_LOW_ERR;
794 pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
795 }
796 else {
797 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
798 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
799 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
800 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
801 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
802 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
803 pAC->I2c.SenTable[i].SenReg = LM80_VT6_IN;
804 }
805 break;
806 default:
807 SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW,
808 SKERR_I2C_E001, SKERR_I2C_E001MSG);
809 break;
810 }
811
812 pAC->I2c.SenTable[i].SenValue = 0;
813 pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
814 pAC->I2c.SenTable[i].SenErrCts = 0;
815 pAC->I2c.SenTable[i].SenBegErrTS = 0;
816 pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
817 pAC->I2c.SenTable[i].SenRead = SkLm80ReadSensor;
818 pAC->I2c.SenTable[i].SenDev = LM80_ADDR;
819 }
820
821#ifndef SK_DIAG
822 pAC->I2c.DummyReads = pAC->I2c.MaxSens;
823#endif /* !SK_DIAG */
824
825 /* Clear I2C IRQ */
826 SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
827
828 /* Now we are I/O initialized */
829 pAC->I2c.InitLevel = SK_INIT_IO;
830 return(0);
831} /* SkI2cInit1 */
832
833
834/*
835 * Init level 2: Start first sensor read.
836 */
837static int SkI2cInit2(
838SK_AC *pAC, /* Adapter Context */
839SK_IOC IoC) /* I/O Context */
840{
841 int ReadComplete;
842 SK_SENSOR *pSen;
843
844 if (pAC->I2c.InitLevel != SK_INIT_IO) {
845 /* ReInit not needed in I2C module */
846 /* Init0 and Init2 not permitted */
847 return(0);
848 }
849
850 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
851 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
852
853 if (ReadComplete) {
854 SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG);
855 }
856
857 /* Now we are correctly initialized */
858 pAC->I2c.InitLevel = SK_INIT_RUN;
859
860 return(0);
861} /* SkI2cInit2*/
862
863
864/*
865 * Initialize I2C devices
866 *
867 * Get the first voltage value and discard it.
868 * Go into temperature read mode. A default pointer is not set.
869 *
870 * The things to be done depend on the init level in the parameter list:
871 * Level 0:
872 * Initialize only the data structures. Do NOT access hardware.
873 * Level 1:
874 * Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts.
875 * Level 2:
876 * Everything is possible. Interrupts may be used from now on.
877 *
878 * return:
879 * 0 = success
880 * other = error.
881 */
882int SkI2cInit(
883SK_AC *pAC, /* Adapter Context */
884SK_IOC IoC, /* I/O Context needed in levels 1 and 2 */
885int Level) /* Init Level */
886{
887
888 switch (Level) {
889 case SK_INIT_DATA:
890 return(SkI2cInit0(pAC));
891 case SK_INIT_IO:
892 return(SkI2cInit1(pAC, IoC));
893 case SK_INIT_RUN:
894 return(SkI2cInit2(pAC, IoC));
895 default:
896 break;
897 }
898
899 return(0);
900} /* SkI2cInit */
901
902
903#ifndef SK_DIAG
904
905/*
906 * Interrupt service function for the I2C Interface
907 *
908 * Clears the Interrupt source
909 *
910 * Reads the register and check it for sending a trap.
911 *
912 * Starts the timer if necessary.
913 */
914void SkI2cIsr(
915SK_AC *pAC, /* Adapter Context */
916SK_IOC IoC) /* I/O Context */
917{
918 SK_EVPARA Para;
919
920 /* Clear I2C IRQ */
921 SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
922
923 Para.Para64 = 0;
924 SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para);
925} /* SkI2cIsr */
926
927
928/*
929 * Check this sensors Value against the threshold and send events.
930 */
931static void SkI2cCheckSensor(
932SK_AC *pAC, /* Adapter Context */
933SK_SENSOR *pSen)
934{
935 SK_EVPARA ParaLocal;
936 SK_BOOL TooHigh; /* Is sensor too high? */
937 SK_BOOL TooLow; /* Is sensor too low? */
938 SK_U64 CurrTime; /* Current Time */
939 SK_BOOL DoTrapSend; /* We need to send a trap */
940 SK_BOOL DoErrLog; /* We need to log the error */
941 SK_BOOL IsError; /* We need to log the error */
942
943 /* Check Dummy Reads first */
944 if (pAC->I2c.DummyReads > 0) {
945 pAC->I2c.DummyReads--;
946 return;
947 }
948
949 /* Get the current time */
950 CurrTime = SkOsGetTime(pAC);
951
952 /* Set para to the most useful setting: The current sensor. */
953 ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens;
954
955 /* Check the Value against the thresholds. First: Error Thresholds */
956 TooHigh = (pSen->SenValue > pSen->SenThreErrHigh);
957 TooLow = (pSen->SenValue < pSen->SenThreErrLow);
958
959 IsError = SK_FALSE;
960 if (TooHigh || TooLow) {
961 /* Error condition is satisfied */
962 DoTrapSend = SK_TRUE;
963 DoErrLog = SK_TRUE;
964
965 /* Now error condition is satisfied */
966 IsError = SK_TRUE;
967
968 if (pSen->SenErrFlag == SK_SEN_ERR_ERR) {
969 /* This state is the former one */
970
971 /* So check first whether we have to send a trap */
972 if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD >
973 CurrTime) {
974 /*
975 * Do NOT send the Trap. The hold back time
976 * has to run out first.
977 */
978 DoTrapSend = SK_FALSE;
979 }
980
981 /* Check now whether we have to log an Error */
982 if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD >
983 CurrTime) {
984 /*
985 * Do NOT log the error. The hold back time
986 * has to run out first.
987 */
988 DoErrLog = SK_FALSE;
989 }
990 }
991 else {
992 /* We came from a different state -> Set Begin Time Stamp */
993 pSen->SenBegErrTS = CurrTime;
994 pSen->SenErrFlag = SK_SEN_ERR_ERR;
995 }
996
997 if (DoTrapSend) {
998 /* Set current Time */
999 pSen->SenLastErrTrapTS = CurrTime;
1000 pSen->SenErrCts++;
1001
1002 /* Queue PNMI Event */
1003 SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
1004 SK_PNMI_EVT_SEN_ERR_UPP :
1005 SK_PNMI_EVT_SEN_ERR_LOW),
1006 ParaLocal);
1007 }
1008
1009 if (DoErrLog) {
1010 /* Set current Time */
1011 pSen->SenLastErrLogTS = CurrTime;
1012
1013 if (pSen->SenType == SK_SEN_TEMP) {
1014 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011, SKERR_I2C_E011MSG);
1015 }
1016 else if (pSen->SenType == SK_SEN_VOLT) {
1017 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012, SKERR_I2C_E012MSG);
1018 }
1019 else {
1020 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015, SKERR_I2C_E015MSG);
1021 }
1022 }
1023 }
1024
1025 /* Check the Value against the thresholds */
1026 /* 2nd: Warning thresholds */
1027 TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh);
1028 TooLow = (pSen->SenValue < pSen->SenThreWarnLow);
1029
1030 if (!IsError && (TooHigh || TooLow)) {
1031 /* Error condition is satisfied */
1032 DoTrapSend = SK_TRUE;
1033 DoErrLog = SK_TRUE;
1034
1035 if (pSen->SenErrFlag == SK_SEN_ERR_WARN) {
1036 /* This state is the former one */
1037
1038 /* So check first whether we have to send a trap */
1039 if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD > CurrTime) {
1040 /*
1041 * Do NOT send the Trap. The hold back time
1042 * has to run out first.
1043 */
1044 DoTrapSend = SK_FALSE;
1045 }
1046
1047 /* Check now whether we have to log an Error */
1048 if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD > CurrTime) {
1049 /*
1050 * Do NOT log the error. The hold back time
1051 * has to run out first.
1052 */
1053 DoErrLog = SK_FALSE;
1054 }
1055 }
1056 else {
1057 /* We came from a different state -> Set Begin Time Stamp */
1058 pSen->SenBegWarnTS = CurrTime;
1059 pSen->SenErrFlag = SK_SEN_ERR_WARN;
1060 }
1061
1062 if (DoTrapSend) {
1063 /* Set current Time */
1064 pSen->SenLastWarnTrapTS = CurrTime;
1065 pSen->SenWarnCts++;
1066
1067 /* Queue PNMI Event */
1068 SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
1069 SK_PNMI_EVT_SEN_WAR_UPP :
1070 SK_PNMI_EVT_SEN_WAR_LOW),
1071 ParaLocal);
1072 }
1073
1074 if (DoErrLog) {
1075 /* Set current Time */
1076 pSen->SenLastWarnLogTS = CurrTime;
1077
1078 if (pSen->SenType == SK_SEN_TEMP) {
1079 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009, SKERR_I2C_E009MSG);
1080 }
1081 else if (pSen->SenType == SK_SEN_VOLT) {
1082 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010, SKERR_I2C_E010MSG);
1083 }
1084 else {
1085 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014, SKERR_I2C_E014MSG);
1086 }
1087 }
1088 }
1089
1090 /* Check for NO error at all */
1091 if (!IsError && !TooHigh && !TooLow) {
1092 /* Set o.k. Status if no error and no warning condition */
1093 pSen->SenErrFlag = SK_SEN_ERR_OK;
1094 }
1095
1096 /* End of check against the thresholds */
1097
1098 /* Bug fix AF: 16.Aug.2001: Correct the init base
1099 * of LM80 sensor.
1100 */
1101 if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) {
1102
1103 pSen->SenInit = SK_SEN_DYN_INIT_NONE;
1104
1105 if (pSen->SenValue > SK_SEN_PCI_IO_RANGE_LIMITER) {
1106 /* 5V PCI-IO Voltage */
1107 pSen->SenThreWarnLow = SK_SEN_PCI_IO_5V_LOW_WARN;
1108 pSen->SenThreErrLow = SK_SEN_PCI_IO_5V_LOW_ERR;
1109 }
1110 else {
1111 /* 3.3V PCI-IO Voltage */
1112 pSen->SenThreWarnHigh = SK_SEN_PCI_IO_3V3_HIGH_WARN;
1113 pSen->SenThreErrHigh = SK_SEN_PCI_IO_3V3_HIGH_ERR;
1114 }
1115 }
1116
1117#ifdef TEST_ONLY
1118 /* Dynamic thresholds also for VAUX of LM80 sensor */
1119 if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) {
1120
1121 pSen->SenInit = SK_SEN_DYN_INIT_NONE;
1122
1123 /* 3.3V VAUX Voltage */
1124 if (pSen->SenValue > SK_SEN_VAUX_RANGE_LIMITER) {
1125 pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
1126 pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
1127 }
1128 /* 0V VAUX Voltage */
1129 else {
1130 pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR;
1131 pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR;
1132 }
1133 }
1134
1135 /*
1136 * Check initialization state:
1137 * The VIO Thresholds need adaption
1138 */
1139 if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
1140 pSen->SenValue > SK_SEN_WARNLOW2C &&
1141 pSen->SenValue < SK_SEN_WARNHIGH2) {
1142 pSen->SenThreErrLow = SK_SEN_ERRLOW2C;
1143 pSen->SenThreWarnLow = SK_SEN_WARNLOW2C;
1144 pSen->SenInit = SK_TRUE;
1145 }
1146
1147 if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
1148 pSen->SenValue > SK_SEN_WARNLOW2 &&
1149 pSen->SenValue < SK_SEN_WARNHIGH2C) {
1150 pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C;
1151 pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C;
1152 pSen->SenInit = SK_TRUE;
1153 }
1154#endif
1155
1156 if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) {
1157 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG);
1158 }
1159} /* SkI2cCheckSensor */
1160
1161
1162/*
1163 * The only Event to be served is the timeout event
1164 *
1165 */
1166int SkI2cEvent(
1167SK_AC *pAC, /* Adapter Context */
1168SK_IOC IoC, /* I/O Context */
1169SK_U32 Event, /* Module specific Event */
1170SK_EVPARA Para) /* Event specific Parameter */
1171{
1172 int ReadComplete;
1173 SK_SENSOR *pSen;
1174 SK_U32 Time;
1175 SK_EVPARA ParaLocal;
1176 int i;
1177
1178 /* New case: no sensors */
1179 if (pAC->I2c.MaxSens == 0) {
1180 return(0);
1181 }
1182
1183 switch (Event) {
1184 case SK_I2CEV_IRQ:
1185 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1186 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1187
1188 if (ReadComplete) {
1189 /* Check sensor against defined thresholds */
1190 SkI2cCheckSensor(pAC, pSen);
1191
1192 /* Increment Current sensor and set appropriate Timeout */
1193 pAC->I2c.CurrSens++;
1194 if (pAC->I2c.CurrSens >= pAC->I2c.MaxSens) {
1195 pAC->I2c.CurrSens = 0;
1196 Time = SK_I2C_TIM_LONG;
1197 }
1198 else {
1199 Time = SK_I2C_TIM_SHORT;
1200 }
1201
1202 /* Start Timer */
1203 ParaLocal.Para64 = (SK_U64)0;
1204
1205 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1206
1207 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1208 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1209 }
1210 else {
1211 /* Start Timer */
1212 ParaLocal.Para64 = (SK_U64)0;
1213
1214 pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
1215
1216 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH,
1217 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1218 }
1219 break;
1220 case SK_I2CEV_TIM:
1221 if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) {
1222
1223 ParaLocal.Para64 = (SK_U64)0;
1224 SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer);
1225
1226 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1227 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1228
1229 if (ReadComplete) {
1230 /* Check sensor against defined thresholds */
1231 SkI2cCheckSensor(pAC, pSen);
1232
1233 /* Increment Current sensor and set appropriate Timeout */
1234 pAC->I2c.CurrSens++;
1235 if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
1236 pAC->I2c.CurrSens = 0;
1237 Time = SK_I2C_TIM_LONG;
1238 }
1239 else {
1240 Time = SK_I2C_TIM_SHORT;
1241 }
1242
1243 /* Start Timer */
1244 ParaLocal.Para64 = (SK_U64)0;
1245
1246 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1247
1248 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1249 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1250 }
1251 }
1252 else {
1253 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1254 pSen->SenErrFlag = SK_SEN_ERR_FAULTY;
1255 SK_I2C_STOP(IoC);
1256
1257 /* Increment Current sensor and set appropriate Timeout */
1258 pAC->I2c.CurrSens++;
1259 if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
1260 pAC->I2c.CurrSens = 0;
1261 Time = SK_I2C_TIM_LONG;
1262 }
1263 else {
1264 Time = SK_I2C_TIM_SHORT;
1265 }
1266
1267 /* Start Timer */
1268 ParaLocal.Para64 = (SK_U64)0;
1269
1270 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1271
1272 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1273 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1274 }
1275 break;
1276 case SK_I2CEV_CLEAR:
1277 for (i = 0; i < SK_MAX_SENSORS; i++) {
1278 pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
1279 pAC->I2c.SenTable[i].SenErrCts = 0;
1280 pAC->I2c.SenTable[i].SenWarnCts = 0;
1281 pAC->I2c.SenTable[i].SenBegErrTS = 0;
1282 pAC->I2c.SenTable[i].SenBegWarnTS = 0;
1283 pAC->I2c.SenTable[i].SenLastErrTrapTS = (SK_U64)0;
1284 pAC->I2c.SenTable[i].SenLastErrLogTS = (SK_U64)0;
1285 pAC->I2c.SenTable[i].SenLastWarnTrapTS = (SK_U64)0;
1286 pAC->I2c.SenTable[i].SenLastWarnLogTS = (SK_U64)0;
1287 }
1288 break;
1289 default:
1290 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG);
1291 }
1292
1293 return(0);
1294} /* SkI2cEvent*/
1295
1296#endif /* !SK_DIAG */
diff --git a/drivers/net/sk98lin/sklm80.c b/drivers/net/sk98lin/sklm80.c
new file mode 100644
index 000000000000..68292d18175b
--- /dev/null
+++ b/drivers/net/sk98lin/sklm80.c
@@ -0,0 +1,213 @@
1/******************************************************************************
2 *
3 * Name: sklm80.c
4 * Project: Gigabit Ethernet Adapters, TWSI-Module
5 * Version: $Revision: 1.22 $
6 * Date: $Date: 2003/10/20 09:08:21 $
7 * Purpose: Functions to access Voltage and Temperature Sensor (LM80)
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 LM80 functions
27*/
28#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
29static const char SysKonnectFileId[] =
30 "@(#) $Id: sklm80.c,v 1.22 2003/10/20 09:08:21 rschmidt Exp $ (C) Marvell. ";
31#endif
32
33#include "h/skdrv1st.h" /* Driver Specific Definitions */
34#include "h/lm80.h"
35#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
36
37#ifdef SK_DIAG
38#define BREAK_OR_WAIT(pAC,IoC,Event) SkI2cWait(pAC,IoC,Event)
39#else /* nSK_DIAG */
40#define BREAK_OR_WAIT(pAC,IoC,Event) break
41#endif /* nSK_DIAG */
42
43#ifdef SK_DIAG
44/*
45 * read the register 'Reg' from the device 'Dev'
46 *
47 * return read error -1
48 * success the read value
49 */
50int SkLm80RcvReg(
51SK_IOC IoC, /* Adapter Context */
52int Dev, /* I2C device address */
53int Reg) /* register to read */
54{
55 int Val = 0;
56 int TempExt;
57
58 /* Signal device number */
59 if (SkI2cSndDev(IoC, Dev, I2C_WRITE)) {
60 return(-1);
61 }
62
63 if (SkI2cSndByte(IoC, Reg)) {
64 return(-1);
65 }
66
67 /* repeat start */
68 if (SkI2cSndDev(IoC, Dev, I2C_READ)) {
69 return(-1);
70 }
71
72 switch (Reg) {
73 case LM80_TEMP_IN:
74 Val = (int)SkI2cRcvByte(IoC, 1);
75
76 /* First: correct the value: it might be negative */
77 if ((Val & 0x80) != 0) {
78 /* Value is negative */
79 Val = Val - 256;
80 }
81 Val = Val * SK_LM80_TEMP_LSB;
82 SkI2cStop(IoC);
83
84 TempExt = (int)SkLm80RcvReg(IoC, LM80_ADDR, LM80_TEMP_CTRL);
85
86 if (Val > 0) {
87 Val += ((TempExt >> 7) * SK_LM80_TEMPEXT_LSB);
88 }
89 else {
90 Val -= ((TempExt >> 7) * SK_LM80_TEMPEXT_LSB);
91 }
92 return(Val);
93 break;
94 case LM80_VT0_IN:
95 case LM80_VT1_IN:
96 case LM80_VT2_IN:
97 case LM80_VT3_IN:
98 Val = (int)SkI2cRcvByte(IoC, 1) * SK_LM80_VT_LSB;
99 break;
100
101 default:
102 Val = (int)SkI2cRcvByte(IoC, 1);
103 break;
104 }
105
106 SkI2cStop(IoC);
107 return(Val);
108}
109#endif /* SK_DIAG */
110
111/*
112 * read a sensors value (LM80 specific)
113 *
114 * This function reads a sensors value from the I2C sensor chip LM80.
115 * The sensor is defined by its index into the sensors database in the struct
116 * pAC points to.
117 *
118 * Returns 1 if the read is completed
119 * 0 if the read must be continued (I2C Bus still allocated)
120 */
121int SkLm80ReadSensor(
122SK_AC *pAC, /* Adapter Context */
123SK_IOC IoC, /* I/O Context needed in level 1 and 2 */
124SK_SENSOR *pSen) /* Sensor to be read */
125{
126 SK_I32 Value;
127
128 switch (pSen->SenState) {
129 case SK_SEN_IDLE:
130 /* Send address to ADDR register */
131 SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, pSen->SenReg, 0);
132
133 pSen->SenState = SK_SEN_VALUE ;
134 BREAK_OR_WAIT(pAC, IoC, I2C_READ);
135
136 case SK_SEN_VALUE:
137 /* Read value from data register */
138 SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value));
139
140 Value &= 0xff; /* only least significant byte is valid */
141
142 /* Do NOT check the Value against the thresholds */
143 /* Checking is done in the calling instance */
144
145 if (pSen->SenType == SK_SEN_VOLT) {
146 /* Voltage sensor */
147 pSen->SenValue = Value * SK_LM80_VT_LSB;
148 pSen->SenState = SK_SEN_IDLE ;
149 return(1);
150 }
151
152 if (pSen->SenType == SK_SEN_FAN) {
153 if (Value != 0 && Value != 0xff) {
154 /* Fan speed counter */
155 pSen->SenValue = SK_LM80_FAN_FAKTOR/Value;
156 }
157 else {
158 /* Indicate Fan error */
159 pSen->SenValue = 0;
160 }
161 pSen->SenState = SK_SEN_IDLE ;
162 return(1);
163 }
164
165 /* First: correct the value: it might be negative */
166 if ((Value & 0x80) != 0) {
167 /* Value is negative */
168 Value = Value - 256;
169 }
170
171 /* We have a temperature sensor and need to get the signed extension.
172 * For now we get the extension from the last reading, so in the normal
173 * case we won't see flickering temperatures.
174 */
175 pSen->SenValue = (Value * SK_LM80_TEMP_LSB) +
176 (pSen->SenValue % SK_LM80_TEMP_LSB);
177
178 /* Send address to ADDR register */
179 SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, LM80_TEMP_CTRL, 0);
180
181 pSen->SenState = SK_SEN_VALEXT ;
182 BREAK_OR_WAIT(pAC, IoC, I2C_READ);
183
184 case SK_SEN_VALEXT:
185 /* Read value from data register */
186 SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value));
187 Value &= LM80_TEMP_LSB_9; /* only bit 7 is valid */
188
189 /* cut the LSB bit */
190 pSen->SenValue = ((pSen->SenValue / SK_LM80_TEMP_LSB) *
191 SK_LM80_TEMP_LSB);
192
193 if (pSen->SenValue < 0) {
194 /* Value negative: The bit value must be subtracted */
195 pSen->SenValue -= ((Value >> 7) * SK_LM80_TEMPEXT_LSB);
196 }
197 else {
198 /* Value positive: The bit value must be added */
199 pSen->SenValue += ((Value >> 7) * SK_LM80_TEMPEXT_LSB);
200 }
201
202 pSen->SenState = SK_SEN_IDLE ;
203 return(1);
204
205 default:
206 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E007, SKERR_I2C_E007MSG);
207 return(1);
208 }
209
210 /* Not completed */
211 return(0);
212}
213
diff --git a/drivers/net/sk98lin/skproc.c b/drivers/net/sk98lin/skproc.c
new file mode 100644
index 000000000000..5cece25c034e
--- /dev/null
+++ b/drivers/net/sk98lin/skproc.c
@@ -0,0 +1,265 @@
1/******************************************************************************
2 *
3 * Name: skproc.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.11 $
6 * Date: $Date: 2003/12/11 16:03:57 $
7 * Purpose: Funktions to display statictic data
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * Created 22-Nov-2000
22 * Author: Mirko Lindner (mlindner@syskonnect.de)
23 *
24 * The information in this file is provided "AS IS" without warranty.
25 *
26 ******************************************************************************/
27#include <linux/proc_fs.h>
28#include <linux/seq_file.h>
29
30#include "h/skdrv1st.h"
31#include "h/skdrv2nd.h"
32#include "h/skversion.h"
33
34static int sk_seq_show(struct seq_file *seq, void *v);
35static int sk_proc_open(struct inode *inode, struct file *file);
36
37struct file_operations sk_proc_fops = {
38 .owner = THIS_MODULE,
39 .open = sk_proc_open,
40 .read = seq_read,
41 .llseek = seq_lseek,
42 .release = single_release,
43};
44
45
46/*****************************************************************************
47 *
48 * sk_seq_show - show proc information of a particular adapter
49 *
50 * Description:
51 * This function fills the proc entry with statistic data about
52 * the ethernet device. It invokes the generic sk_gen_browse() to
53 * print out all items one per one.
54 *
55 * Returns: 0
56 *
57 */
58static int sk_seq_show(struct seq_file *seq, void *v)
59{
60 struct net_device *dev = seq->private;
61 DEV_NET *pNet = netdev_priv(dev);
62 SK_AC *pAC = pNet->pAC;
63 SK_PNMI_STRUCT_DATA *pPnmiStruct = &pAC->PnmiStruct;
64 unsigned long Flags;
65 unsigned int Size;
66 char sens_msg[50];
67 int t;
68 int i;
69
70 /* NetIndex in GetStruct is now required, zero is only dummy */
71 for (t=pAC->GIni.GIMacsFound; t > 0; t--) {
72 if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 1)
73 t--;
74
75 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
76 Size = SK_PNMI_STRUCT_SIZE;
77#ifdef SK_DIAG_SUPPORT
78 if (pAC->BoardLevel == SK_INIT_DATA) {
79 SK_MEMCPY(&(pAC->PnmiStruct), &(pAC->PnmiBackup), sizeof(SK_PNMI_STRUCT_DATA));
80 if (pAC->DiagModeActive == DIAG_NOTACTIVE) {
81 pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
82 }
83 } else {
84 SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, t-1);
85 }
86#else
87 SkPnmiGetStruct(pAC, pAC->IoBase,
88 pPnmiStruct, &Size, t-1);
89#endif
90 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
91
92 if (pAC->dev[t-1] == dev) {
93 SK_PNMI_STAT *pPnmiStat = &pPnmiStruct->Stat[0];
94
95 seq_printf(seq, "\nDetailed statistic for device %s\n",
96 pAC->dev[t-1]->name);
97 seq_printf(seq, "=======================================\n");
98
99 /* Board statistics */
100 seq_printf(seq, "\nBoard statistics\n\n");
101 seq_printf(seq, "Active Port %c\n",
102 'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
103 Net[t-1].PrefPort]->PortNumber);
104 seq_printf(seq, "Preferred Port %c\n",
105 'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
106 Net[t-1].PrefPort]->PortNumber);
107
108 seq_printf(seq, "Bus speed (MHz) %d\n",
109 pPnmiStruct->BusSpeed);
110
111 seq_printf(seq, "Bus width (Bit) %d\n",
112 pPnmiStruct->BusWidth);
113 seq_printf(seq, "Driver version %s\n",
114 VER_STRING);
115 seq_printf(seq, "Hardware revision v%d.%d\n",
116 (pAC->GIni.GIPciHwRev >> 4) & 0x0F,
117 pAC->GIni.GIPciHwRev & 0x0F);
118
119 /* Print sensor informations */
120 for (i=0; i < pAC->I2c.MaxSens; i ++) {
121 /* Check type */
122 switch (pAC->I2c.SenTable[i].SenType) {
123 case 1:
124 strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
125 strcat(sens_msg, " (C)");
126 seq_printf(seq, "%-25s %d.%02d\n",
127 sens_msg,
128 pAC->I2c.SenTable[i].SenValue / 10,
129 pAC->I2c.SenTable[i].SenValue % 10);
130
131 strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
132 strcat(sens_msg, " (F)");
133 seq_printf(seq, "%-25s %d.%02d\n",
134 sens_msg,
135 ((((pAC->I2c.SenTable[i].SenValue)
136 *10)*9)/5 + 3200)/100,
137 ((((pAC->I2c.SenTable[i].SenValue)
138 *10)*9)/5 + 3200) % 10);
139 break;
140 case 2:
141 strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
142 strcat(sens_msg, " (V)");
143 seq_printf(seq, "%-25s %d.%03d\n",
144 sens_msg,
145 pAC->I2c.SenTable[i].SenValue / 1000,
146 pAC->I2c.SenTable[i].SenValue % 1000);
147 break;
148 case 3:
149 strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
150 strcat(sens_msg, " (rpm)");
151 seq_printf(seq, "%-25s %d\n",
152 sens_msg,
153 pAC->I2c.SenTable[i].SenValue);
154 break;
155 default:
156 break;
157 }
158 }
159
160 /*Receive statistics */
161 seq_printf(seq, "\nReceive statistics\n\n");
162
163 seq_printf(seq, "Received bytes %Lu\n",
164 (unsigned long long) pPnmiStat->StatRxOctetsOkCts);
165 seq_printf(seq, "Received packets %Lu\n",
166 (unsigned long long) pPnmiStat->StatRxOkCts);
167#if 0
168 if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC &&
169 pAC->HWRevision < 12) {
170 pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
171 pPnmiStat->StatRxShortsCts;
172 pPnmiStat->StatRxShortsCts = 0;
173 }
174#endif
175 if (dev->mtu > 1500)
176 pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
177 pPnmiStat->StatRxTooLongCts;
178
179 seq_printf(seq, "Receive errors %Lu\n",
180 (unsigned long long) pPnmiStruct->InErrorsCts);
181 seq_printf(seq, "Receive dropped %Lu\n",
182 (unsigned long long) pPnmiStruct->RxNoBufCts);
183 seq_printf(seq, "Received multicast %Lu\n",
184 (unsigned long long) pPnmiStat->StatRxMulticastOkCts);
185 seq_printf(seq, "Receive error types\n");
186 seq_printf(seq, " length %Lu\n",
187 (unsigned long long) pPnmiStat->StatRxRuntCts);
188 seq_printf(seq, " buffer overflow %Lu\n",
189 (unsigned long long) pPnmiStat->StatRxFifoOverflowCts);
190 seq_printf(seq, " bad crc %Lu\n",
191 (unsigned long long) pPnmiStat->StatRxFcsCts);
192 seq_printf(seq, " framing %Lu\n",
193 (unsigned long long) pPnmiStat->StatRxFramingCts);
194 seq_printf(seq, " missed frames %Lu\n",
195 (unsigned long long) pPnmiStat->StatRxMissedCts);
196
197 if (dev->mtu > 1500)
198 pPnmiStat->StatRxTooLongCts = 0;
199
200 seq_printf(seq, " too long %Lu\n",
201 (unsigned long long) pPnmiStat->StatRxTooLongCts);
202 seq_printf(seq, " carrier extension %Lu\n",
203 (unsigned long long) pPnmiStat->StatRxCextCts);
204 seq_printf(seq, " too short %Lu\n",
205 (unsigned long long) pPnmiStat->StatRxShortsCts);
206 seq_printf(seq, " symbol %Lu\n",
207 (unsigned long long) pPnmiStat->StatRxSymbolCts);
208 seq_printf(seq, " LLC MAC size %Lu\n",
209 (unsigned long long) pPnmiStat->StatRxIRLengthCts);
210 seq_printf(seq, " carrier event %Lu\n",
211 (unsigned long long) pPnmiStat->StatRxCarrierCts);
212 seq_printf(seq, " jabber %Lu\n",
213 (unsigned long long) pPnmiStat->StatRxJabberCts);
214
215
216 /*Transmit statistics */
217 seq_printf(seq, "\nTransmit statistics\n\n");
218
219 seq_printf(seq, "Transmited bytes %Lu\n",
220 (unsigned long long) pPnmiStat->StatTxOctetsOkCts);
221 seq_printf(seq, "Transmited packets %Lu\n",
222 (unsigned long long) pPnmiStat->StatTxOkCts);
223 seq_printf(seq, "Transmit errors %Lu\n",
224 (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
225 seq_printf(seq, "Transmit dropped %Lu\n",
226 (unsigned long long) pPnmiStruct->TxNoBufCts);
227 seq_printf(seq, "Transmit collisions %Lu\n",
228 (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
229 seq_printf(seq, "Transmit error types\n");
230 seq_printf(seq, " excessive collision %ld\n",
231 pAC->stats.tx_aborted_errors);
232 seq_printf(seq, " carrier %Lu\n",
233 (unsigned long long) pPnmiStat->StatTxCarrierCts);
234 seq_printf(seq, " fifo underrun %Lu\n",
235 (unsigned long long) pPnmiStat->StatTxFifoUnderrunCts);
236 seq_printf(seq, " heartbeat %Lu\n",
237 (unsigned long long) pPnmiStat->StatTxCarrierCts);
238 seq_printf(seq, " window %ld\n",
239 pAC->stats.tx_window_errors);
240
241 }
242 }
243 return 0;
244}
245
246/*****************************************************************************
247 *
248 * sk_proc_open - register the show function when proc is open'ed
249 *
250 * Description:
251 * This function is called whenever a sk98lin proc file is queried.
252 *
253 * Returns: the return value of single_open()
254 *
255 */
256static int sk_proc_open(struct inode *inode, struct file *file)
257{
258 return single_open(file, sk_seq_show, PDE(inode)->data);
259}
260
261/*******************************************************************************
262 *
263 * End of file
264 *
265 ******************************************************************************/
diff --git a/drivers/net/sk98lin/skqueue.c b/drivers/net/sk98lin/skqueue.c
new file mode 100644
index 000000000000..0275b4f71d9b
--- /dev/null
+++ b/drivers/net/sk98lin/skqueue.c
@@ -0,0 +1,179 @@
1/******************************************************************************
2 *
3 * Name: skqueue.c
4 * Project: Gigabit Ethernet Adapters, Event Scheduler Module
5 * Version: $Revision: 1.20 $
6 * Date: $Date: 2003/09/16 13:44:00 $
7 * Purpose: Management of an event queue.
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25
26/*
27 * Event queue and dispatcher
28 */
29#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
30static const char SysKonnectFileId[] =
31 "@(#) $Id: skqueue.c,v 1.20 2003/09/16 13:44:00 rschmidt Exp $ (C) Marvell.";
32#endif
33
34#include "h/skdrv1st.h" /* Driver Specific Definitions */
35#include "h/skqueue.h" /* Queue Definitions */
36#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
37
38#ifdef __C2MAN__
39/*
40 Event queue management.
41
42 General Description:
43
44 */
45intro()
46{}
47#endif
48
49#define PRINTF(a,b,c)
50
51/*
52 * init event queue management
53 *
54 * Must be called during init level 0.
55 */
56void SkEventInit(
57SK_AC *pAC, /* Adapter context */
58SK_IOC Ioc, /* IO context */
59int Level) /* Init level */
60{
61 switch (Level) {
62 case SK_INIT_DATA:
63 pAC->Event.EvPut = pAC->Event.EvGet = pAC->Event.EvQueue;
64 break;
65 default:
66 break;
67 }
68}
69
70/*
71 * add event to queue
72 */
73void SkEventQueue(
74SK_AC *pAC, /* Adapters context */
75SK_U32 Class, /* Event Class */
76SK_U32 Event, /* Event to be queued */
77SK_EVPARA Para) /* Event parameter */
78{
79 pAC->Event.EvPut->Class = Class;
80 pAC->Event.EvPut->Event = Event;
81 pAC->Event.EvPut->Para = Para;
82
83 if (++pAC->Event.EvPut == &pAC->Event.EvQueue[SK_MAX_EVENT])
84 pAC->Event.EvPut = pAC->Event.EvQueue;
85
86 if (pAC->Event.EvPut == pAC->Event.EvGet) {
87 SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG);
88 }
89}
90
91/*
92 * event dispatcher
93 * while event queue is not empty
94 * get event from queue
95 * send command to state machine
96 * end
97 * return error reported by individual Event function
98 * 0 if no error occured.
99 */
100int SkEventDispatcher(
101SK_AC *pAC, /* Adapters Context */
102SK_IOC Ioc) /* Io context */
103{
104 SK_EVENTELEM *pEv; /* pointer into queue */
105 SK_U32 Class;
106 int Rtv;
107
108 pEv = pAC->Event.EvGet;
109
110 PRINTF("dispatch get %x put %x\n", pEv, pAC->Event.ev_put);
111
112 while (pEv != pAC->Event.EvPut) {
113 PRINTF("dispatch Class %d Event %d\n", pEv->Class, pEv->Event);
114
115 switch (Class = pEv->Class) {
116#ifndef SK_USE_LAC_EV
117#ifndef SK_SLIM
118 case SKGE_RLMT: /* RLMT Event */
119 Rtv = SkRlmtEvent(pAC, Ioc, pEv->Event, pEv->Para);
120 break;
121 case SKGE_I2C: /* I2C Event */
122 Rtv = SkI2cEvent(pAC, Ioc, pEv->Event, pEv->Para);
123 break;
124 case SKGE_PNMI: /* PNMI Event */
125 Rtv = SkPnmiEvent(pAC, Ioc, pEv->Event, pEv->Para);
126 break;
127#endif /* not SK_SLIM */
128#endif /* not SK_USE_LAC_EV */
129 case SKGE_DRV: /* Driver Event */
130 Rtv = SkDrvEvent(pAC, Ioc, pEv->Event, pEv->Para);
131 break;
132#ifndef SK_USE_SW_TIMER
133 case SKGE_HWAC:
134 Rtv = SkGeSirqEvent(pAC, Ioc, pEv->Event, pEv->Para);
135 break;
136#else /* !SK_USE_SW_TIMER */
137 case SKGE_SWT :
138 Rtv = SkSwtEvent(pAC, Ioc, pEv->Event, pEv->Para);
139 break;
140#endif /* !SK_USE_SW_TIMER */
141#ifdef SK_USE_LAC_EV
142 case SKGE_LACP :
143 Rtv = SkLacpEvent(pAC, Ioc, pEv->Event, pEv->Para);
144 break;
145 case SKGE_RSF :
146 Rtv = SkRsfEvent(pAC, Ioc, pEv->Event, pEv->Para);
147 break;
148 case SKGE_MARKER :
149 Rtv = SkMarkerEvent(pAC, Ioc, pEv->Event, pEv->Para);
150 break;
151 case SKGE_FD :
152 Rtv = SkFdEvent(pAC, Ioc, pEv->Event, pEv->Para);
153 break;
154#endif /* SK_USE_LAC_EV */
155#ifdef SK_USE_CSUM
156 case SKGE_CSUM :
157 Rtv = SkCsEvent(pAC, Ioc, pEv->Event, pEv->Para);
158 break;
159#endif /* SK_USE_CSUM */
160 default :
161 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_Q_E002, SKERR_Q_E002MSG);
162 Rtv = 0;
163 }
164
165 if (Rtv != 0) {
166 return(Rtv);
167 }
168
169 if (++pEv == &pAC->Event.EvQueue[SK_MAX_EVENT])
170 pEv = pAC->Event.EvQueue;
171
172 /* Renew get: it is used in queue_events to detect overruns */
173 pAC->Event.EvGet = pEv;
174 }
175
176 return(0);
177}
178
179/* End of file */
diff --git a/drivers/net/sk98lin/skrlmt.c b/drivers/net/sk98lin/skrlmt.c
new file mode 100644
index 000000000000..9ea11ab2296a
--- /dev/null
+++ b/drivers/net/sk98lin/skrlmt.c
@@ -0,0 +1,3258 @@
1/******************************************************************************
2 *
3 * Name: skrlmt.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.69 $
6 * Date: $Date: 2003/04/15 09:39:22 $
7 * Purpose: Manage links on SK-NET Adapters, esp. redundant ones.
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * This module contains code for Link ManagemenT (LMT) of SK-NET Adapters.
30 * It is mainly intended for adapters with more than one link.
31 * For such adapters, this module realizes Redundant Link ManagemenT (RLMT).
32 *
33 * Include File Hierarchy:
34 *
35 * "skdrv1st.h"
36 * "skdrv2nd.h"
37 *
38 ******************************************************************************/
39
40#ifndef lint
41static const char SysKonnectFileId[] =
42 "@(#) $Id: skrlmt.c,v 1.69 2003/04/15 09:39:22 tschilli Exp $ (C) Marvell.";
43#endif /* !defined(lint) */
44
45#define __SKRLMT_C
46
47#ifdef __cplusplus
48extern "C" {
49#endif /* cplusplus */
50
51#include "h/skdrv1st.h"
52#include "h/skdrv2nd.h"
53
54/* defines ********************************************************************/
55
56#ifndef SK_HWAC_LINK_LED
57#define SK_HWAC_LINK_LED(a,b,c,d)
58#endif /* !defined(SK_HWAC_LINK_LED) */
59
60#ifndef DEBUG
61#define RLMT_STATIC static
62#else /* DEBUG */
63#define RLMT_STATIC
64
65#ifndef SK_LITTLE_ENDIAN
66/* First 32 bits */
67#define OFFS_LO32 1
68
69/* Second 32 bits */
70#define OFFS_HI32 0
71#else /* SK_LITTLE_ENDIAN */
72/* First 32 bits */
73#define OFFS_LO32 0
74
75/* Second 32 bits */
76#define OFFS_HI32 1
77#endif /* SK_LITTLE_ENDIAN */
78
79#endif /* DEBUG */
80
81/* ----- Private timeout values ----- */
82
83#define SK_RLMT_MIN_TO_VAL 125000 /* 1/8 sec. */
84#define SK_RLMT_DEF_TO_VAL 1000000 /* 1 sec. */
85#define SK_RLMT_PORTDOWN_TIM_VAL 900000 /* another 0.9 sec. */
86#define SK_RLMT_PORTSTART_TIM_VAL 100000 /* 0.1 sec. */
87#define SK_RLMT_PORTUP_TIM_VAL 2500000 /* 2.5 sec. */
88#define SK_RLMT_SEG_TO_VAL 900000000 /* 15 min. */
89
90/* Assume tick counter increment is 1 - may be set OS-dependent. */
91#ifndef SK_TICK_INCR
92#define SK_TICK_INCR SK_CONSTU64(1)
93#endif /* !defined(SK_TICK_INCR) */
94
95/*
96 * Amount that a time stamp must be later to be recognized as "substantially
97 * later". This is about 1/128 sec, but above 1 tick counter increment.
98 */
99#define SK_RLMT_BC_DELTA (1 + ((SK_TICKS_PER_SEC >> 7) > SK_TICK_INCR ? \
100 (SK_TICKS_PER_SEC >> 7) : SK_TICK_INCR))
101
102/* ----- Private RLMT defaults ----- */
103
104#define SK_RLMT_DEF_PREF_PORT 0 /* "Lower" port. */
105#define SK_RLMT_DEF_MODE SK_RLMT_CHECK_LINK /* Default RLMT Mode. */
106
107/* ----- Private RLMT checking states ----- */
108
109#define SK_RLMT_RCS_SEG 1 /* RLMT Check State: check seg. */
110#define SK_RLMT_RCS_START_SEG 2 /* RLMT Check State: start check seg. */
111#define SK_RLMT_RCS_SEND_SEG 4 /* RLMT Check State: send BPDU packet */
112#define SK_RLMT_RCS_REPORT_SEG 8 /* RLMT Check State: report seg. */
113
114/* ----- Private PORT checking states ----- */
115
116#define SK_RLMT_PCS_TX 1 /* Port Check State: check tx. */
117#define SK_RLMT_PCS_RX 2 /* Port Check State: check rx. */
118
119/* ----- Private PORT events ----- */
120
121/* Note: Update simulation when changing these. */
122#define SK_RLMT_PORTSTART_TIM 1100 /* Port start timeout. */
123#define SK_RLMT_PORTUP_TIM 1101 /* Port can now go up. */
124#define SK_RLMT_PORTDOWN_RX_TIM 1102 /* Port did not receive once ... */
125#define SK_RLMT_PORTDOWN 1103 /* Port went down. */
126#define SK_RLMT_PORTDOWN_TX_TIM 1104 /* Partner did not receive ... */
127
128/* ----- Private RLMT events ----- */
129
130/* Note: Update simulation when changing these. */
131#define SK_RLMT_TIM 2100 /* RLMT timeout. */
132#define SK_RLMT_SEG_TIM 2101 /* RLMT segmentation check timeout. */
133
134#define TO_SHORTEN(tim) ((tim) / 2)
135
136/* Error numbers and messages. */
137#define SKERR_RLMT_E001 (SK_ERRBASE_RLMT + 0)
138#define SKERR_RLMT_E001_MSG "No Packet."
139#define SKERR_RLMT_E002 (SKERR_RLMT_E001 + 1)
140#define SKERR_RLMT_E002_MSG "Short Packet."
141#define SKERR_RLMT_E003 (SKERR_RLMT_E002 + 1)
142#define SKERR_RLMT_E003_MSG "Unknown RLMT event."
143#define SKERR_RLMT_E004 (SKERR_RLMT_E003 + 1)
144#define SKERR_RLMT_E004_MSG "PortsUp incorrect."
145#define SKERR_RLMT_E005 (SKERR_RLMT_E004 + 1)
146#define SKERR_RLMT_E005_MSG \
147 "Net seems to be segmented (different root bridges are reported on the ports)."
148#define SKERR_RLMT_E006 (SKERR_RLMT_E005 + 1)
149#define SKERR_RLMT_E006_MSG "Duplicate MAC Address detected."
150#define SKERR_RLMT_E007 (SKERR_RLMT_E006 + 1)
151#define SKERR_RLMT_E007_MSG "LinksUp incorrect."
152#define SKERR_RLMT_E008 (SKERR_RLMT_E007 + 1)
153#define SKERR_RLMT_E008_MSG "Port not started but link came up."
154#define SKERR_RLMT_E009 (SKERR_RLMT_E008 + 1)
155#define SKERR_RLMT_E009_MSG "Corrected illegal setting of Preferred Port."
156#define SKERR_RLMT_E010 (SKERR_RLMT_E009 + 1)
157#define SKERR_RLMT_E010_MSG "Ignored illegal Preferred Port."
158
159/* LLC field values. */
160#define LLC_COMMAND_RESPONSE_BIT 1
161#define LLC_TEST_COMMAND 0xE3
162#define LLC_UI 0x03
163
164/* RLMT Packet fields. */
165#define SK_RLMT_DSAP 0
166#define SK_RLMT_SSAP 0
167#define SK_RLMT_CTRL (LLC_TEST_COMMAND)
168#define SK_RLMT_INDICATOR0 0x53 /* S */
169#define SK_RLMT_INDICATOR1 0x4B /* K */
170#define SK_RLMT_INDICATOR2 0x2D /* - */
171#define SK_RLMT_INDICATOR3 0x52 /* R */
172#define SK_RLMT_INDICATOR4 0x4C /* L */
173#define SK_RLMT_INDICATOR5 0x4D /* M */
174#define SK_RLMT_INDICATOR6 0x54 /* T */
175#define SK_RLMT_PACKET_VERSION 0
176
177/* RLMT SPT Flag values. */
178#define SK_RLMT_SPT_FLAG_CHANGE 0x01
179#define SK_RLMT_SPT_FLAG_CHANGE_ACK 0x80
180
181/* RLMT SPT Packet fields. */
182#define SK_RLMT_SPT_DSAP 0x42
183#define SK_RLMT_SPT_SSAP 0x42
184#define SK_RLMT_SPT_CTRL (LLC_UI)
185#define SK_RLMT_SPT_PROTOCOL_ID0 0x00
186#define SK_RLMT_SPT_PROTOCOL_ID1 0x00
187#define SK_RLMT_SPT_PROTOCOL_VERSION_ID 0x00
188#define SK_RLMT_SPT_BPDU_TYPE 0x00
189#define SK_RLMT_SPT_FLAGS 0x00 /* ?? */
190#define SK_RLMT_SPT_ROOT_ID0 0xFF /* Lowest possible priority. */
191#define SK_RLMT_SPT_ROOT_ID1 0xFF /* Lowest possible priority. */
192
193/* Remaining 6 bytes will be the current port address. */
194#define SK_RLMT_SPT_ROOT_PATH_COST0 0x00
195#define SK_RLMT_SPT_ROOT_PATH_COST1 0x00
196#define SK_RLMT_SPT_ROOT_PATH_COST2 0x00
197#define SK_RLMT_SPT_ROOT_PATH_COST3 0x00
198#define SK_RLMT_SPT_BRIDGE_ID0 0xFF /* Lowest possible priority. */
199#define SK_RLMT_SPT_BRIDGE_ID1 0xFF /* Lowest possible priority. */
200
201/* Remaining 6 bytes will be the current port address. */
202#define SK_RLMT_SPT_PORT_ID0 0xFF /* Lowest possible priority. */
203#define SK_RLMT_SPT_PORT_ID1 0xFF /* Lowest possible priority. */
204#define SK_RLMT_SPT_MSG_AGE0 0x00
205#define SK_RLMT_SPT_MSG_AGE1 0x00
206#define SK_RLMT_SPT_MAX_AGE0 0x00
207#define SK_RLMT_SPT_MAX_AGE1 0xFF
208#define SK_RLMT_SPT_HELLO_TIME0 0x00
209#define SK_RLMT_SPT_HELLO_TIME1 0xFF
210#define SK_RLMT_SPT_FWD_DELAY0 0x00
211#define SK_RLMT_SPT_FWD_DELAY1 0x40
212
213/* Size defines. */
214#define SK_RLMT_MIN_PACKET_SIZE 34
215#define SK_RLMT_MAX_PACKET_SIZE (SK_RLMT_MAX_TX_BUF_SIZE)
216#define SK_PACKET_DATA_LEN (SK_RLMT_MAX_PACKET_SIZE - \
217 SK_RLMT_MIN_PACKET_SIZE)
218
219/* ----- RLMT packet types ----- */
220#define SK_PACKET_ANNOUNCE 1 /* Port announcement. */
221#define SK_PACKET_ALIVE 2 /* Alive packet to port. */
222#define SK_PACKET_ADDR_CHANGED 3 /* Port address changed. */
223#define SK_PACKET_CHECK_TX 4 /* Check your tx line. */
224
225#ifdef SK_LITTLE_ENDIAN
226#define SK_U16_TO_NETWORK_ORDER(Val,Addr) { \
227 SK_U8 *_Addr = (SK_U8*)(Addr); \
228 SK_U16 _Val = (SK_U16)(Val); \
229 *_Addr++ = (SK_U8)(_Val >> 8); \
230 *_Addr = (SK_U8)(_Val & 0xFF); \
231}
232#endif /* SK_LITTLE_ENDIAN */
233
234#ifdef SK_BIG_ENDIAN
235#define SK_U16_TO_NETWORK_ORDER(Val,Addr) (*(SK_U16*)(Addr) = (SK_U16)(Val))
236#endif /* SK_BIG_ENDIAN */
237
238#define AUTONEG_FAILED SK_FALSE
239#define AUTONEG_SUCCESS SK_TRUE
240
241
242/* typedefs *******************************************************************/
243
244/* RLMT packet. Length: SK_RLMT_MAX_PACKET_SIZE (60) bytes. */
245typedef struct s_RlmtPacket {
246 SK_U8 DstAddr[SK_MAC_ADDR_LEN];
247 SK_U8 SrcAddr[SK_MAC_ADDR_LEN];
248 SK_U8 TypeLen[2];
249 SK_U8 DSap;
250 SK_U8 SSap;
251 SK_U8 Ctrl;
252 SK_U8 Indicator[7];
253 SK_U8 RlmtPacketType[2];
254 SK_U8 Align1[2];
255 SK_U8 Random[4]; /* Random value of requesting(!) station. */
256 SK_U8 RlmtPacketVersion[2]; /* RLMT Packet version. */
257 SK_U8 Data[SK_PACKET_DATA_LEN];
258} SK_RLMT_PACKET;
259
260typedef struct s_SpTreeRlmtPacket {
261 SK_U8 DstAddr[SK_MAC_ADDR_LEN];
262 SK_U8 SrcAddr[SK_MAC_ADDR_LEN];
263 SK_U8 TypeLen[2];
264 SK_U8 DSap;
265 SK_U8 SSap;
266 SK_U8 Ctrl;
267 SK_U8 ProtocolId[2];
268 SK_U8 ProtocolVersionId;
269 SK_U8 BpduType;
270 SK_U8 Flags;
271 SK_U8 RootId[8];
272 SK_U8 RootPathCost[4];
273 SK_U8 BridgeId[8];
274 SK_U8 PortId[2];
275 SK_U8 MessageAge[2];
276 SK_U8 MaxAge[2];
277 SK_U8 HelloTime[2];
278 SK_U8 ForwardDelay[2];
279} SK_SPTREE_PACKET;
280
281/* global variables ***********************************************************/
282
283SK_MAC_ADDR SkRlmtMcAddr = {{0x01, 0x00, 0x5A, 0x52, 0x4C, 0x4D}};
284SK_MAC_ADDR BridgeMcAddr = {{0x01, 0x80, 0xC2, 0x00, 0x00, 0x00}};
285SK_MAC_ADDR BcAddr = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
286
287/* local variables ************************************************************/
288
289/* None. */
290
291/* functions ******************************************************************/
292
293RLMT_STATIC void SkRlmtCheckSwitch(
294 SK_AC *pAC,
295 SK_IOC IoC,
296 SK_U32 NetIdx);
297RLMT_STATIC void SkRlmtCheckSeg(
298 SK_AC *pAC,
299 SK_IOC IoC,
300 SK_U32 NetIdx);
301RLMT_STATIC void SkRlmtEvtSetNets(
302 SK_AC *pAC,
303 SK_IOC IoC,
304 SK_EVPARA Para);
305
306/******************************************************************************
307 *
308 * SkRlmtInit - initialize data, set state to init
309 *
310 * Description:
311 *
312 * SK_INIT_DATA
313 * ============
314 *
315 * This routine initializes all RLMT-related variables to a known state.
316 * The initial state is SK_RLMT_RS_INIT.
317 * All ports are initialized to SK_RLMT_PS_INIT.
318 *
319 *
320 * SK_INIT_IO
321 * ==========
322 *
323 * Nothing.
324 *
325 *
326 * SK_INIT_RUN
327 * ===========
328 *
329 * Determine the adapter's random value.
330 * Set the hw registers, the "logical MAC address", the
331 * RLMT multicast address, and eventually the BPDU multicast address.
332 *
333 * Context:
334 * init, pageable
335 *
336 * Returns:
337 * Nothing.
338 */
339void SkRlmtInit(
340SK_AC *pAC, /* Adapter Context */
341SK_IOC IoC, /* I/O Context */
342int Level) /* Initialization Level */
343{
344 SK_U32 i, j;
345 SK_U64 Random;
346 SK_EVPARA Para;
347 SK_MAC_ADDR VirtualMacAddress;
348 SK_MAC_ADDR PhysicalAMacAddress;
349 SK_BOOL VirtualMacAddressSet;
350 SK_BOOL PhysicalAMacAddressSet;
351
352 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT,
353 ("RLMT Init level %d.\n", Level))
354
355 switch (Level) {
356 case SK_INIT_DATA: /* Initialize data structures. */
357 SK_MEMSET((char *)&pAC->Rlmt, 0, sizeof(SK_RLMT));
358
359 for (i = 0; i < SK_MAX_MACS; i++) {
360 pAC->Rlmt.Port[i].PortState = SK_RLMT_PS_INIT;
361 pAC->Rlmt.Port[i].LinkDown = SK_TRUE;
362 pAC->Rlmt.Port[i].PortDown = SK_TRUE;
363 pAC->Rlmt.Port[i].PortStarted = SK_FALSE;
364 pAC->Rlmt.Port[i].PortNoRx = SK_FALSE;
365 pAC->Rlmt.Port[i].RootIdSet = SK_FALSE;
366 pAC->Rlmt.Port[i].PortNumber = i;
367 pAC->Rlmt.Port[i].Net = &pAC->Rlmt.Net[0];
368 pAC->Rlmt.Port[i].AddrPort = &pAC->Addr.Port[i];
369 }
370
371 pAC->Rlmt.NumNets = 1;
372 for (i = 0; i < SK_MAX_NETS; i++) {
373 pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
374 pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
375 pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
376 pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF; /* Automatic. */
377 /* Just assuming. */
378 pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
379 pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
380 pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
381 pAC->Rlmt.Net[i].NetNumber = i;
382 }
383
384 pAC->Rlmt.Net[0].Port[0] = &pAC->Rlmt.Port[0];
385 pAC->Rlmt.Net[0].Port[1] = &pAC->Rlmt.Port[1];
386#if SK_MAX_NETS > 1
387 pAC->Rlmt.Net[1].Port[0] = &pAC->Rlmt.Port[1];
388#endif /* SK_MAX_NETS > 1 */
389 break;
390
391 case SK_INIT_IO: /* GIMacsFound first available here. */
392 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT,
393 ("RLMT: %d MACs were detected.\n", pAC->GIni.GIMacsFound))
394
395 pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound;
396
397 /* Initialize HW registers? */
398 if (pAC->GIni.GIMacsFound == 1) {
399 Para.Para32[0] = SK_RLMT_MODE_CLS;
400 Para.Para32[1] = 0;
401 (void)SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE, Para);
402 }
403 break;
404
405 case SK_INIT_RUN:
406 /* Ensure RLMT is set to one net. */
407 if (pAC->Rlmt.NumNets > 1) {
408 Para.Para32[0] = 1;
409 Para.Para32[1] = -1;
410 SkRlmtEvtSetNets(pAC, IoC, Para);
411 }
412
413 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
414 Random = SkOsGetTime(pAC);
415 *(SK_U32*)&pAC->Rlmt.Port[i].Random = *(SK_U32*)&Random;
416
417 for (j = 0; j < 4; j++) {
418 pAC->Rlmt.Port[i].Random[j] ^= pAC->Rlmt.Port[i].AddrPort->
419 CurrentMacAddress.a[SK_MAC_ADDR_LEN - 1 - j];
420 }
421
422 (void)SkAddrMcClear(pAC, IoC, i, SK_ADDR_PERMANENT | SK_MC_SW_ONLY);
423
424 /* Add RLMT MC address. */
425 (void)SkAddrMcAdd(pAC, IoC, i, &SkRlmtMcAddr, SK_ADDR_PERMANENT);
426
427 if (pAC->Rlmt.Net[0].RlmtMode & SK_RLMT_CHECK_SEG) {
428 /* Add BPDU MC address. */
429 (void)SkAddrMcAdd(pAC, IoC, i, &BridgeMcAddr, SK_ADDR_PERMANENT);
430 }
431
432 (void)SkAddrMcUpdate(pAC, IoC, i);
433 }
434
435 VirtualMacAddressSet = SK_FALSE;
436 /* Read virtual MAC address from Control Register File. */
437 for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
438
439 SK_IN8(IoC, B2_MAC_1 + j, &VirtualMacAddress.a[j]);
440 VirtualMacAddressSet |= VirtualMacAddress.a[j];
441 }
442
443 PhysicalAMacAddressSet = SK_FALSE;
444 /* Read physical MAC address for MAC A from Control Register File. */
445 for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
446
447 SK_IN8(IoC, B2_MAC_2 + j, &PhysicalAMacAddress.a[j]);
448 PhysicalAMacAddressSet |= PhysicalAMacAddress.a[j];
449 }
450
451 /* check if the two mac addresses contain reasonable values */
452 if (!VirtualMacAddressSet || !PhysicalAMacAddressSet) {
453
454 pAC->Rlmt.RlmtOff = SK_TRUE;
455 }
456
457 /* if the two mac addresses are equal switch off the RLMT_PRE_LOOKAHEAD
458 and the RLMT_LOOKAHEAD macros */
459 else if (SK_ADDR_EQUAL(PhysicalAMacAddress.a, VirtualMacAddress.a)) {
460
461 pAC->Rlmt.RlmtOff = SK_TRUE;
462 }
463 else {
464 pAC->Rlmt.RlmtOff = SK_FALSE;
465 }
466 break;
467
468 default: /* error */
469 break;
470 }
471 return;
472} /* SkRlmtInit */
473
474
475/******************************************************************************
476 *
477 * SkRlmtBuildCheckChain - build the check chain
478 *
479 * Description:
480 * This routine builds the local check chain:
481 * - Each port that is up checks the next port.
482 * - The last port that is up checks the first port that is up.
483 *
484 * Notes:
485 * - Currently only local ports are considered when building the chain.
486 * - Currently the SuspectState is just reset;
487 * it would be better to save it ...
488 *
489 * Context:
490 * runtime, pageable?
491 *
492 * Returns:
493 * Nothing
494 */
495RLMT_STATIC void SkRlmtBuildCheckChain(
496SK_AC *pAC, /* Adapter Context */
497SK_U32 NetIdx) /* Net Number */
498{
499 SK_U32 i;
500 SK_U32 NumMacsUp;
501 SK_RLMT_PORT * FirstMacUp;
502 SK_RLMT_PORT * PrevMacUp;
503
504 FirstMacUp = NULL;
505 PrevMacUp = NULL;
506
507 if (!(pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) {
508 for (i = 0; i < pAC->Rlmt.Net[i].NumPorts; i++) {
509 pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0;
510 }
511 return; /* Done. */
512 }
513
514 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
515 ("SkRlmtBuildCheckChain.\n"))
516
517 NumMacsUp = 0;
518
519 for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
520 pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0;
521 pAC->Rlmt.Net[NetIdx].Port[i]->PortsSuspect = 0;
522 pAC->Rlmt.Net[NetIdx].Port[i]->CheckingState &=
523 ~(SK_RLMT_PCS_RX | SK_RLMT_PCS_TX);
524
525 /*
526 * If more than two links are detected we should consider
527 * checking at least two other ports:
528 * 1. the next port that is not LinkDown and
529 * 2. the next port that is not PortDown.
530 */
531 if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) {
532 if (NumMacsUp == 0) {
533 FirstMacUp = pAC->Rlmt.Net[NetIdx].Port[i];
534 }
535 else {
536 PrevMacUp->PortCheck[
537 pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked].CheckAddr =
538 pAC->Rlmt.Net[NetIdx].Port[i]->AddrPort->CurrentMacAddress;
539 PrevMacUp->PortCheck[
540 PrevMacUp->PortsChecked].SuspectTx = SK_FALSE;
541 PrevMacUp->PortsChecked++;
542 }
543 PrevMacUp = pAC->Rlmt.Net[NetIdx].Port[i];
544 NumMacsUp++;
545 }
546 }
547
548 if (NumMacsUp > 1) {
549 PrevMacUp->PortCheck[PrevMacUp->PortsChecked].CheckAddr =
550 FirstMacUp->AddrPort->CurrentMacAddress;
551 PrevMacUp->PortCheck[PrevMacUp->PortsChecked].SuspectTx =
552 SK_FALSE;
553 PrevMacUp->PortsChecked++;
554 }
555
556#ifdef DEBUG
557 for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
558 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
559 ("Port %d checks %d other ports: %2X.\n", i,
560 pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked,
561 pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[0].CheckAddr.a[5]))
562 }
563#endif /* DEBUG */
564
565 return;
566} /* SkRlmtBuildCheckChain */
567
568
569/******************************************************************************
570 *
571 * SkRlmtBuildPacket - build an RLMT packet
572 *
573 * Description:
574 * This routine sets up an RLMT packet.
575 *
576 * Context:
577 * runtime, pageable?
578 *
579 * Returns:
580 * NULL or pointer to RLMT mbuf
581 */
582RLMT_STATIC SK_MBUF *SkRlmtBuildPacket(
583SK_AC *pAC, /* Adapter Context */
584SK_IOC IoC, /* I/O Context */
585SK_U32 PortNumber, /* Sending port */
586SK_U16 PacketType, /* RLMT packet type */
587SK_MAC_ADDR *SrcAddr, /* Source address */
588SK_MAC_ADDR *DestAddr) /* Destination address */
589{
590 int i;
591 SK_U16 Length;
592 SK_MBUF *pMb;
593 SK_RLMT_PACKET *pPacket;
594
595#ifdef DEBUG
596 SK_U8 CheckSrc = 0;
597 SK_U8 CheckDest = 0;
598
599 for (i = 0; i < SK_MAC_ADDR_LEN; ++i) {
600 CheckSrc |= SrcAddr->a[i];
601 CheckDest |= DestAddr->a[i];
602 }
603
604 if ((CheckSrc == 0) || (CheckDest == 0)) {
605 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_ERR,
606 ("SkRlmtBuildPacket: Invalid %s%saddr.\n",
607 (CheckSrc == 0 ? "Src" : ""), (CheckDest == 0 ? "Dest" : "")))
608 }
609#endif
610
611 if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) != NULL) {
612 pPacket = (SK_RLMT_PACKET*)pMb->pData;
613 for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
614 pPacket->DstAddr[i] = DestAddr->a[i];
615 pPacket->SrcAddr[i] = SrcAddr->a[i];
616 }
617 pPacket->DSap = SK_RLMT_DSAP;
618 pPacket->SSap = SK_RLMT_SSAP;
619 pPacket->Ctrl = SK_RLMT_CTRL;
620 pPacket->Indicator[0] = SK_RLMT_INDICATOR0;
621 pPacket->Indicator[1] = SK_RLMT_INDICATOR1;
622 pPacket->Indicator[2] = SK_RLMT_INDICATOR2;
623 pPacket->Indicator[3] = SK_RLMT_INDICATOR3;
624 pPacket->Indicator[4] = SK_RLMT_INDICATOR4;
625 pPacket->Indicator[5] = SK_RLMT_INDICATOR5;
626 pPacket->Indicator[6] = SK_RLMT_INDICATOR6;
627
628 SK_U16_TO_NETWORK_ORDER(PacketType, &pPacket->RlmtPacketType[0]);
629
630 for (i = 0; i < 4; i++) {
631 pPacket->Random[i] = pAC->Rlmt.Port[PortNumber].Random[i];
632 }
633
634 SK_U16_TO_NETWORK_ORDER(
635 SK_RLMT_PACKET_VERSION, &pPacket->RlmtPacketVersion[0]);
636
637 for (i = 0; i < SK_PACKET_DATA_LEN; i++) {
638 pPacket->Data[i] = 0x00;
639 }
640
641 Length = SK_RLMT_MAX_PACKET_SIZE; /* Or smaller. */
642 pMb->Length = Length;
643 pMb->PortIdx = PortNumber;
644 Length -= 14;
645 SK_U16_TO_NETWORK_ORDER(Length, &pPacket->TypeLen[0]);
646
647 if (PacketType == SK_PACKET_ALIVE) {
648 pAC->Rlmt.Port[PortNumber].TxHelloCts++;
649 }
650 }
651
652 return (pMb);
653} /* SkRlmtBuildPacket */
654
655
656/******************************************************************************
657 *
658 * SkRlmtBuildSpanningTreePacket - build spanning tree check packet
659 *
660 * Description:
661 * This routine sets up a BPDU packet for spanning tree check.
662 *
663 * Context:
664 * runtime, pageable?
665 *
666 * Returns:
667 * NULL or pointer to RLMT mbuf
668 */
669RLMT_STATIC SK_MBUF *SkRlmtBuildSpanningTreePacket(
670SK_AC *pAC, /* Adapter Context */
671SK_IOC IoC, /* I/O Context */
672SK_U32 PortNumber) /* Sending port */
673{
674 unsigned i;
675 SK_U16 Length;
676 SK_MBUF *pMb;
677 SK_SPTREE_PACKET *pSPacket;
678
679 if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) !=
680 NULL) {
681 pSPacket = (SK_SPTREE_PACKET*)pMb->pData;
682 for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
683 pSPacket->DstAddr[i] = BridgeMcAddr.a[i];
684 pSPacket->SrcAddr[i] =
685 pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i];
686 }
687 pSPacket->DSap = SK_RLMT_SPT_DSAP;
688 pSPacket->SSap = SK_RLMT_SPT_SSAP;
689 pSPacket->Ctrl = SK_RLMT_SPT_CTRL;
690
691 pSPacket->ProtocolId[0] = SK_RLMT_SPT_PROTOCOL_ID0;
692 pSPacket->ProtocolId[1] = SK_RLMT_SPT_PROTOCOL_ID1;
693 pSPacket->ProtocolVersionId = SK_RLMT_SPT_PROTOCOL_VERSION_ID;
694 pSPacket->BpduType = SK_RLMT_SPT_BPDU_TYPE;
695 pSPacket->Flags = SK_RLMT_SPT_FLAGS;
696 pSPacket->RootId[0] = SK_RLMT_SPT_ROOT_ID0;
697 pSPacket->RootId[1] = SK_RLMT_SPT_ROOT_ID1;
698 pSPacket->RootPathCost[0] = SK_RLMT_SPT_ROOT_PATH_COST0;
699 pSPacket->RootPathCost[1] = SK_RLMT_SPT_ROOT_PATH_COST1;
700 pSPacket->RootPathCost[2] = SK_RLMT_SPT_ROOT_PATH_COST2;
701 pSPacket->RootPathCost[3] = SK_RLMT_SPT_ROOT_PATH_COST3;
702 pSPacket->BridgeId[0] = SK_RLMT_SPT_BRIDGE_ID0;
703 pSPacket->BridgeId[1] = SK_RLMT_SPT_BRIDGE_ID1;
704
705 /*
706 * Use logical MAC address as bridge ID and filter these packets
707 * on receive.
708 */
709 for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
710 pSPacket->BridgeId[i + 2] = pSPacket->RootId[i + 2] =
711 pAC->Addr.Net[pAC->Rlmt.Port[PortNumber].Net->NetNumber].
712 CurrentMacAddress.a[i];
713 }
714 pSPacket->PortId[0] = SK_RLMT_SPT_PORT_ID0;
715 pSPacket->PortId[1] = SK_RLMT_SPT_PORT_ID1;
716 pSPacket->MessageAge[0] = SK_RLMT_SPT_MSG_AGE0;
717 pSPacket->MessageAge[1] = SK_RLMT_SPT_MSG_AGE1;
718 pSPacket->MaxAge[0] = SK_RLMT_SPT_MAX_AGE0;
719 pSPacket->MaxAge[1] = SK_RLMT_SPT_MAX_AGE1;
720 pSPacket->HelloTime[0] = SK_RLMT_SPT_HELLO_TIME0;
721 pSPacket->HelloTime[1] = SK_RLMT_SPT_HELLO_TIME1;
722 pSPacket->ForwardDelay[0] = SK_RLMT_SPT_FWD_DELAY0;
723 pSPacket->ForwardDelay[1] = SK_RLMT_SPT_FWD_DELAY1;
724
725 Length = SK_RLMT_MAX_PACKET_SIZE; /* Or smaller. */
726 pMb->Length = Length;
727 pMb->PortIdx = PortNumber;
728 Length -= 14;
729 SK_U16_TO_NETWORK_ORDER(Length, &pSPacket->TypeLen[0]);
730
731 pAC->Rlmt.Port[PortNumber].TxSpHelloReqCts++;
732 }
733
734 return (pMb);
735} /* SkRlmtBuildSpanningTreePacket */
736
737
738/******************************************************************************
739 *
740 * SkRlmtSend - build and send check packets
741 *
742 * Description:
743 * Depending on the RLMT state and the checking state, several packets
744 * are sent through the indicated port.
745 *
746 * Context:
747 * runtime, pageable?
748 *
749 * Returns:
750 * Nothing.
751 */
752RLMT_STATIC void SkRlmtSend(
753SK_AC *pAC, /* Adapter Context */
754SK_IOC IoC, /* I/O Context */
755SK_U32 PortNumber) /* Sending port */
756{
757 unsigned j;
758 SK_EVPARA Para;
759 SK_RLMT_PORT *pRPort;
760
761 pRPort = &pAC->Rlmt.Port[PortNumber];
762 if (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) {
763 if (pRPort->CheckingState & (SK_RLMT_PCS_TX | SK_RLMT_PCS_RX)) {
764 /* Port is suspicious. Send the RLMT packet to the RLMT mc addr. */
765 if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
766 SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
767 &SkRlmtMcAddr)) != NULL) {
768 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
769 }
770 }
771 else {
772 /*
773 * Send a directed RLMT packet to all ports that are
774 * checked by the indicated port.
775 */
776 for (j = 0; j < pRPort->PortsChecked; j++) {
777 if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
778 SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
779 &pRPort->PortCheck[j].CheckAddr)) != NULL) {
780 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
781 }
782 }
783 }
784 }
785
786 if ((pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) &&
787 (pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEND_SEG)) {
788 /*
789 * Send a BPDU packet to make a connected switch tell us
790 * the correct root bridge.
791 */
792 if ((Para.pParaPtr =
793 SkRlmtBuildSpanningTreePacket(pAC, IoC, PortNumber)) != NULL) {
794 pAC->Rlmt.Port[PortNumber].Net->CheckingState &= ~SK_RLMT_RCS_SEND_SEG;
795 pRPort->RootIdSet = SK_FALSE;
796
797 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
798 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_TX,
799 ("SkRlmtSend: BPDU Packet on Port %u.\n", PortNumber))
800 }
801 }
802 return;
803} /* SkRlmtSend */
804
805
806/******************************************************************************
807 *
808 * SkRlmtPortReceives - check if port is (going) down and bring it up
809 *
810 * Description:
811 * This routine checks if a port who received a non-BPDU packet
812 * needs to go up or needs to be stopped going down.
813 *
814 * Context:
815 * runtime, pageable?
816 *
817 * Returns:
818 * Nothing.
819 */
820RLMT_STATIC void SkRlmtPortReceives(
821SK_AC *pAC, /* Adapter Context */
822SK_IOC IoC, /* I/O Context */
823SK_U32 PortNumber) /* Port to check */
824{
825 SK_RLMT_PORT *pRPort;
826 SK_EVPARA Para;
827
828 pRPort = &pAC->Rlmt.Port[PortNumber];
829 pRPort->PortNoRx = SK_FALSE;
830
831 if ((pRPort->PortState == SK_RLMT_PS_DOWN) &&
832 !(pRPort->CheckingState & SK_RLMT_PCS_TX)) {
833 /*
834 * Port is marked down (rx), but received a non-BPDU packet.
835 * Bring it up.
836 */
837 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
838 ("SkRlmtPacketReceive: Received on PortDown.\n"))
839
840 pRPort->PortState = SK_RLMT_PS_GOING_UP;
841 pRPort->GuTimeStamp = SkOsGetTime(pAC);
842 Para.Para32[0] = PortNumber;
843 Para.Para32[1] = (SK_U32)-1;
844 SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL,
845 SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para);
846 pRPort->CheckingState &= ~SK_RLMT_PCS_RX;
847 /* pAC->Rlmt.CheckSwitch = SK_TRUE; */
848 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
849 } /* PortDown && !SuspectTx */
850 else if (pRPort->CheckingState & SK_RLMT_PCS_RX) {
851 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
852 ("SkRlmtPacketReceive: Stop bringing port down.\n"))
853 SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
854 pRPort->CheckingState &= ~SK_RLMT_PCS_RX;
855 /* pAC->Rlmt.CheckSwitch = SK_TRUE; */
856 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
857 } /* PortGoingDown */
858
859 return;
860} /* SkRlmtPortReceives */
861
862
863/******************************************************************************
864 *
865 * SkRlmtPacketReceive - receive a packet for closer examination
866 *
867 * Description:
868 * This routine examines a packet more closely than SK_RLMT_LOOKAHEAD.
869 *
870 * Context:
871 * runtime, pageable?
872 *
873 * Returns:
874 * Nothing.
875 */
876RLMT_STATIC void SkRlmtPacketReceive(
877SK_AC *pAC, /* Adapter Context */
878SK_IOC IoC, /* I/O Context */
879SK_MBUF *pMb) /* Received packet */
880{
881#ifdef xDEBUG
882 extern void DumpData(char *p, int size);
883#endif /* DEBUG */
884 int i;
885 unsigned j;
886 SK_U16 PacketType;
887 SK_U32 PortNumber;
888 SK_ADDR_PORT *pAPort;
889 SK_RLMT_PORT *pRPort;
890 SK_RLMT_PACKET *pRPacket;
891 SK_SPTREE_PACKET *pSPacket;
892 SK_EVPARA Para;
893
894 PortNumber = pMb->PortIdx;
895 pAPort = &pAC->Addr.Port[PortNumber];
896 pRPort = &pAC->Rlmt.Port[PortNumber];
897
898 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
899 ("SkRlmtPacketReceive: PortNumber == %d.\n", PortNumber))
900
901 pRPacket = (SK_RLMT_PACKET*)pMb->pData;
902 pSPacket = (SK_SPTREE_PACKET*)pRPacket;
903
904#ifdef xDEBUG
905 DumpData((char *)pRPacket, 32);
906#endif /* DEBUG */
907
908 if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) != 0) {
909 SkRlmtPortReceives(pAC, IoC, PortNumber);
910 }
911
912 /* Check destination address. */
913
914 if (!SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->DstAddr) &&
915 !SK_ADDR_EQUAL(SkRlmtMcAddr.a, pRPacket->DstAddr) &&
916 !SK_ADDR_EQUAL(BridgeMcAddr.a, pRPacket->DstAddr)) {
917
918 /* Not sent to current MAC or registered MC address => Trash it. */
919 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
920 ("SkRlmtPacketReceive: Not for me.\n"))
921
922 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
923 return;
924 }
925 else if (SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->SrcAddr)) {
926
927 /*
928 * Was sent by same port (may happen during port switching
929 * or in case of duplicate MAC addresses).
930 */
931
932 /*
933 * Check for duplicate address here:
934 * If Packet.Random != My.Random => DupAddr.
935 */
936 for (i = 3; i >= 0; i--) {
937 if (pRPort->Random[i] != pRPacket->Random[i]) {
938 break;
939 }
940 }
941
942 /*
943 * CAUTION: Do not check for duplicate MAC address in RLMT Alive Reply
944 * packets (they have the LLC_COMMAND_RESPONSE_BIT set in
945 * pRPacket->SSap).
946 */
947 if (i >= 0 && pRPacket->DSap == SK_RLMT_DSAP &&
948 pRPacket->Ctrl == SK_RLMT_CTRL &&
949 pRPacket->SSap == SK_RLMT_SSAP &&
950 pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 &&
951 pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 &&
952 pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 &&
953 pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 &&
954 pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 &&
955 pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 &&
956 pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) {
957 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
958 ("SkRlmtPacketReceive: Duplicate MAC Address.\n"))
959
960 /* Error Log entry. */
961 SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E006, SKERR_RLMT_E006_MSG);
962 }
963 else {
964 /* Simply trash it. */
965 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
966 ("SkRlmtPacketReceive: Sent by me.\n"))
967 }
968
969 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
970 return;
971 }
972
973 /* Check SuspectTx entries. */
974 if (pRPort->PortsSuspect > 0) {
975 for (j = 0; j < pRPort->PortsChecked; j++) {
976 if (pRPort->PortCheck[j].SuspectTx &&
977 SK_ADDR_EQUAL(
978 pRPacket->SrcAddr, pRPort->PortCheck[j].CheckAddr.a)) {
979 pRPort->PortCheck[j].SuspectTx = SK_FALSE;
980 pRPort->PortsSuspect--;
981 break;
982 }
983 }
984 }
985
986 /* Determine type of packet. */
987 if (pRPacket->DSap == SK_RLMT_DSAP &&
988 pRPacket->Ctrl == SK_RLMT_CTRL &&
989 (pRPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SSAP &&
990 pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 &&
991 pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 &&
992 pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 &&
993 pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 &&
994 pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 &&
995 pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 &&
996 pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) {
997
998 /* It's an RLMT packet. */
999 PacketType = (SK_U16)((pRPacket->RlmtPacketType[0] << 8) |
1000 pRPacket->RlmtPacketType[1]);
1001
1002 switch (PacketType) {
1003 case SK_PACKET_ANNOUNCE: /* Not yet used. */
1004#if 0
1005 /* Build the check chain. */
1006 SkRlmtBuildCheckChain(pAC);
1007#endif /* 0 */
1008
1009 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1010 ("SkRlmtPacketReceive: Announce.\n"))
1011
1012 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1013 break;
1014
1015 case SK_PACKET_ALIVE:
1016 if (pRPacket->SSap & LLC_COMMAND_RESPONSE_BIT) {
1017 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1018 ("SkRlmtPacketReceive: Alive Reply.\n"))
1019
1020 if (!(pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_LLC) ||
1021 SK_ADDR_EQUAL(
1022 pRPacket->DstAddr, pAPort->CurrentMacAddress.a)) {
1023 /* Obviously we could send something. */
1024 if (pRPort->CheckingState & SK_RLMT_PCS_TX) {
1025 pRPort->CheckingState &= ~SK_RLMT_PCS_TX;
1026 SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
1027 }
1028
1029 if ((pRPort->PortState == SK_RLMT_PS_DOWN) &&
1030 !(pRPort->CheckingState & SK_RLMT_PCS_RX)) {
1031 pRPort->PortState = SK_RLMT_PS_GOING_UP;
1032 pRPort->GuTimeStamp = SkOsGetTime(pAC);
1033
1034 SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
1035
1036 Para.Para32[0] = PortNumber;
1037 Para.Para32[1] = (SK_U32)-1;
1038 SkTimerStart(pAC, IoC, &pRPort->UpTimer,
1039 SK_RLMT_PORTUP_TIM_VAL, SKGE_RLMT,
1040 SK_RLMT_PORTUP_TIM, Para);
1041 }
1042 }
1043
1044 /* Mark sending port as alive? */
1045 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1046 }
1047 else { /* Alive Request Packet. */
1048 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1049 ("SkRlmtPacketReceive: Alive Request.\n"))
1050
1051 pRPort->RxHelloCts++;
1052
1053 /* Answer. */
1054 for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
1055 pRPacket->DstAddr[i] = pRPacket->SrcAddr[i];
1056 pRPacket->SrcAddr[i] =
1057 pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i];
1058 }
1059 pRPacket->SSap |= LLC_COMMAND_RESPONSE_BIT;
1060
1061 Para.pParaPtr = pMb;
1062 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
1063 }
1064 break;
1065
1066 case SK_PACKET_CHECK_TX:
1067 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1068 ("SkRlmtPacketReceive: Check your tx line.\n"))
1069
1070 /* A port checking us requests us to check our tx line. */
1071 pRPort->CheckingState |= SK_RLMT_PCS_TX;
1072
1073 /* Start PortDownTx timer. */
1074 Para.Para32[0] = PortNumber;
1075 Para.Para32[1] = (SK_U32)-1;
1076 SkTimerStart(pAC, IoC, &pRPort->DownTxTimer,
1077 SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT,
1078 SK_RLMT_PORTDOWN_TX_TIM, Para);
1079
1080 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1081
1082 if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
1083 SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
1084 &SkRlmtMcAddr)) != NULL) {
1085 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
1086 }
1087 break;
1088
1089 case SK_PACKET_ADDR_CHANGED:
1090 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1091 ("SkRlmtPacketReceive: Address Change.\n"))
1092
1093 /* Build the check chain. */
1094 SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
1095 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1096 break;
1097
1098 default:
1099 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1100 ("SkRlmtPacketReceive: Unknown RLMT packet.\n"))
1101
1102 /* RA;:;: ??? */
1103 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1104 }
1105 }
1106 else if (pSPacket->DSap == SK_RLMT_SPT_DSAP &&
1107 pSPacket->Ctrl == SK_RLMT_SPT_CTRL &&
1108 (pSPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SPT_SSAP) {
1109 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1110 ("SkRlmtPacketReceive: BPDU Packet.\n"))
1111
1112 /* Spanning Tree packet. */
1113 pRPort->RxSpHelloCts++;
1114
1115 if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pAC->Addr.Net[pAC->Rlmt.
1116 Port[PortNumber].Net->NetNumber].CurrentMacAddress.a[0])) {
1117 /*
1118 * Check segmentation if a new root bridge is set and
1119 * the segmentation check is not currently running.
1120 */
1121 if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pRPort->Root.Id[2]) &&
1122 (pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) &&
1123 (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG)
1124 != 0 && (pAC->Rlmt.Port[PortNumber].Net->CheckingState &
1125 SK_RLMT_RCS_SEG) == 0) {
1126 pAC->Rlmt.Port[PortNumber].Net->CheckingState |=
1127 SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG;
1128 }
1129
1130 /* Store tree view of this port. */
1131 for (i = 0; i < 8; i++) {
1132 pRPort->Root.Id[i] = pSPacket->RootId[i];
1133 }
1134 pRPort->RootIdSet = SK_TRUE;
1135
1136 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP,
1137 ("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n",
1138 PortNumber,
1139 pRPort->Root.Id[0], pRPort->Root.Id[1],
1140 pRPort->Root.Id[2], pRPort->Root.Id[3],
1141 pRPort->Root.Id[4], pRPort->Root.Id[5],
1142 pRPort->Root.Id[6], pRPort->Root.Id[7]))
1143 }
1144
1145 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1146 if ((pAC->Rlmt.Port[PortNumber].Net->CheckingState &
1147 SK_RLMT_RCS_REPORT_SEG) != 0) {
1148 SkRlmtCheckSeg(pAC, IoC, pAC->Rlmt.Port[PortNumber].Net->NetNumber);
1149 }
1150 }
1151 else {
1152 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1153 ("SkRlmtPacketReceive: Unknown Packet Type.\n"))
1154
1155 /* Unknown packet. */
1156 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1157 }
1158 return;
1159} /* SkRlmtPacketReceive */
1160
1161
1162/******************************************************************************
1163 *
1164 * SkRlmtCheckPort - check if a port works
1165 *
1166 * Description:
1167 * This routine checks if a port whose link is up received something
1168 * and if it seems to transmit successfully.
1169 *
1170 * # PortState: PsInit, PsLinkDown, PsDown, PsGoingUp, PsUp
1171 * # PortCheckingState (Bitfield): ChkTx, ChkRx, ChkSeg
1172 * # RlmtCheckingState (Bitfield): ChkSeg, StartChkSeg, ReportSeg
1173 *
1174 * if (Rx - RxBpdu == 0) { # No rx.
1175 * if (state == PsUp) {
1176 * PortCheckingState |= ChkRx
1177 * }
1178 * if (ModeCheckSeg && (Timeout ==
1179 * TO_SHORTEN(RLMT_DEFAULT_TIMEOUT))) {
1180 * RlmtCheckingState |= ChkSeg)
1181 * PortCheckingState |= ChkSeg
1182 * }
1183 * NewTimeout = TO_SHORTEN(Timeout)
1184 * if (NewTimeout < RLMT_MIN_TIMEOUT) {
1185 * NewTimeout = RLMT_MIN_TIMEOUT
1186 * PortState = PsDown
1187 * ...
1188 * }
1189 * }
1190 * else { # something was received
1191 * # Set counter to 0 at LinkDown?
1192 * # No - rx may be reported after LinkDown ???
1193 * PortCheckingState &= ~ChkRx
1194 * NewTimeout = RLMT_DEFAULT_TIMEOUT
1195 * if (RxAck == 0) {
1196 * possible reasons:
1197 * is my tx line bad? --
1198 * send RLMT multicast and report
1199 * back internally? (only possible
1200 * between ports on same adapter)
1201 * }
1202 * if (RxChk == 0) {
1203 * possible reasons:
1204 * - tx line of port set to check me
1205 * maybe bad
1206 * - no other port/adapter available or set
1207 * to check me
1208 * - adapter checking me has a longer
1209 * timeout
1210 * ??? anything that can be done here?
1211 * }
1212 * }
1213 *
1214 * Context:
1215 * runtime, pageable?
1216 *
1217 * Returns:
1218 * New timeout value.
1219 */
1220RLMT_STATIC SK_U32 SkRlmtCheckPort(
1221SK_AC *pAC, /* Adapter Context */
1222SK_IOC IoC, /* I/O Context */
1223SK_U32 PortNumber) /* Port to check */
1224{
1225 unsigned i;
1226 SK_U32 NewTimeout;
1227 SK_RLMT_PORT *pRPort;
1228 SK_EVPARA Para;
1229
1230 pRPort = &pAC->Rlmt.Port[PortNumber];
1231
1232 if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) == 0) {
1233 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1234 ("SkRlmtCheckPort %d: No (%d) receives in last time slot.\n",
1235 PortNumber, pRPort->PacketsPerTimeSlot))
1236
1237 /*
1238 * Check segmentation if there was no receive at least twice
1239 * in a row (PortNoRx is already set) and the segmentation
1240 * check is not currently running.
1241 */
1242
1243 if (pRPort->PortNoRx && (pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) &&
1244 (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) &&
1245 !(pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEG)) {
1246 pAC->Rlmt.Port[PortNumber].Net->CheckingState |=
1247 SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG;
1248 }
1249
1250 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1251 ("SkRlmtCheckPort: PortsSuspect %d, PcsRx %d.\n",
1252 pRPort->PortsSuspect, pRPort->CheckingState & SK_RLMT_PCS_RX))
1253
1254 if (pRPort->PortState != SK_RLMT_PS_DOWN) {
1255 NewTimeout = TO_SHORTEN(pAC->Rlmt.Port[PortNumber].Net->TimeoutValue);
1256 if (NewTimeout < SK_RLMT_MIN_TO_VAL) {
1257 NewTimeout = SK_RLMT_MIN_TO_VAL;
1258 }
1259
1260 if (!(pRPort->CheckingState & SK_RLMT_PCS_RX)) {
1261 Para.Para32[0] = PortNumber;
1262 pRPort->CheckingState |= SK_RLMT_PCS_RX;
1263
1264 /*
1265 * What shall we do if the port checked by this one receives
1266 * our request frames? What's bad - our rx line or his tx line?
1267 */
1268 Para.Para32[1] = (SK_U32)-1;
1269 SkTimerStart(pAC, IoC, &pRPort->DownRxTimer,
1270 SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT,
1271 SK_RLMT_PORTDOWN_RX_TIM, Para);
1272
1273 for (i = 0; i < pRPort->PortsChecked; i++) {
1274 if (pRPort->PortCheck[i].SuspectTx) {
1275 continue;
1276 }
1277 pRPort->PortCheck[i].SuspectTx = SK_TRUE;
1278 pRPort->PortsSuspect++;
1279 if ((Para.pParaPtr =
1280 SkRlmtBuildPacket(pAC, IoC, PortNumber, SK_PACKET_CHECK_TX,
1281 &pAC->Addr.Port[PortNumber].CurrentMacAddress,
1282 &pRPort->PortCheck[i].CheckAddr)) != NULL) {
1283 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
1284 }
1285 }
1286 }
1287 }
1288 else { /* PortDown -- or all partners suspect. */
1289 NewTimeout = SK_RLMT_DEF_TO_VAL;
1290 }
1291 pRPort->PortNoRx = SK_TRUE;
1292 }
1293 else { /* A non-BPDU packet was received. */
1294 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1295 ("SkRlmtCheckPort %d: %d (%d) receives in last time slot.\n",
1296 PortNumber,
1297 pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot,
1298 pRPort->PacketsPerTimeSlot))
1299
1300 SkRlmtPortReceives(pAC, IoC, PortNumber);
1301 if (pAC->Rlmt.CheckSwitch) {
1302 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
1303 }
1304
1305 NewTimeout = SK_RLMT_DEF_TO_VAL;
1306 }
1307
1308 return (NewTimeout);
1309} /* SkRlmtCheckPort */
1310
1311
1312/******************************************************************************
1313 *
1314 * SkRlmtSelectBcRx - select new active port, criteria 1 (CLP)
1315 *
1316 * Description:
1317 * This routine selects the port that received a broadcast frame
1318 * substantially later than all other ports.
1319 *
1320 * Context:
1321 * runtime, pageable?
1322 *
1323 * Returns:
1324 * SK_BOOL
1325 */
1326RLMT_STATIC SK_BOOL SkRlmtSelectBcRx(
1327SK_AC *pAC, /* Adapter Context */
1328SK_IOC IoC, /* I/O Context */
1329SK_U32 Active, /* Active port */
1330SK_U32 PrefPort, /* Preferred port */
1331SK_U32 *pSelect) /* New active port */
1332{
1333 SK_U64 BcTimeStamp;
1334 SK_U32 i;
1335 SK_BOOL PortFound;
1336
1337 BcTimeStamp = 0; /* Not totally necessary, but feeling better. */
1338 PortFound = SK_FALSE;
1339
1340 /* Select port with the latest TimeStamp. */
1341 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1342
1343 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1344 ("TimeStamp Port %d (Down: %d, NoRx: %d): %08x %08x.\n",
1345 i,
1346 pAC->Rlmt.Port[i].PortDown, pAC->Rlmt.Port[i].PortNoRx,
1347 *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_HI32),
1348 *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_LO32)))
1349
1350 if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx) {
1351 if (!PortFound || pAC->Rlmt.Port[i].BcTimeStamp > BcTimeStamp) {
1352 BcTimeStamp = pAC->Rlmt.Port[i].BcTimeStamp;
1353 *pSelect = i;
1354 PortFound = SK_TRUE;
1355 }
1356 }
1357 }
1358
1359 if (PortFound) {
1360 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1361 ("Port %d received the last broadcast.\n", *pSelect))
1362
1363 /* Look if another port's time stamp is similar. */
1364 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1365 if (i == *pSelect) {
1366 continue;
1367 }
1368 if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx &&
1369 (pAC->Rlmt.Port[i].BcTimeStamp >
1370 BcTimeStamp - SK_RLMT_BC_DELTA ||
1371 pAC->Rlmt.Port[i].BcTimeStamp +
1372 SK_RLMT_BC_DELTA > BcTimeStamp)) {
1373 PortFound = SK_FALSE;
1374
1375 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1376 ("Port %d received a broadcast at a similar time.\n", i))
1377 break;
1378 }
1379 }
1380 }
1381
1382#ifdef DEBUG
1383 if (PortFound) {
1384 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1385 ("SK_RLMT_SELECT_BCRX found Port %d receiving the substantially "
1386 "latest broadcast (%u).\n",
1387 *pSelect,
1388 BcTimeStamp - pAC->Rlmt.Port[1 - *pSelect].BcTimeStamp))
1389 }
1390#endif /* DEBUG */
1391
1392 return (PortFound);
1393} /* SkRlmtSelectBcRx */
1394
1395
1396/******************************************************************************
1397 *
1398 * SkRlmtSelectNotSuspect - select new active port, criteria 2 (CLP)
1399 *
1400 * Description:
1401 * This routine selects a good port (it is PortUp && !SuspectRx).
1402 *
1403 * Context:
1404 * runtime, pageable?
1405 *
1406 * Returns:
1407 * SK_BOOL
1408 */
1409RLMT_STATIC SK_BOOL SkRlmtSelectNotSuspect(
1410SK_AC *pAC, /* Adapter Context */
1411SK_IOC IoC, /* I/O Context */
1412SK_U32 Active, /* Active port */
1413SK_U32 PrefPort, /* Preferred port */
1414SK_U32 *pSelect) /* New active port */
1415{
1416 SK_U32 i;
1417 SK_BOOL PortFound;
1418
1419 PortFound = SK_FALSE;
1420
1421 /* Select first port that is PortUp && !SuspectRx. */
1422 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1423 if (!pAC->Rlmt.Port[i].PortDown &&
1424 !(pAC->Rlmt.Port[i].CheckingState & SK_RLMT_PCS_RX)) {
1425 *pSelect = i;
1426 if (!pAC->Rlmt.Port[Active].PortDown &&
1427 !(pAC->Rlmt.Port[Active].CheckingState & SK_RLMT_PCS_RX)) {
1428 *pSelect = Active;
1429 }
1430 if (!pAC->Rlmt.Port[PrefPort].PortDown &&
1431 !(pAC->Rlmt.Port[PrefPort].CheckingState & SK_RLMT_PCS_RX)) {
1432 *pSelect = PrefPort;
1433 }
1434 PortFound = SK_TRUE;
1435 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1436 ("SK_RLMT_SELECT_NOTSUSPECT found Port %d up and not check RX.\n",
1437 *pSelect))
1438 break;
1439 }
1440 }
1441 return (PortFound);
1442} /* SkRlmtSelectNotSuspect */
1443
1444
1445/******************************************************************************
1446 *
1447 * SkRlmtSelectUp - select new active port, criteria 3, 4 (CLP)
1448 *
1449 * Description:
1450 * This routine selects a port that is up.
1451 *
1452 * Context:
1453 * runtime, pageable?
1454 *
1455 * Returns:
1456 * SK_BOOL
1457 */
1458RLMT_STATIC SK_BOOL SkRlmtSelectUp(
1459SK_AC *pAC, /* Adapter Context */
1460SK_IOC IoC, /* I/O Context */
1461SK_U32 Active, /* Active port */
1462SK_U32 PrefPort, /* Preferred port */
1463SK_U32 *pSelect, /* New active port */
1464SK_BOOL AutoNegDone) /* Successfully auto-negotiated? */
1465{
1466 SK_U32 i;
1467 SK_BOOL PortFound;
1468
1469 PortFound = SK_FALSE;
1470
1471 /* Select first port that is PortUp. */
1472 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1473 if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_UP &&
1474 pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
1475 *pSelect = i;
1476 if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_UP &&
1477 pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) {
1478 *pSelect = Active;
1479 }
1480 if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_UP &&
1481 pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) {
1482 *pSelect = PrefPort;
1483 }
1484 PortFound = SK_TRUE;
1485 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1486 ("SK_RLMT_SELECT_UP found Port %d up.\n", *pSelect))
1487 break;
1488 }
1489 }
1490 return (PortFound);
1491} /* SkRlmtSelectUp */
1492
1493
1494/******************************************************************************
1495 *
1496 * SkRlmtSelectGoingUp - select new active port, criteria 5, 6 (CLP)
1497 *
1498 * Description:
1499 * This routine selects the port that is going up for the longest time.
1500 *
1501 * Context:
1502 * runtime, pageable?
1503 *
1504 * Returns:
1505 * SK_BOOL
1506 */
1507RLMT_STATIC SK_BOOL SkRlmtSelectGoingUp(
1508SK_AC *pAC, /* Adapter Context */
1509SK_IOC IoC, /* I/O Context */
1510SK_U32 Active, /* Active port */
1511SK_U32 PrefPort, /* Preferred port */
1512SK_U32 *pSelect, /* New active port */
1513SK_BOOL AutoNegDone) /* Successfully auto-negotiated? */
1514{
1515 SK_U64 GuTimeStamp;
1516 SK_U32 i;
1517 SK_BOOL PortFound;
1518
1519 GuTimeStamp = 0;
1520 PortFound = SK_FALSE;
1521
1522 /* Select port that is PortGoingUp for the longest time. */
1523 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1524 if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP &&
1525 pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
1526 GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp;
1527 *pSelect = i;
1528 PortFound = SK_TRUE;
1529 break;
1530 }
1531 }
1532
1533 if (!PortFound) {
1534 return (SK_FALSE);
1535 }
1536
1537 for (i = *pSelect + 1; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1538 if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP &&
1539 pAC->Rlmt.Port[i].GuTimeStamp < GuTimeStamp &&
1540 pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
1541 GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp;
1542 *pSelect = i;
1543 }
1544 }
1545
1546 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1547 ("SK_RLMT_SELECT_GOINGUP found Port %d going up.\n", *pSelect))
1548 return (SK_TRUE);
1549} /* SkRlmtSelectGoingUp */
1550
1551
1552/******************************************************************************
1553 *
1554 * SkRlmtSelectDown - select new active port, criteria 7, 8 (CLP)
1555 *
1556 * Description:
1557 * This routine selects a port that is down.
1558 *
1559 * Context:
1560 * runtime, pageable?
1561 *
1562 * Returns:
1563 * SK_BOOL
1564 */
1565RLMT_STATIC SK_BOOL SkRlmtSelectDown(
1566SK_AC *pAC, /* Adapter Context */
1567SK_IOC IoC, /* I/O Context */
1568SK_U32 Active, /* Active port */
1569SK_U32 PrefPort, /* Preferred port */
1570SK_U32 *pSelect, /* New active port */
1571SK_BOOL AutoNegDone) /* Successfully auto-negotiated? */
1572{
1573 SK_U32 i;
1574 SK_BOOL PortFound;
1575
1576 PortFound = SK_FALSE;
1577
1578 /* Select first port that is PortDown. */
1579 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1580 if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_DOWN &&
1581 pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
1582 *pSelect = i;
1583 if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_DOWN &&
1584 pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) {
1585 *pSelect = Active;
1586 }
1587 if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_DOWN &&
1588 pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) {
1589 *pSelect = PrefPort;
1590 }
1591 PortFound = SK_TRUE;
1592 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1593 ("SK_RLMT_SELECT_DOWN found Port %d down.\n", *pSelect))
1594 break;
1595 }
1596 }
1597 return (PortFound);
1598} /* SkRlmtSelectDown */
1599
1600
1601/******************************************************************************
1602 *
1603 * SkRlmtCheckSwitch - select new active port and switch to it
1604 *
1605 * Description:
1606 * This routine decides which port should be the active one and queues
1607 * port switching if necessary.
1608 *
1609 * Context:
1610 * runtime, pageable?
1611 *
1612 * Returns:
1613 * Nothing.
1614 */
1615RLMT_STATIC void SkRlmtCheckSwitch(
1616SK_AC *pAC, /* Adapter Context */
1617SK_IOC IoC, /* I/O Context */
1618SK_U32 NetIdx) /* Net index */
1619{
1620 SK_EVPARA Para;
1621 SK_U32 Active;
1622 SK_U32 PrefPort;
1623 SK_U32 i;
1624 SK_BOOL PortFound;
1625
1626 Active = pAC->Rlmt.Net[NetIdx].ActivePort; /* Index of active port. */
1627 PrefPort = pAC->Rlmt.Net[NetIdx].PrefPort; /* Index of preferred port. */
1628 PortFound = SK_FALSE;
1629 pAC->Rlmt.CheckSwitch = SK_FALSE;
1630
1631#if 0 /* RW 2001/10/18 - active port becomes always prefered one */
1632 if (pAC->Rlmt.Net[NetIdx].Preference == 0xFFFFFFFF) { /* Automatic */
1633 /* disable auto-fail back */
1634 PrefPort = Active;
1635 }
1636#endif
1637
1638 if (pAC->Rlmt.Net[NetIdx].LinksUp == 0) {
1639 /* Last link went down - shut down the net. */
1640 pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_DOWN;
1641 Para.Para32[0] = SK_RLMT_NET_DOWN_TEMP;
1642 Para.Para32[1] = NetIdx;
1643 SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para);
1644
1645 Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
1646 Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber;
1647 Para.Para32[1] = NetIdx;
1648 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para);
1649 return;
1650 } /* pAC->Rlmt.LinksUp == 0 */
1651 else if (pAC->Rlmt.Net[NetIdx].LinksUp == 1 &&
1652 pAC->Rlmt.Net[NetIdx].RlmtState == SK_RLMT_RS_NET_DOWN) {
1653 /* First link came up - get the net up. */
1654 pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_UP;
1655
1656 /*
1657 * If pAC->Rlmt.ActivePort != Para.Para32[0],
1658 * the DRV switches to the port that came up.
1659 */
1660 for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
1661 if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) {
1662 if (!pAC->Rlmt.Net[NetIdx].Port[Active]->LinkDown) {
1663 i = Active;
1664 }
1665 if (!pAC->Rlmt.Net[NetIdx].Port[PrefPort]->LinkDown) {
1666 i = PrefPort;
1667 }
1668 PortFound = SK_TRUE;
1669 break;
1670 }
1671 }
1672
1673 if (PortFound) {
1674 Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber;
1675 Para.Para32[1] = NetIdx;
1676 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para);
1677
1678 pAC->Rlmt.Net[NetIdx].ActivePort = i;
1679 Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber;
1680 Para.Para32[1] = NetIdx;
1681 SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_UP, Para);
1682
1683 if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
1684 (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC,
1685 pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber,
1686 SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].
1687 CurrentMacAddress, &SkRlmtMcAddr)) != NULL) {
1688 /*
1689 * Send announce packet to RLMT multicast address to force
1690 * switches to learn the new location of the logical MAC address.
1691 */
1692 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
1693 }
1694 }
1695 else {
1696 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E007, SKERR_RLMT_E007_MSG);
1697 }
1698
1699 return;
1700 } /* LinksUp == 1 && RlmtState == SK_RLMT_RS_NET_DOWN */
1701 else { /* Cannot be reached in dual-net mode. */
1702 Para.Para32[0] = Active;
1703
1704 /*
1705 * Preselection:
1706 * If RLMT Mode != CheckLinkState
1707 * select port that received a broadcast frame substantially later
1708 * than all other ports
1709 * else select first port that is not SuspectRx
1710 * else select first port that is PortUp
1711 * else select port that is PortGoingUp for the longest time
1712 * else select first port that is PortDown
1713 * else stop.
1714 *
1715 * For the preselected port:
1716 * If ActivePort is equal in quality, select ActivePort.
1717 *
1718 * If PrefPort is equal in quality, select PrefPort.
1719 *
1720 * If ActivePort != SelectedPort,
1721 * If old ActivePort is LinkDown,
1722 * SwitchHard
1723 * else
1724 * SwitchSoft
1725 */
1726 /* check of ChgBcPrio flag added */
1727 if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) &&
1728 (!pAC->Rlmt.Net[0].ChgBcPrio)) {
1729
1730 if (!PortFound) {
1731 PortFound = SkRlmtSelectBcRx(
1732 pAC, IoC, Active, PrefPort, &Para.Para32[1]);
1733 }
1734
1735 if (!PortFound) {
1736 PortFound = SkRlmtSelectNotSuspect(
1737 pAC, IoC, Active, PrefPort, &Para.Para32[1]);
1738 }
1739 } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */
1740
1741 /* with changed priority for last broadcast received */
1742 if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) &&
1743 (pAC->Rlmt.Net[0].ChgBcPrio)) {
1744 if (!PortFound) {
1745 PortFound = SkRlmtSelectNotSuspect(
1746 pAC, IoC, Active, PrefPort, &Para.Para32[1]);
1747 }
1748
1749 if (!PortFound) {
1750 PortFound = SkRlmtSelectBcRx(
1751 pAC, IoC, Active, PrefPort, &Para.Para32[1]);
1752 }
1753 } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */
1754
1755 if (!PortFound) {
1756 PortFound = SkRlmtSelectUp(
1757 pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
1758 }
1759
1760 if (!PortFound) {
1761 PortFound = SkRlmtSelectUp(
1762 pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
1763 }
1764
1765 if (!PortFound) {
1766 PortFound = SkRlmtSelectGoingUp(
1767 pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
1768 }
1769
1770 if (!PortFound) {
1771 PortFound = SkRlmtSelectGoingUp(
1772 pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
1773 }
1774
1775 if (pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) {
1776 if (!PortFound) {
1777 PortFound = SkRlmtSelectDown(pAC, IoC,
1778 Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
1779 }
1780
1781 if (!PortFound) {
1782 PortFound = SkRlmtSelectDown(pAC, IoC,
1783 Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
1784 }
1785 } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */
1786
1787 if (PortFound) {
1788
1789 if (Para.Para32[1] != Active) {
1790 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1791 ("Active: %d, Para1: %d.\n", Active, Para.Para32[1]))
1792 pAC->Rlmt.Net[NetIdx].ActivePort = Para.Para32[1];
1793 Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
1794 Port[Para.Para32[0]]->PortNumber;
1795 Para.Para32[1] = pAC->Rlmt.Net[NetIdx].
1796 Port[Para.Para32[1]]->PortNumber;
1797 SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[1], SK_LED_ACTIVE);
1798 if (pAC->Rlmt.Port[Active].LinkDown) {
1799 SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_HARD, Para);
1800 }
1801 else {
1802 SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY);
1803 SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_SOFT, Para);
1804 }
1805 Para.Para32[1] = NetIdx;
1806 Para.Para32[0] =
1807 pAC->Rlmt.Net[NetIdx].Port[Para.Para32[0]]->PortNumber;
1808 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para);
1809 Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
1810 Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber;
1811 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para);
1812 if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
1813 (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, Para.Para32[0],
1814 SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].CurrentMacAddress,
1815 &SkRlmtMcAddr)) != NULL) {
1816 /*
1817 * Send announce packet to RLMT multicast address to force
1818 * switches to learn the new location of the logical
1819 * MAC address.
1820 */
1821 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
1822 } /* (Para.pParaPtr = SkRlmtBuildPacket(...)) != NULL */
1823 } /* Para.Para32[1] != Active */
1824 } /* PortFound */
1825 else {
1826 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E004, SKERR_RLMT_E004_MSG);
1827 }
1828 } /* LinksUp > 1 || LinksUp == 1 && RlmtState != SK_RLMT_RS_NET_DOWN */
1829 return;
1830} /* SkRlmtCheckSwitch */
1831
1832
1833/******************************************************************************
1834 *
1835 * SkRlmtCheckSeg - Report if segmentation is detected
1836 *
1837 * Description:
1838 * This routine checks if the ports see different root bridges and reports
1839 * segmentation in such a case.
1840 *
1841 * Context:
1842 * runtime, pageable?
1843 *
1844 * Returns:
1845 * Nothing.
1846 */
1847RLMT_STATIC void SkRlmtCheckSeg(
1848SK_AC *pAC, /* Adapter Context */
1849SK_IOC IoC, /* I/O Context */
1850SK_U32 NetIdx) /* Net number */
1851{
1852 SK_EVPARA Para;
1853 SK_RLMT_NET *pNet;
1854 SK_U32 i, j;
1855 SK_BOOL Equal;
1856
1857 pNet = &pAC->Rlmt.Net[NetIdx];
1858 pNet->RootIdSet = SK_FALSE;
1859 Equal = SK_TRUE;
1860
1861 for (i = 0; i < pNet->NumPorts; i++) {
1862 if (pNet->Port[i]->LinkDown || !pNet->Port[i]->RootIdSet) {
1863 continue;
1864 }
1865
1866 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP,
1867 ("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n", i,
1868 pNet->Port[i]->Root.Id[0], pNet->Port[i]->Root.Id[1],
1869 pNet->Port[i]->Root.Id[2], pNet->Port[i]->Root.Id[3],
1870 pNet->Port[i]->Root.Id[4], pNet->Port[i]->Root.Id[5],
1871 pNet->Port[i]->Root.Id[6], pNet->Port[i]->Root.Id[7]))
1872
1873 if (!pNet->RootIdSet) {
1874 pNet->Root = pNet->Port[i]->Root;
1875 pNet->RootIdSet = SK_TRUE;
1876 continue;
1877 }
1878
1879 for (j = 0; j < 8; j ++) {
1880 Equal &= pNet->Port[i]->Root.Id[j] == pNet->Root.Id[j];
1881 if (!Equal) {
1882 break;
1883 }
1884 }
1885
1886 if (!Equal) {
1887 SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E005, SKERR_RLMT_E005_MSG);
1888 Para.Para32[0] = NetIdx;
1889 Para.Para32[1] = (SK_U32)-1;
1890 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SEGMENTATION, Para);
1891
1892 pNet->CheckingState &= ~SK_RLMT_RCS_REPORT_SEG;
1893
1894 /* 2000-03-06 RA: New. */
1895 Para.Para32[0] = NetIdx;
1896 Para.Para32[1] = (SK_U32)-1;
1897 SkTimerStart(pAC, IoC, &pNet->SegTimer, SK_RLMT_SEG_TO_VAL,
1898 SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
1899 break;
1900 }
1901 } /* for (i = 0; i < pNet->NumPorts; i++) */
1902
1903 /* 2000-03-06 RA: Moved here. */
1904 /* Segmentation check not running anymore. */
1905 pNet->CheckingState &= ~SK_RLMT_RCS_SEG;
1906
1907} /* SkRlmtCheckSeg */
1908
1909
1910/******************************************************************************
1911 *
1912 * SkRlmtPortStart - initialize port variables and start port
1913 *
1914 * Description:
1915 * This routine initializes a port's variables and issues a PORT_START
1916 * to the HWAC module. This handles retries if the start fails or the
1917 * link eventually goes down.
1918 *
1919 * Context:
1920 * runtime, pageable?
1921 *
1922 * Returns:
1923 * Nothing
1924 */
1925RLMT_STATIC void SkRlmtPortStart(
1926SK_AC *pAC, /* Adapter Context */
1927SK_IOC IoC, /* I/O Context */
1928SK_U32 PortNumber) /* Port number */
1929{
1930 SK_EVPARA Para;
1931
1932 pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_LINK_DOWN;
1933 pAC->Rlmt.Port[PortNumber].PortStarted = SK_TRUE;
1934 pAC->Rlmt.Port[PortNumber].LinkDown = SK_TRUE;
1935 pAC->Rlmt.Port[PortNumber].PortDown = SK_TRUE;
1936 pAC->Rlmt.Port[PortNumber].CheckingState = 0;
1937 pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE;
1938 Para.Para32[0] = PortNumber;
1939 Para.Para32[1] = (SK_U32)-1;
1940 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
1941} /* SkRlmtPortStart */
1942
1943
1944/******************************************************************************
1945 *
1946 * SkRlmtEvtPortStartTim - PORT_START_TIM
1947 *
1948 * Description:
1949 * This routine handles PORT_START_TIM events.
1950 *
1951 * Context:
1952 * runtime, pageable?
1953 * may be called after SK_INIT_IO
1954 *
1955 * Returns:
1956 * Nothing
1957 */
1958RLMT_STATIC void SkRlmtEvtPortStartTim(
1959SK_AC *pAC, /* Adapter Context */
1960SK_IOC IoC, /* I/O Context */
1961SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */
1962{
1963 SK_U32 i;
1964
1965 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1966 ("SK_RLMT_PORTSTART_TIMEOUT Port %d Event BEGIN.\n", Para.Para32[0]))
1967
1968 if (Para.Para32[1] != (SK_U32)-1) {
1969 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1970 ("Bad Parameter.\n"))
1971 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1972 ("SK_RLMT_PORTSTART_TIMEOUT Event EMPTY.\n"))
1973 return;
1974 }
1975
1976 /*
1977 * Used to start non-preferred ports if the preferred one
1978 * does not come up.
1979 * This timeout needs only be set when starting the first
1980 * (preferred) port.
1981 */
1982 if (pAC->Rlmt.Port[Para.Para32[0]].LinkDown) {
1983 /* PORT_START failed. */
1984 for (i = 0; i < pAC->Rlmt.Port[Para.Para32[0]].Net->NumPorts; i++) {
1985 if (!pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortStarted) {
1986 SkRlmtPortStart(pAC, IoC,
1987 pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortNumber);
1988 }
1989 }
1990 }
1991
1992 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1993 ("SK_RLMT_PORTSTART_TIMEOUT Event END.\n"))
1994} /* SkRlmtEvtPortStartTim */
1995
1996
1997/******************************************************************************
1998 *
1999 * SkRlmtEvtLinkUp - LINK_UP
2000 *
2001 * Description:
2002 * This routine handles LLINK_UP events.
2003 *
2004 * Context:
2005 * runtime, pageable?
2006 * may be called after SK_INIT_IO
2007 *
2008 * Returns:
2009 * Nothing
2010 */
2011RLMT_STATIC void SkRlmtEvtLinkUp(
2012SK_AC *pAC, /* Adapter Context */
2013SK_IOC IoC, /* I/O Context */
2014SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 Undefined */
2015{
2016 SK_U32 i;
2017 SK_RLMT_PORT *pRPort;
2018 SK_EVPARA Para2;
2019
2020 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2021 ("SK_RLMT_LINK_UP Port %d Event BEGIN.\n", Para.Para32[0]))
2022
2023 pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
2024 if (!pRPort->PortStarted) {
2025 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E008, SKERR_RLMT_E008_MSG);
2026
2027 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2028 ("SK_RLMT_LINK_UP Event EMPTY.\n"))
2029 return;
2030 }
2031
2032 if (!pRPort->LinkDown) {
2033 /* RA;:;: Any better solution? */
2034 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2035 ("SK_RLMT_LINK_UP Event EMPTY.\n"))
2036 return;
2037 }
2038
2039 SkTimerStop(pAC, IoC, &pRPort->UpTimer);
2040 SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
2041 SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
2042
2043 /* Do something if timer already fired? */
2044
2045 pRPort->LinkDown = SK_FALSE;
2046 pRPort->PortState = SK_RLMT_PS_GOING_UP;
2047 pRPort->GuTimeStamp = SkOsGetTime(pAC);
2048 pRPort->BcTimeStamp = 0;
2049 pRPort->Net->LinksUp++;
2050 if (pRPort->Net->LinksUp == 1) {
2051 SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_ACTIVE);
2052 }
2053 else {
2054 SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY);
2055 }
2056
2057 for (i = 0; i < pRPort->Net->NumPorts; i++) {
2058 if (!pRPort->Net->Port[i]->PortStarted) {
2059 SkRlmtPortStart(pAC, IoC, pRPort->Net->Port[i]->PortNumber);
2060 }
2061 }
2062
2063 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
2064
2065 if (pRPort->Net->LinksUp >= 2) {
2066 if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) {
2067 /* Build the check chain. */
2068 SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
2069 }
2070 }
2071
2072 /* If the first link comes up, start the periodical RLMT timeout. */
2073 if (pRPort->Net->NumPorts > 1 && pRPort->Net->LinksUp == 1 &&
2074 (pRPort->Net->RlmtMode & SK_RLMT_CHECK_OTHERS) != 0) {
2075 Para2.Para32[0] = pRPort->Net->NetNumber;
2076 Para2.Para32[1] = (SK_U32)-1;
2077 SkTimerStart(pAC, IoC, &pRPort->Net->LocTimer,
2078 pRPort->Net->TimeoutValue, SKGE_RLMT, SK_RLMT_TIM, Para2);
2079 }
2080
2081 Para2 = Para;
2082 Para2.Para32[1] = (SK_U32)-1;
2083 SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL,
2084 SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para2);
2085
2086 /* Later: if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LOC_LINK) && */
2087 if ((pRPort->Net->RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
2088 (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LINK) != 0 &&
2089 (Para2.pParaPtr =
2090 SkRlmtBuildPacket(pAC, IoC, Para.Para32[0], SK_PACKET_ANNOUNCE,
2091 &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress, &SkRlmtMcAddr)
2092 ) != NULL) {
2093 /* Send "new" packet to RLMT multicast address. */
2094 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
2095 }
2096
2097 if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_SEG) {
2098 if ((Para2.pParaPtr =
2099 SkRlmtBuildSpanningTreePacket(pAC, IoC, Para.Para32[0])) != NULL) {
2100 pAC->Rlmt.Port[Para.Para32[0]].RootIdSet = SK_FALSE;
2101 pRPort->Net->CheckingState |=
2102 SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG;
2103
2104 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
2105
2106 Para.Para32[1] = (SK_U32)-1;
2107 SkTimerStart(pAC, IoC, &pRPort->Net->SegTimer,
2108 SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
2109 }
2110 }
2111
2112 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2113 ("SK_RLMT_LINK_UP Event END.\n"))
2114} /* SkRlmtEvtLinkUp */
2115
2116
2117/******************************************************************************
2118 *
2119 * SkRlmtEvtPortUpTim - PORT_UP_TIM
2120 *
2121 * Description:
2122 * This routine handles PORT_UP_TIM events.
2123 *
2124 * Context:
2125 * runtime, pageable?
2126 * may be called after SK_INIT_IO
2127 *
2128 * Returns:
2129 * Nothing
2130 */
2131RLMT_STATIC void SkRlmtEvtPortUpTim(
2132SK_AC *pAC, /* Adapter Context */
2133SK_IOC IoC, /* I/O Context */
2134SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */
2135{
2136 SK_RLMT_PORT *pRPort;
2137
2138 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2139 ("SK_RLMT_PORTUP_TIM Port %d Event BEGIN.\n", Para.Para32[0]))
2140
2141 if (Para.Para32[1] != (SK_U32)-1) {
2142 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2143 ("Bad Parameter.\n"))
2144 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2145 ("SK_RLMT_PORTUP_TIM Event EMPTY.\n"))
2146 return;
2147 }
2148
2149 pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
2150 if (pRPort->LinkDown || (pRPort->PortState == SK_RLMT_PS_UP)) {
2151 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2152 ("SK_RLMT_PORTUP_TIM Port %d Event EMPTY.\n", Para.Para32[0]))
2153 return;
2154 }
2155
2156 pRPort->PortDown = SK_FALSE;
2157 pRPort->PortState = SK_RLMT_PS_UP;
2158 pRPort->Net->PortsUp++;
2159 if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) {
2160 if (pAC->Rlmt.NumNets <= 1) {
2161 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
2162 }
2163 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_UP, Para);
2164 }
2165
2166 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2167 ("SK_RLMT_PORTUP_TIM Event END.\n"))
2168} /* SkRlmtEvtPortUpTim */
2169
2170
2171/******************************************************************************
2172 *
2173 * SkRlmtEvtPortDownTim - PORT_DOWN_*
2174 *
2175 * Description:
2176 * This routine handles PORT_DOWN_* events.
2177 *
2178 * Context:
2179 * runtime, pageable?
2180 * may be called after SK_INIT_IO
2181 *
2182 * Returns:
2183 * Nothing
2184 */
2185RLMT_STATIC void SkRlmtEvtPortDownX(
2186SK_AC *pAC, /* Adapter Context */
2187SK_IOC IoC, /* I/O Context */
2188SK_U32 Event, /* Event code */
2189SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */
2190{
2191 SK_RLMT_PORT *pRPort;
2192
2193 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2194 ("SK_RLMT_PORTDOWN* Port %d Event (%d) BEGIN.\n",
2195 Para.Para32[0], Event))
2196
2197 if (Para.Para32[1] != (SK_U32)-1) {
2198 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2199 ("Bad Parameter.\n"))
2200 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2201 ("SK_RLMT_PORTDOWN* Event EMPTY.\n"))
2202 return;
2203 }
2204
2205 pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
2206 if (!pRPort->PortStarted || (Event == SK_RLMT_PORTDOWN_TX_TIM &&
2207 !(pRPort->CheckingState & SK_RLMT_PCS_TX))) {
2208 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2209 ("SK_RLMT_PORTDOWN* Event (%d) EMPTY.\n", Event))
2210 return;
2211 }
2212
2213 /* Stop port's timers. */
2214 SkTimerStop(pAC, IoC, &pRPort->UpTimer);
2215 SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
2216 SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
2217
2218 if (pRPort->PortState != SK_RLMT_PS_LINK_DOWN) {
2219 pRPort->PortState = SK_RLMT_PS_DOWN;
2220 }
2221
2222 if (!pRPort->PortDown) {
2223 pRPort->Net->PortsUp--;
2224 pRPort->PortDown = SK_TRUE;
2225 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_DOWN, Para);
2226 }
2227
2228 pRPort->PacketsPerTimeSlot = 0;
2229 /* pRPort->DataPacketsPerTimeSlot = 0; */
2230 pRPort->BpduPacketsPerTimeSlot = 0;
2231 pRPort->BcTimeStamp = 0;
2232
2233 /*
2234 * RA;:;: To be checked:
2235 * - actions at RLMT_STOP: We should not switch anymore.
2236 */
2237 if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) {
2238 if (Para.Para32[0] ==
2239 pRPort->Net->Port[pRPort->Net->ActivePort]->PortNumber) {
2240 /* Active Port went down. */
2241 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
2242 }
2243 }
2244
2245 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2246 ("SK_RLMT_PORTDOWN* Event (%d) END.\n", Event))
2247} /* SkRlmtEvtPortDownX */
2248
2249
2250/******************************************************************************
2251 *
2252 * SkRlmtEvtLinkDown - LINK_DOWN
2253 *
2254 * Description:
2255 * This routine handles LINK_DOWN events.
2256 *
2257 * Context:
2258 * runtime, pageable?
2259 * may be called after SK_INIT_IO
2260 *
2261 * Returns:
2262 * Nothing
2263 */
2264RLMT_STATIC void SkRlmtEvtLinkDown(
2265SK_AC *pAC, /* Adapter Context */
2266SK_IOC IoC, /* I/O Context */
2267SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 Undefined */
2268{
2269 SK_RLMT_PORT *pRPort;
2270
2271 pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
2272 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2273 ("SK_RLMT_LINK_DOWN Port %d Event BEGIN.\n", Para.Para32[0]))
2274
2275 if (!pAC->Rlmt.Port[Para.Para32[0]].LinkDown) {
2276 pRPort->Net->LinksUp--;
2277 pRPort->LinkDown = SK_TRUE;
2278 pRPort->PortState = SK_RLMT_PS_LINK_DOWN;
2279 SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_OFF);
2280
2281 if ((pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) != 0) {
2282 /* Build the check chain. */
2283 SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
2284 }
2285
2286 /* Ensure that port is marked down. */
2287 Para.Para32[1] = -1;
2288 (void)SkRlmtEvent(pAC, IoC, SK_RLMT_PORTDOWN, Para);
2289 }
2290
2291 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2292 ("SK_RLMT_LINK_DOWN Event END.\n"))
2293} /* SkRlmtEvtLinkDown */
2294
2295
2296/******************************************************************************
2297 *
2298 * SkRlmtEvtPortAddr - PORT_ADDR
2299 *
2300 * Description:
2301 * This routine handles PORT_ADDR events.
2302 *
2303 * Context:
2304 * runtime, pageable?
2305 * may be called after SK_INIT_IO
2306 *
2307 * Returns:
2308 * Nothing
2309 */
2310RLMT_STATIC void SkRlmtEvtPortAddr(
2311SK_AC *pAC, /* Adapter Context */
2312SK_IOC IoC, /* I/O Context */
2313SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */
2314{
2315 SK_U32 i, j;
2316 SK_RLMT_PORT *pRPort;
2317 SK_MAC_ADDR *pOldMacAddr;
2318 SK_MAC_ADDR *pNewMacAddr;
2319
2320 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2321 ("SK_RLMT_PORT_ADDR Port %d Event BEGIN.\n", Para.Para32[0]))
2322
2323 if (Para.Para32[1] != (SK_U32)-1) {
2324 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2325 ("Bad Parameter.\n"))
2326 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2327 ("SK_RLMT_PORT_ADDR Event EMPTY.\n"))
2328 return;
2329 }
2330
2331 /* Port's physical MAC address changed. */
2332 pOldMacAddr = &pAC->Addr.Port[Para.Para32[0]].PreviousMacAddress;
2333 pNewMacAddr = &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress;
2334
2335 /*
2336 * NOTE: This is not scalable for solutions where ports are
2337 * checked remotely. There, we need to send an RLMT
2338 * address change packet - and how do we ensure delivery?
2339 */
2340 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
2341 pRPort = &pAC->Rlmt.Port[i];
2342 for (j = 0; j < pRPort->PortsChecked; j++) {
2343 if (SK_ADDR_EQUAL(
2344 pRPort->PortCheck[j].CheckAddr.a, pOldMacAddr->a)) {
2345 pRPort->PortCheck[j].CheckAddr = *pNewMacAddr;
2346 }
2347 }
2348 }
2349
2350 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2351 ("SK_RLMT_PORT_ADDR Event END.\n"))
2352} /* SkRlmtEvtPortAddr */
2353
2354
2355/******************************************************************************
2356 *
2357 * SkRlmtEvtStart - START
2358 *
2359 * Description:
2360 * This routine handles START events.
2361 *
2362 * Context:
2363 * runtime, pageable?
2364 * may be called after SK_INIT_IO
2365 *
2366 * Returns:
2367 * Nothing
2368 */
2369RLMT_STATIC void SkRlmtEvtStart(
2370SK_AC *pAC, /* Adapter Context */
2371SK_IOC IoC, /* I/O Context */
2372SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
2373{
2374 SK_EVPARA Para2;
2375 SK_U32 PortIdx;
2376 SK_U32 PortNumber;
2377
2378 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2379 ("SK_RLMT_START Net %d Event BEGIN.\n", Para.Para32[0]))
2380
2381 if (Para.Para32[1] != (SK_U32)-1) {
2382 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2383 ("Bad Parameter.\n"))
2384 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2385 ("SK_RLMT_START Event EMPTY.\n"))
2386 return;
2387 }
2388
2389 if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
2390 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2391 ("Bad NetNumber %d.\n", Para.Para32[0]))
2392 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2393 ("SK_RLMT_START Event EMPTY.\n"))
2394 return;
2395 }
2396
2397 if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState != SK_RLMT_RS_INIT) {
2398 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2399 ("SK_RLMT_START Event EMPTY.\n"))
2400 return;
2401 }
2402
2403 if (pAC->Rlmt.NetsStarted >= pAC->Rlmt.NumNets) {
2404 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2405 ("All nets should have been started.\n"))
2406 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2407 ("SK_RLMT_START Event EMPTY.\n"))
2408 return;
2409 }
2410
2411 if (pAC->Rlmt.Net[Para.Para32[0]].PrefPort >=
2412 pAC->Rlmt.Net[Para.Para32[0]].NumPorts) {
2413 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E009, SKERR_RLMT_E009_MSG);
2414
2415 /* Change PrefPort to internal default. */
2416 Para2.Para32[0] = 0xFFFFFFFF;
2417 Para2.Para32[1] = Para.Para32[0];
2418 (void)SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE, Para2);
2419 }
2420
2421 PortIdx = pAC->Rlmt.Net[Para.Para32[0]].PrefPort;
2422 PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[PortIdx]->PortNumber;
2423
2424 pAC->Rlmt.Net[Para.Para32[0]].LinksUp = 0;
2425 pAC->Rlmt.Net[Para.Para32[0]].PortsUp = 0;
2426 pAC->Rlmt.Net[Para.Para32[0]].CheckingState = 0;
2427 pAC->Rlmt.Net[Para.Para32[0]].RlmtState = SK_RLMT_RS_NET_DOWN;
2428
2429 /* Start preferred port. */
2430 SkRlmtPortStart(pAC, IoC, PortNumber);
2431
2432 /* Start Timer (for first port only). */
2433 Para2.Para32[0] = PortNumber;
2434 Para2.Para32[1] = (SK_U32)-1;
2435 SkTimerStart(pAC, IoC, &pAC->Rlmt.Port[PortNumber].UpTimer,
2436 SK_RLMT_PORTSTART_TIM_VAL, SKGE_RLMT, SK_RLMT_PORTSTART_TIM, Para2);
2437
2438 pAC->Rlmt.NetsStarted++;
2439
2440 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2441 ("SK_RLMT_START Event END.\n"))
2442} /* SkRlmtEvtStart */
2443
2444
2445/******************************************************************************
2446 *
2447 * SkRlmtEvtStop - STOP
2448 *
2449 * Description:
2450 * This routine handles STOP events.
2451 *
2452 * Context:
2453 * runtime, pageable?
2454 * may be called after SK_INIT_IO
2455 *
2456 * Returns:
2457 * Nothing
2458 */
2459RLMT_STATIC void SkRlmtEvtStop(
2460SK_AC *pAC, /* Adapter Context */
2461SK_IOC IoC, /* I/O Context */
2462SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
2463{
2464 SK_EVPARA Para2;
2465 SK_U32 PortNumber;
2466 SK_U32 i;
2467
2468 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2469 ("SK_RLMT_STOP Net %d Event BEGIN.\n", Para.Para32[0]))
2470
2471 if (Para.Para32[1] != (SK_U32)-1) {
2472 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2473 ("Bad Parameter.\n"))
2474 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2475 ("SK_RLMT_STOP Event EMPTY.\n"))
2476 return;
2477 }
2478
2479 if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
2480 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2481 ("Bad NetNumber %d.\n", Para.Para32[0]))
2482 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2483 ("SK_RLMT_STOP Event EMPTY.\n"))
2484 return;
2485 }
2486
2487 if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState == SK_RLMT_RS_INIT) {
2488 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2489 ("SK_RLMT_STOP Event EMPTY.\n"))
2490 return;
2491 }
2492
2493 if (pAC->Rlmt.NetsStarted == 0) {
2494 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2495 ("All nets are stopped.\n"))
2496 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2497 ("SK_RLMT_STOP Event EMPTY.\n"))
2498 return;
2499 }
2500
2501 /* Stop RLMT timers. */
2502 SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer);
2503 SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].SegTimer);
2504
2505 /* Stop net. */
2506 pAC->Rlmt.Net[Para.Para32[0]].RlmtState = SK_RLMT_RS_INIT;
2507 pAC->Rlmt.Net[Para.Para32[0]].RootIdSet = SK_FALSE;
2508 Para2.Para32[0] = SK_RLMT_NET_DOWN_FINAL;
2509 Para2.Para32[1] = Para.Para32[0]; /* Net# */
2510 SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para2);
2511
2512 /* Stop ports. */
2513 for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
2514 PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber;
2515 if (pAC->Rlmt.Port[PortNumber].PortState != SK_RLMT_PS_INIT) {
2516 SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].UpTimer);
2517 SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].DownRxTimer);
2518 SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].DownTxTimer);
2519
2520 pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_INIT;
2521 pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE;
2522 pAC->Rlmt.Port[PortNumber].PortStarted = SK_FALSE;
2523 Para2.Para32[0] = PortNumber;
2524 Para2.Para32[1] = (SK_U32)-1;
2525 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para2);
2526 }
2527 }
2528
2529 pAC->Rlmt.NetsStarted--;
2530
2531 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2532 ("SK_RLMT_STOP Event END.\n"))
2533} /* SkRlmtEvtStop */
2534
2535
2536/******************************************************************************
2537 *
2538 * SkRlmtEvtTim - TIM
2539 *
2540 * Description:
2541 * This routine handles TIM events.
2542 *
2543 * Context:
2544 * runtime, pageable?
2545 * may be called after SK_INIT_IO
2546 *
2547 * Returns:
2548 * Nothing
2549 */
2550RLMT_STATIC void SkRlmtEvtTim(
2551SK_AC *pAC, /* Adapter Context */
2552SK_IOC IoC, /* I/O Context */
2553SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
2554{
2555 SK_RLMT_PORT *pRPort;
2556 SK_U32 Timeout;
2557 SK_U32 NewTimeout;
2558 SK_U32 PortNumber;
2559 SK_U32 i;
2560
2561 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2562 ("SK_RLMT_TIM Event BEGIN.\n"))
2563
2564 if (Para.Para32[1] != (SK_U32)-1) {
2565 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2566 ("Bad Parameter.\n"))
2567 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2568 ("SK_RLMT_TIM Event EMPTY.\n"))
2569 return;
2570 }
2571
2572 if ((pAC->Rlmt.Net[Para.Para32[0]].RlmtMode & SK_RLMT_CHECK_OTHERS) == 0 ||
2573 pAC->Rlmt.Net[Para.Para32[0]].LinksUp == 0) {
2574 /* Mode changed or all links down: No more link checking. */
2575 return;
2576 }
2577
2578#if 0
2579 pAC->Rlmt.SwitchCheckCounter--;
2580 if (pAC->Rlmt.SwitchCheckCounter == 0) {
2581 pAC->Rlmt.SwitchCheckCounter;
2582 }
2583#endif /* 0 */
2584
2585 NewTimeout = SK_RLMT_DEF_TO_VAL;
2586 for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
2587 PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber;
2588 pRPort = &pAC->Rlmt.Port[PortNumber];
2589 if (!pRPort->LinkDown) {
2590 Timeout = SkRlmtCheckPort(pAC, IoC, PortNumber);
2591 if (Timeout < NewTimeout) {
2592 NewTimeout = Timeout;
2593 }
2594
2595 /*
2596 * These counters should be set to 0 for all ports before the
2597 * first frame is sent in the next loop.
2598 */
2599 pRPort->PacketsPerTimeSlot = 0;
2600 /* pRPort->DataPacketsPerTimeSlot = 0; */
2601 pRPort->BpduPacketsPerTimeSlot = 0;
2602 }
2603 }
2604 pAC->Rlmt.Net[Para.Para32[0]].TimeoutValue = NewTimeout;
2605
2606 if (pAC->Rlmt.Net[Para.Para32[0]].LinksUp > 1) {
2607 /*
2608 * If checking remote ports, also send packets if
2609 * (LinksUp == 1) &&
2610 * this port checks at least one (remote) port.
2611 */
2612
2613 /*
2614 * Must be new loop, as SkRlmtCheckPort can request to
2615 * check segmentation when e.g. checking the last port.
2616 */
2617 for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
2618 if (!pAC->Rlmt.Net[Para.Para32[0]].Port[i]->LinkDown) {
2619 SkRlmtSend(pAC, IoC,
2620 pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber);
2621 }
2622 }
2623 }
2624
2625 SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer,
2626 pAC->Rlmt.Net[Para.Para32[0]].TimeoutValue, SKGE_RLMT, SK_RLMT_TIM,
2627 Para);
2628
2629 if (pAC->Rlmt.Net[Para.Para32[0]].LinksUp > 1 &&
2630 (pAC->Rlmt.Net[Para.Para32[0]].RlmtMode & SK_RLMT_CHECK_SEG) &&
2631 (pAC->Rlmt.Net[Para.Para32[0]].CheckingState & SK_RLMT_RCS_START_SEG)) {
2632 SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].SegTimer,
2633 SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
2634 pAC->Rlmt.Net[Para.Para32[0]].CheckingState &= ~SK_RLMT_RCS_START_SEG;
2635 pAC->Rlmt.Net[Para.Para32[0]].CheckingState |=
2636 SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG;
2637 }
2638
2639 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2640 ("SK_RLMT_TIM Event END.\n"))
2641} /* SkRlmtEvtTim */
2642
2643
2644/******************************************************************************
2645 *
2646 * SkRlmtEvtSegTim - SEG_TIM
2647 *
2648 * Description:
2649 * This routine handles SEG_TIM events.
2650 *
2651 * Context:
2652 * runtime, pageable?
2653 * may be called after SK_INIT_IO
2654 *
2655 * Returns:
2656 * Nothing
2657 */
2658RLMT_STATIC void SkRlmtEvtSegTim(
2659SK_AC *pAC, /* Adapter Context */
2660SK_IOC IoC, /* I/O Context */
2661SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
2662{
2663#ifdef xDEBUG
2664 int j;
2665#endif /* DEBUG */
2666
2667 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2668 ("SK_RLMT_SEG_TIM Event BEGIN.\n"))
2669
2670 if (Para.Para32[1] != (SK_U32)-1) {
2671 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2672 ("Bad Parameter.\n"))
2673 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2674 ("SK_RLMT_SEG_TIM Event EMPTY.\n"))
2675 return;
2676 }
2677
2678#ifdef xDEBUG
2679 for (j = 0; j < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; j++) {
2680 SK_ADDR_PORT *pAPort;
2681 SK_U32 k;
2682 SK_U16 *InAddr;
2683 SK_U8 InAddr8[6];
2684
2685 InAddr = (SK_U16 *)&InAddr8[0];
2686 pAPort = pAC->Rlmt.Net[Para.Para32[0]].Port[j]->AddrPort;
2687 for (k = 0; k < pAPort->NextExactMatchRlmt; k++) {
2688 /* Get exact match address k from port j. */
2689 XM_INADDR(IoC, pAC->Rlmt.Net[Para.Para32[0]].Port[j]->PortNumber,
2690 XM_EXM(k), InAddr);
2691 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2692 ("MC address %d on Port %u: %02x %02x %02x %02x %02x %02x -- %02x %02x %02x %02x %02x %02x.\n",
2693 k, pAC->Rlmt.Net[Para.Para32[0]].Port[j]->PortNumber,
2694 InAddr8[0], InAddr8[1], InAddr8[2],
2695 InAddr8[3], InAddr8[4], InAddr8[5],
2696 pAPort->Exact[k].a[0], pAPort->Exact[k].a[1],
2697 pAPort->Exact[k].a[2], pAPort->Exact[k].a[3],
2698 pAPort->Exact[k].a[4], pAPort->Exact[k].a[5]))
2699 }
2700 }
2701#endif /* xDEBUG */
2702
2703 SkRlmtCheckSeg(pAC, IoC, Para.Para32[0]);
2704
2705 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2706 ("SK_RLMT_SEG_TIM Event END.\n"))
2707} /* SkRlmtEvtSegTim */
2708
2709
2710/******************************************************************************
2711 *
2712 * SkRlmtEvtPacketRx - PACKET_RECEIVED
2713 *
2714 * Description:
2715 * This routine handles PACKET_RECEIVED events.
2716 *
2717 * Context:
2718 * runtime, pageable?
2719 * may be called after SK_INIT_IO
2720 *
2721 * Returns:
2722 * Nothing
2723 */
2724RLMT_STATIC void SkRlmtEvtPacketRx(
2725SK_AC *pAC, /* Adapter Context */
2726SK_IOC IoC, /* I/O Context */
2727SK_EVPARA Para) /* SK_MBUF *pMb */
2728{
2729 SK_MBUF *pMb;
2730 SK_MBUF *pNextMb;
2731 SK_U32 NetNumber;
2732
2733
2734 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2735 ("SK_RLMT_PACKET_RECEIVED Event BEGIN.\n"))
2736
2737 /* Should we ignore frames during port switching? */
2738
2739#ifdef DEBUG
2740 pMb = Para.pParaPtr;
2741 if (pMb == NULL) {
2742 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("No mbuf.\n"))
2743 }
2744 else if (pMb->pNext != NULL) {
2745 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2746 ("More than one mbuf or pMb->pNext not set.\n"))
2747 }
2748#endif /* DEBUG */
2749
2750 for (pMb = Para.pParaPtr; pMb != NULL; pMb = pNextMb) {
2751 pNextMb = pMb->pNext;
2752 pMb->pNext = NULL;
2753
2754 NetNumber = pAC->Rlmt.Port[pMb->PortIdx].Net->NetNumber;
2755 if (pAC->Rlmt.Net[NetNumber].RlmtState == SK_RLMT_RS_INIT) {
2756 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
2757 }
2758 else {
2759 SkRlmtPacketReceive(pAC, IoC, pMb);
2760 }
2761 }
2762
2763 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2764 ("SK_RLMT_PACKET_RECEIVED Event END.\n"))
2765} /* SkRlmtEvtPacketRx */
2766
2767
2768/******************************************************************************
2769 *
2770 * SkRlmtEvtStatsClear - STATS_CLEAR
2771 *
2772 * Description:
2773 * This routine handles STATS_CLEAR events.
2774 *
2775 * Context:
2776 * runtime, pageable?
2777 * may be called after SK_INIT_IO
2778 *
2779 * Returns:
2780 * Nothing
2781 */
2782RLMT_STATIC void SkRlmtEvtStatsClear(
2783SK_AC *pAC, /* Adapter Context */
2784SK_IOC IoC, /* I/O Context */
2785SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
2786{
2787 SK_U32 i;
2788 SK_RLMT_PORT *pRPort;
2789
2790 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2791 ("SK_RLMT_STATS_CLEAR Event BEGIN.\n"))
2792
2793 if (Para.Para32[1] != (SK_U32)-1) {
2794 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2795 ("Bad Parameter.\n"))
2796 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2797 ("SK_RLMT_STATS_CLEAR Event EMPTY.\n"))
2798 return;
2799 }
2800
2801 if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
2802 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2803 ("Bad NetNumber %d.\n", Para.Para32[0]))
2804 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2805 ("SK_RLMT_STATS_CLEAR Event EMPTY.\n"))
2806 return;
2807 }
2808
2809 /* Clear statistics for logical and physical ports. */
2810 for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
2811 pRPort =
2812 &pAC->Rlmt.Port[pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber];
2813 pRPort->TxHelloCts = 0;
2814 pRPort->RxHelloCts = 0;
2815 pRPort->TxSpHelloReqCts = 0;
2816 pRPort->RxSpHelloCts = 0;
2817 }
2818
2819 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2820 ("SK_RLMT_STATS_CLEAR Event END.\n"))
2821} /* SkRlmtEvtStatsClear */
2822
2823
2824/******************************************************************************
2825 *
2826 * SkRlmtEvtStatsUpdate - STATS_UPDATE
2827 *
2828 * Description:
2829 * This routine handles STATS_UPDATE events.
2830 *
2831 * Context:
2832 * runtime, pageable?
2833 * may be called after SK_INIT_IO
2834 *
2835 * Returns:
2836 * Nothing
2837 */
2838RLMT_STATIC void SkRlmtEvtStatsUpdate(
2839SK_AC *pAC, /* Adapter Context */
2840SK_IOC IoC, /* I/O Context */
2841SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
2842{
2843 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2844 ("SK_RLMT_STATS_UPDATE Event BEGIN.\n"))
2845
2846 if (Para.Para32[1] != (SK_U32)-1) {
2847 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2848 ("Bad Parameter.\n"))
2849 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2850 ("SK_RLMT_STATS_UPDATE Event EMPTY.\n"))
2851 return;
2852 }
2853
2854 if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
2855 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2856 ("Bad NetNumber %d.\n", Para.Para32[0]))
2857 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2858 ("SK_RLMT_STATS_UPDATE Event EMPTY.\n"))
2859 return;
2860 }
2861
2862 /* Update statistics - currently always up-to-date. */
2863
2864 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2865 ("SK_RLMT_STATS_UPDATE Event END.\n"))
2866} /* SkRlmtEvtStatsUpdate */
2867
2868
2869/******************************************************************************
2870 *
2871 * SkRlmtEvtPrefportChange - PREFPORT_CHANGE
2872 *
2873 * Description:
2874 * This routine handles PREFPORT_CHANGE events.
2875 *
2876 * Context:
2877 * runtime, pageable?
2878 * may be called after SK_INIT_IO
2879 *
2880 * Returns:
2881 * Nothing
2882 */
2883RLMT_STATIC void SkRlmtEvtPrefportChange(
2884SK_AC *pAC, /* Adapter Context */
2885SK_IOC IoC, /* I/O Context */
2886SK_EVPARA Para) /* SK_U32 PortIndex; SK_U32 NetNumber */
2887{
2888 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2889 ("SK_RLMT_PREFPORT_CHANGE to Port %d Event BEGIN.\n", Para.Para32[0]))
2890
2891 if (Para.Para32[1] >= pAC->Rlmt.NumNets) {
2892 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2893 ("Bad NetNumber %d.\n", Para.Para32[1]))
2894 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2895 ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"))
2896 return;
2897 }
2898
2899 /* 0xFFFFFFFF == auto-mode. */
2900 if (Para.Para32[0] == 0xFFFFFFFF) {
2901 pAC->Rlmt.Net[Para.Para32[1]].PrefPort = SK_RLMT_DEF_PREF_PORT;
2902 }
2903 else {
2904 if (Para.Para32[0] >= pAC->Rlmt.Net[Para.Para32[1]].NumPorts) {
2905 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E010, SKERR_RLMT_E010_MSG);
2906
2907 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2908 ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"))
2909 return;
2910 }
2911
2912 pAC->Rlmt.Net[Para.Para32[1]].PrefPort = Para.Para32[0];
2913 }
2914
2915 pAC->Rlmt.Net[Para.Para32[1]].Preference = Para.Para32[0];
2916
2917 if (pAC->Rlmt.Net[Para.Para32[1]].RlmtState != SK_RLMT_RS_INIT) {
2918 SkRlmtCheckSwitch(pAC, IoC, Para.Para32[1]);
2919 }
2920
2921 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2922 ("SK_RLMT_PREFPORT_CHANGE Event END.\n"))
2923} /* SkRlmtEvtPrefportChange */
2924
2925
2926/******************************************************************************
2927 *
2928 * SkRlmtEvtSetNets - SET_NETS
2929 *
2930 * Description:
2931 * This routine handles SET_NETS events.
2932 *
2933 * Context:
2934 * runtime, pageable?
2935 * may be called after SK_INIT_IO
2936 *
2937 * Returns:
2938 * Nothing
2939 */
2940RLMT_STATIC void SkRlmtEvtSetNets(
2941SK_AC *pAC, /* Adapter Context */
2942SK_IOC IoC, /* I/O Context */
2943SK_EVPARA Para) /* SK_U32 NumNets; SK_U32 -1 */
2944{
2945 int i;
2946
2947 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2948 ("SK_RLMT_SET_NETS Event BEGIN.\n"))
2949
2950 if (Para.Para32[1] != (SK_U32)-1) {
2951 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2952 ("Bad Parameter.\n"))
2953 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2954 ("SK_RLMT_SET_NETS Event EMPTY.\n"))
2955 return;
2956 }
2957
2958 if (Para.Para32[0] == 0 || Para.Para32[0] > SK_MAX_NETS ||
2959 Para.Para32[0] > (SK_U32)pAC->GIni.GIMacsFound) {
2960 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2961 ("Bad number of nets: %d.\n", Para.Para32[0]))
2962 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2963 ("SK_RLMT_SET_NETS Event EMPTY.\n"))
2964 return;
2965 }
2966
2967 if (Para.Para32[0] == pAC->Rlmt.NumNets) { /* No change. */
2968 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2969 ("SK_RLMT_SET_NETS Event EMPTY.\n"))
2970 return;
2971 }
2972
2973 /* Entering and leaving dual mode only allowed while nets are stopped. */
2974 if (pAC->Rlmt.NetsStarted > 0) {
2975 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2976 ("Changing dual mode only allowed while all nets are stopped.\n"))
2977 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2978 ("SK_RLMT_SET_NETS Event EMPTY.\n"))
2979 return;
2980 }
2981
2982 if (Para.Para32[0] == 1) {
2983 if (pAC->Rlmt.NumNets > 1) {
2984 /* Clear logical MAC addr from second net's active port. */
2985 (void)SkAddrOverride(pAC, IoC, pAC->Rlmt.Net[1].Port[pAC->Addr.
2986 Net[1].ActivePort]->PortNumber, NULL, SK_ADDR_CLEAR_LOGICAL);
2987 pAC->Rlmt.Net[1].NumPorts = 0;
2988 }
2989
2990 pAC->Rlmt.NumNets = Para.Para32[0];
2991 for (i = 0; (SK_U32)i < pAC->Rlmt.NumNets; i++) {
2992 pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
2993 pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
2994 pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF; /* "Automatic" */
2995 pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
2996 /* Just assuming. */
2997 pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
2998 pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
2999 pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
3000 pAC->Rlmt.Net[i].NetNumber = i;
3001 }
3002
3003 pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[0];
3004 pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound;
3005
3006 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para);
3007
3008 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3009 ("RLMT: Changed to one net with two ports.\n"))
3010 }
3011 else if (Para.Para32[0] == 2) {
3012 pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[1];
3013 pAC->Rlmt.Net[1].NumPorts = pAC->GIni.GIMacsFound - 1;
3014 pAC->Rlmt.Net[0].NumPorts =
3015 pAC->GIni.GIMacsFound - pAC->Rlmt.Net[1].NumPorts;
3016
3017 pAC->Rlmt.NumNets = Para.Para32[0];
3018 for (i = 0; (SK_U32)i < pAC->Rlmt.NumNets; i++) {
3019 pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
3020 pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
3021 pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF; /* "Automatic" */
3022 pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
3023 /* Just assuming. */
3024 pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
3025 pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
3026 pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
3027
3028 pAC->Rlmt.Net[i].NetNumber = i;
3029 }
3030
3031 /* Set logical MAC addr on second net's active port. */
3032 (void)SkAddrOverride(pAC, IoC, pAC->Rlmt.Net[1].Port[pAC->Addr.
3033 Net[1].ActivePort]->PortNumber, NULL, SK_ADDR_SET_LOGICAL);
3034
3035 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para);
3036
3037 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3038 ("RLMT: Changed to two nets with one port each.\n"))
3039 }
3040 else {
3041 /* Not implemented for more than two nets. */
3042 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3043 ("SetNets not implemented for more than two nets.\n"))
3044 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3045 ("SK_RLMT_SET_NETS Event EMPTY.\n"))
3046 return;
3047 }
3048
3049 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3050 ("SK_RLMT_SET_NETS Event END.\n"))
3051} /* SkRlmtSetNets */
3052
3053
3054/******************************************************************************
3055 *
3056 * SkRlmtEvtModeChange - MODE_CHANGE
3057 *
3058 * Description:
3059 * This routine handles MODE_CHANGE events.
3060 *
3061 * Context:
3062 * runtime, pageable?
3063 * may be called after SK_INIT_IO
3064 *
3065 * Returns:
3066 * Nothing
3067 */
3068RLMT_STATIC void SkRlmtEvtModeChange(
3069SK_AC *pAC, /* Adapter Context */
3070SK_IOC IoC, /* I/O Context */
3071SK_EVPARA Para) /* SK_U32 NewMode; SK_U32 NetNumber */
3072{
3073 SK_EVPARA Para2;
3074 SK_U32 i;
3075 SK_U32 PrevRlmtMode;
3076
3077 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3078 ("SK_RLMT_MODE_CHANGE Event BEGIN.\n"))
3079
3080 if (Para.Para32[1] >= pAC->Rlmt.NumNets) {
3081 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3082 ("Bad NetNumber %d.\n", Para.Para32[1]))
3083 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3084 ("SK_RLMT_MODE_CHANGE Event EMPTY.\n"))
3085 return;
3086 }
3087
3088 Para.Para32[0] |= SK_RLMT_CHECK_LINK;
3089
3090 if ((pAC->Rlmt.Net[Para.Para32[1]].NumPorts == 1) &&
3091 Para.Para32[0] != SK_RLMT_MODE_CLS) {
3092 pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = SK_RLMT_MODE_CLS;
3093 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3094 ("Forced RLMT mode to CLS on single port net.\n"))
3095 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3096 ("SK_RLMT_MODE_CHANGE Event EMPTY.\n"))
3097 return;
3098 }
3099
3100 /* Update RLMT mode. */
3101 PrevRlmtMode = pAC->Rlmt.Net[Para.Para32[1]].RlmtMode;
3102 pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = Para.Para32[0];
3103
3104 if ((PrevRlmtMode & SK_RLMT_CHECK_LOC_LINK) !=
3105 (pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) {
3106 /* SK_RLMT_CHECK_LOC_LINK bit changed. */
3107 if ((PrevRlmtMode & SK_RLMT_CHECK_OTHERS) == 0 &&
3108 pAC->Rlmt.Net[Para.Para32[1]].NumPorts > 1 &&
3109 pAC->Rlmt.Net[Para.Para32[1]].PortsUp >= 1) {
3110 /* 20001207 RA: Was "PortsUp == 1". */
3111 Para2.Para32[0] = Para.Para32[1];
3112 Para2.Para32[1] = (SK_U32)-1;
3113 SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[1]].LocTimer,
3114 pAC->Rlmt.Net[Para.Para32[1]].TimeoutValue,
3115 SKGE_RLMT, SK_RLMT_TIM, Para2);
3116 }
3117 }
3118
3119 if ((PrevRlmtMode & SK_RLMT_CHECK_SEG) !=
3120 (pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_SEG)) {
3121 /* SK_RLMT_CHECK_SEG bit changed. */
3122 for (i = 0; i < pAC->Rlmt.Net[Para.Para32[1]].NumPorts; i++) {
3123 (void)SkAddrMcClear(pAC, IoC,
3124 pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
3125 SK_ADDR_PERMANENT | SK_MC_SW_ONLY);
3126
3127 /* Add RLMT MC address. */
3128 (void)SkAddrMcAdd(pAC, IoC,
3129 pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
3130 &SkRlmtMcAddr, SK_ADDR_PERMANENT);
3131
3132 if ((pAC->Rlmt.Net[Para.Para32[1]].RlmtMode &
3133 SK_RLMT_CHECK_SEG) != 0) {
3134 /* Add BPDU MC address. */
3135 (void)SkAddrMcAdd(pAC, IoC,
3136 pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
3137 &BridgeMcAddr, SK_ADDR_PERMANENT);
3138
3139 if (pAC->Rlmt.Net[Para.Para32[1]].RlmtState != SK_RLMT_RS_INIT) {
3140 if (!pAC->Rlmt.Net[Para.Para32[1]].Port[i]->LinkDown &&
3141 (Para2.pParaPtr = SkRlmtBuildSpanningTreePacket(
3142 pAC, IoC, i)) != NULL) {
3143 pAC->Rlmt.Net[Para.Para32[1]].Port[i]->RootIdSet =
3144 SK_FALSE;
3145 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
3146 }
3147 }
3148 }
3149 (void)SkAddrMcUpdate(pAC, IoC,
3150 pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber);
3151 } /* for ... */
3152
3153 if ((pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_SEG) != 0) {
3154 Para2.Para32[0] = Para.Para32[1];
3155 Para2.Para32[1] = (SK_U32)-1;
3156 SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[1]].SegTimer,
3157 SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para2);
3158 }
3159 } /* SK_RLMT_CHECK_SEG bit changed. */
3160
3161 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3162 ("SK_RLMT_MODE_CHANGE Event END.\n"))
3163} /* SkRlmtEvtModeChange */
3164
3165
3166/******************************************************************************
3167 *
3168 * SkRlmtEvent - a PORT- or an RLMT-specific event happened
3169 *
3170 * Description:
3171 * This routine calls subroutines to handle PORT- and RLMT-specific events.
3172 *
3173 * Context:
3174 * runtime, pageable?
3175 * may be called after SK_INIT_IO
3176 *
3177 * Returns:
3178 * 0
3179 */
3180int SkRlmtEvent(
3181SK_AC *pAC, /* Adapter Context */
3182SK_IOC IoC, /* I/O Context */
3183SK_U32 Event, /* Event code */
3184SK_EVPARA Para) /* Event-specific parameter */
3185{
3186 switch (Event) {
3187
3188 /* ----- PORT events ----- */
3189
3190 case SK_RLMT_PORTSTART_TIM: /* From RLMT via TIME. */
3191 SkRlmtEvtPortStartTim(pAC, IoC, Para);
3192 break;
3193 case SK_RLMT_LINK_UP: /* From SIRQ. */
3194 SkRlmtEvtLinkUp(pAC, IoC, Para);
3195 break;
3196 case SK_RLMT_PORTUP_TIM: /* From RLMT via TIME. */
3197 SkRlmtEvtPortUpTim(pAC, IoC, Para);
3198 break;
3199 case SK_RLMT_PORTDOWN: /* From RLMT. */
3200 case SK_RLMT_PORTDOWN_RX_TIM: /* From RLMT via TIME. */
3201 case SK_RLMT_PORTDOWN_TX_TIM: /* From RLMT via TIME. */
3202 SkRlmtEvtPortDownX(pAC, IoC, Event, Para);
3203 break;
3204 case SK_RLMT_LINK_DOWN: /* From SIRQ. */
3205 SkRlmtEvtLinkDown(pAC, IoC, Para);
3206 break;
3207 case SK_RLMT_PORT_ADDR: /* From ADDR. */
3208 SkRlmtEvtPortAddr(pAC, IoC, Para);
3209 break;
3210
3211 /* ----- RLMT events ----- */
3212
3213 case SK_RLMT_START: /* From DRV. */
3214 SkRlmtEvtStart(pAC, IoC, Para);
3215 break;
3216 case SK_RLMT_STOP: /* From DRV. */
3217 SkRlmtEvtStop(pAC, IoC, Para);
3218 break;
3219 case SK_RLMT_TIM: /* From RLMT via TIME. */
3220 SkRlmtEvtTim(pAC, IoC, Para);
3221 break;
3222 case SK_RLMT_SEG_TIM:
3223 SkRlmtEvtSegTim(pAC, IoC, Para);
3224 break;
3225 case SK_RLMT_PACKET_RECEIVED: /* From DRV. */
3226 SkRlmtEvtPacketRx(pAC, IoC, Para);
3227 break;
3228 case SK_RLMT_STATS_CLEAR: /* From PNMI. */
3229 SkRlmtEvtStatsClear(pAC, IoC, Para);
3230 break;
3231 case SK_RLMT_STATS_UPDATE: /* From PNMI. */
3232 SkRlmtEvtStatsUpdate(pAC, IoC, Para);
3233 break;
3234 case SK_RLMT_PREFPORT_CHANGE: /* From PNMI. */
3235 SkRlmtEvtPrefportChange(pAC, IoC, Para);
3236 break;
3237 case SK_RLMT_MODE_CHANGE: /* From PNMI. */
3238 SkRlmtEvtModeChange(pAC, IoC, Para);
3239 break;
3240 case SK_RLMT_SET_NETS: /* From DRV. */
3241 SkRlmtEvtSetNets(pAC, IoC, Para);
3242 break;
3243
3244 /* ----- Unknown events ----- */
3245
3246 default: /* Create error log entry. */
3247 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3248 ("Unknown RLMT Event %d.\n", Event))
3249 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E003, SKERR_RLMT_E003_MSG);
3250 break;
3251 } /* switch() */
3252
3253 return (0);
3254} /* SkRlmtEvent */
3255
3256#ifdef __cplusplus
3257}
3258#endif /* __cplusplus */
diff --git a/drivers/net/sk98lin/sktimer.c b/drivers/net/sk98lin/sktimer.c
new file mode 100644
index 000000000000..4e462955ecd8
--- /dev/null
+++ b/drivers/net/sk98lin/sktimer.c
@@ -0,0 +1,250 @@
1/******************************************************************************
2 *
3 * Name: sktimer.c
4 * Project: Gigabit Ethernet Adapters, Event Scheduler Module
5 * Version: $Revision: 1.14 $
6 * Date: $Date: 2003/09/16 13:46:51 $
7 * Purpose: High level timer functions.
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25
26/*
27 * Event queue and dispatcher
28 */
29#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
30static const char SysKonnectFileId[] =
31 "@(#) $Id: sktimer.c,v 1.14 2003/09/16 13:46:51 rschmidt Exp $ (C) Marvell.";
32#endif
33
34#include "h/skdrv1st.h" /* Driver Specific Definitions */
35#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
36
37#ifdef __C2MAN__
38/*
39 Event queue management.
40
41 General Description:
42
43 */
44intro()
45{}
46#endif
47
48
49/* Forward declaration */
50static void timer_done(SK_AC *pAC,SK_IOC Ioc,int Restart);
51
52
53/*
54 * Inits the software timer
55 *
56 * needs to be called during Init level 1.
57 */
58void SkTimerInit(
59SK_AC *pAC, /* Adapters context */
60SK_IOC Ioc, /* IoContext */
61int Level) /* Init Level */
62{
63 switch (Level) {
64 case SK_INIT_DATA:
65 pAC->Tim.StQueue = NULL;
66 break;
67 case SK_INIT_IO:
68 SkHwtInit(pAC, Ioc);
69 SkTimerDone(pAC, Ioc);
70 break;
71 default:
72 break;
73 }
74}
75
76/*
77 * Stops a high level timer
78 * - If a timer is not in the queue the function returns normally, too.
79 */
80void SkTimerStop(
81SK_AC *pAC, /* Adapters context */
82SK_IOC Ioc, /* IoContext */
83SK_TIMER *pTimer) /* Timer Pointer to be started */
84{
85 SK_TIMER **ppTimPrev;
86 SK_TIMER *pTm;
87
88 /*
89 * remove timer from queue
90 */
91 pTimer->TmActive = SK_FALSE;
92
93 if (pAC->Tim.StQueue == pTimer && !pTimer->TmNext) {
94 SkHwtStop(pAC, Ioc);
95 }
96
97 for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev);
98 ppTimPrev = &pTm->TmNext ) {
99
100 if (pTm == pTimer) {
101 /*
102 * Timer found in queue
103 * - dequeue it and
104 * - correct delta of the next timer
105 */
106 *ppTimPrev = pTm->TmNext;
107
108 if (pTm->TmNext) {
109 /* correct delta of next timer in queue */
110 pTm->TmNext->TmDelta += pTm->TmDelta;
111 }
112 return;
113 }
114 }
115}
116
117/*
118 * Start a high level software timer
119 */
120void SkTimerStart(
121SK_AC *pAC, /* Adapters context */
122SK_IOC Ioc, /* IoContext */
123SK_TIMER *pTimer, /* Timer Pointer to be started */
124SK_U32 Time, /* Time value */
125SK_U32 Class, /* Event Class for this timer */
126SK_U32 Event, /* Event Value for this timer */
127SK_EVPARA Para) /* Event Parameter for this timer */
128{
129 SK_TIMER **ppTimPrev;
130 SK_TIMER *pTm;
131 SK_U32 Delta;
132
133 Time /= 16; /* input is uS, clock ticks are 16uS */
134
135 if (!Time)
136 Time = 1;
137
138 SkTimerStop(pAC, Ioc, pTimer);
139
140 pTimer->TmClass = Class;
141 pTimer->TmEvent = Event;
142 pTimer->TmPara = Para;
143 pTimer->TmActive = SK_TRUE;
144
145 if (!pAC->Tim.StQueue) {
146 /* First Timer to be started */
147 pAC->Tim.StQueue = pTimer;
148 pTimer->TmNext = NULL;
149 pTimer->TmDelta = Time;
150
151 SkHwtStart(pAC, Ioc, Time);
152
153 return;
154 }
155
156 /*
157 * timer correction
158 */
159 timer_done(pAC, Ioc, 0);
160
161 /*
162 * find position in queue
163 */
164 Delta = 0;
165 for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev);
166 ppTimPrev = &pTm->TmNext ) {
167
168 if (Delta + pTm->TmDelta > Time) {
169 /* Position found */
170 /* Here the timer needs to be inserted. */
171 break;
172 }
173 Delta += pTm->TmDelta;
174 }
175
176 /* insert in queue */
177 *ppTimPrev = pTimer;
178 pTimer->TmNext = pTm;
179 pTimer->TmDelta = Time - Delta;
180
181 if (pTm) {
182 /* There is a next timer
183 * -> correct its Delta value.
184 */
185 pTm->TmDelta -= pTimer->TmDelta;
186 }
187
188 /* restart with first */
189 SkHwtStart(pAC, Ioc, pAC->Tim.StQueue->TmDelta);
190}
191
192
193void SkTimerDone(
194SK_AC *pAC, /* Adapters context */
195SK_IOC Ioc) /* IoContext */
196{
197 timer_done(pAC, Ioc, 1);
198}
199
200
201static void timer_done(
202SK_AC *pAC, /* Adapters context */
203SK_IOC Ioc, /* IoContext */
204int Restart) /* Do we need to restart the Hardware timer ? */
205{
206 SK_U32 Delta;
207 SK_TIMER *pTm;
208 SK_TIMER *pTComp; /* Timer completed now now */
209 SK_TIMER **ppLast; /* Next field of Last timer to be deq */
210 int Done = 0;
211
212 Delta = SkHwtRead(pAC, Ioc);
213
214 ppLast = &pAC->Tim.StQueue;
215 pTm = pAC->Tim.StQueue;
216 while (pTm && !Done) {
217 if (Delta >= pTm->TmDelta) {
218 /* Timer ran out */
219 pTm->TmActive = SK_FALSE;
220 Delta -= pTm->TmDelta;
221 ppLast = &pTm->TmNext;
222 pTm = pTm->TmNext;
223 }
224 else {
225 /* We found the first timer that did not run out */
226 pTm->TmDelta -= Delta;
227 Delta = 0;
228 Done = 1;
229 }
230 }
231 *ppLast = NULL;
232 /*
233 * pTm points to the first Timer that did not run out.
234 * StQueue points to the first Timer that run out.
235 */
236
237 for ( pTComp = pAC->Tim.StQueue; pTComp; pTComp = pTComp->TmNext) {
238 SkEventQueue(pAC,pTComp->TmClass, pTComp->TmEvent, pTComp->TmPara);
239 }
240
241 /* Set head of timer queue to the first timer that did not run out */
242 pAC->Tim.StQueue = pTm;
243
244 if (Restart && pAC->Tim.StQueue) {
245 /* Restart HW timer */
246 SkHwtStart(pAC, Ioc, pAC->Tim.StQueue->TmDelta);
247 }
248}
249
250/* End of file */
diff --git a/drivers/net/sk98lin/skvpd.c b/drivers/net/sk98lin/skvpd.c
new file mode 100644
index 000000000000..eb3c8988ced1
--- /dev/null
+++ b/drivers/net/sk98lin/skvpd.c
@@ -0,0 +1,1197 @@
1/******************************************************************************
2 *
3 * Name: skvpd.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.37 $
6 * Date: $Date: 2003/01/13 10:42:45 $
7 * Purpose: Shared software to read and write VPD data
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2003 SysKonnect GmbH.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * The information in this file is provided "AS IS" without warranty.
21 *
22 ******************************************************************************/
23
24/*
25 Please refer skvpd.txt for infomation how to include this module
26 */
27static const char SysKonnectFileId[] =
28 "@(#)$Id: skvpd.c,v 1.37 2003/01/13 10:42:45 rschmidt Exp $ (C) SK";
29
30#include "h/skdrv1st.h"
31#include "h/sktypes.h"
32#include "h/skdebug.h"
33#include "h/skdrv2nd.h"
34
35/*
36 * Static functions
37 */
38#ifndef SK_KR_PROTO
39static SK_VPD_PARA *vpd_find_para(
40 SK_AC *pAC,
41 const char *key,
42 SK_VPD_PARA *p);
43#else /* SK_KR_PROTO */
44static SK_VPD_PARA *vpd_find_para();
45#endif /* SK_KR_PROTO */
46
47/*
48 * waits for a completion of a VPD transfer
49 * The VPD transfer must complete within SK_TICKS_PER_SEC/16
50 *
51 * returns 0: success, transfer completes
52 * error exit(9) with a error message
53 */
54static int VpdWait(
55SK_AC *pAC, /* Adapters context */
56SK_IOC IoC, /* IO Context */
57int event) /* event to wait for (VPD_READ / VPD_write) completion*/
58{
59 SK_U64 start_time;
60 SK_U16 state;
61
62 SK_DBG_MSG(pAC,SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
63 ("VPD wait for %s\n", event?"Write":"Read"));
64 start_time = SkOsGetTime(pAC);
65 do {
66 if (SkOsGetTime(pAC) - start_time > SK_TICKS_PER_SEC) {
67
68 /* Bug fix AF: Thu Mar 28 2002
69 * Do not call: VPD_STOP(pAC, IoC);
70 * A pending VPD read cycle can not be aborted by writing
71 * VPD_WRITE to the PCI_VPD_ADR_REG (VPD address register).
72 * Although the write threshold in the OUR-register protects
73 * VPD read only space from being overwritten this does not
74 * protect a VPD read from being `converted` into a VPD write
75 * operation (on the fly). As a consequence the VPD_STOP would
76 * delete VPD read only data. In case of any problems with the
77 * I2C bus we exit the loop here. The I2C read operation can
78 * not be aborted except by a reset (->LR).
79 */
80 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_FATAL | SK_DBGCAT_ERR,
81 ("ERROR:VPD wait timeout\n"));
82 return(1);
83 }
84
85 VPD_IN16(pAC, IoC, PCI_VPD_ADR_REG, &state);
86
87 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
88 ("state = %x, event %x\n",state,event));
89 } while((int)(state & PCI_VPD_FLAG) == event);
90
91 return(0);
92}
93
94#ifdef SKDIAG
95
96/*
97 * Read the dword at address 'addr' from the VPD EEPROM.
98 *
99 * Needed Time: MIN 1,3 ms MAX 2,6 ms
100 *
101 * Note: The DWord is returned in the endianess of the machine the routine
102 * is running on.
103 *
104 * Returns the data read.
105 */
106SK_U32 VpdReadDWord(
107SK_AC *pAC, /* Adapters context */
108SK_IOC IoC, /* IO Context */
109int addr) /* VPD address */
110{
111 SK_U32 Rtv;
112
113 /* start VPD read */
114 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
115 ("VPD read dword at 0x%x\n",addr));
116 addr &= ~VPD_WRITE; /* ensure the R/W bit is set to read */
117
118 VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, (SK_U16)addr);
119
120 /* ignore return code here */
121 (void)VpdWait(pAC, IoC, VPD_READ);
122
123 /* Don't swap here, it's a data stream of bytes */
124 Rtv = 0;
125
126 VPD_IN32(pAC, IoC, PCI_VPD_DAT_REG, &Rtv);
127
128 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
129 ("VPD read dword data = 0x%x\n",Rtv));
130 return(Rtv);
131}
132
133#endif /* SKDIAG */
134
135#if 0
136
137/*
138 Write the dword 'data' at address 'addr' into the VPD EEPROM, and
139 verify that the data is written.
140
141 Needed Time:
142
143. MIN MAX
144. -------------------------------------------------------------------
145. write 1.8 ms 3.6 ms
146. internal write cyles 0.7 ms 7.0 ms
147. -------------------------------------------------------------------
148. over all program time 2.5 ms 10.6 ms
149. read 1.3 ms 2.6 ms
150. -------------------------------------------------------------------
151. over all 3.8 ms 13.2 ms
152.
153
154
155 Returns 0: success
156 1: error, I2C transfer does not terminate
157 2: error, data verify error
158
159 */
160static int VpdWriteDWord(
161SK_AC *pAC, /* pAC pointer */
162SK_IOC IoC, /* IO Context */
163int addr, /* VPD address */
164SK_U32 data) /* VPD data to write */
165{
166 /* start VPD write */
167 /* Don't swap here, it's a data stream of bytes */
168 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
169 ("VPD write dword at addr 0x%x, data = 0x%x\n",addr,data));
170 VPD_OUT32(pAC, IoC, PCI_VPD_DAT_REG, (SK_U32)data);
171 /* But do it here */
172 addr |= VPD_WRITE;
173
174 VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, (SK_U16)(addr | VPD_WRITE));
175
176 /* this may take up to 10,6 ms */
177 if (VpdWait(pAC, IoC, VPD_WRITE)) {
178 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
179 ("Write Timed Out\n"));
180 return(1);
181 };
182
183 /* verify data */
184 if (VpdReadDWord(pAC, IoC, addr) != data) {
185 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
186 ("Data Verify Error\n"));
187 return(2);
188 }
189 return(0);
190} /* VpdWriteDWord */
191
192#endif /* 0 */
193
194/*
195 * Read one Stream of 'len' bytes of VPD data, starting at 'addr' from
196 * or to the I2C EEPROM.
197 *
198 * Returns number of bytes read / written.
199 */
200static int VpdWriteStream(
201SK_AC *pAC, /* Adapters context */
202SK_IOC IoC, /* IO Context */
203char *buf, /* data buffer */
204int Addr, /* VPD start address */
205int Len) /* number of bytes to read / to write */
206{
207 int i;
208 int j;
209 SK_U16 AdrReg;
210 int Rtv;
211 SK_U8 * pComp; /* Compare pointer */
212 SK_U8 Data; /* Input Data for Compare */
213
214 /* Init Compare Pointer */
215 pComp = (SK_U8 *) buf;
216
217 for (i = 0; i < Len; i++, buf++) {
218 if ((i%sizeof(SK_U32)) == 0) {
219 /*
220 * At the begin of each cycle read the Data Reg
221 * So it is initialized even if only a few bytes
222 * are written.
223 */
224 AdrReg = (SK_U16) Addr;
225 AdrReg &= ~VPD_WRITE; /* READ operation */
226
227 VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
228
229 /* Wait for termination */
230 Rtv = VpdWait(pAC, IoC, VPD_READ);
231 if (Rtv != 0) {
232 return(i);
233 }
234 }
235
236 /* Write current Byte */
237 VPD_OUT8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)),
238 *(SK_U8*)buf);
239
240 if (((i%sizeof(SK_U32)) == 3) || (i == (Len - 1))) {
241 /* New Address needs to be written to VPD_ADDR reg */
242 AdrReg = (SK_U16) Addr;
243 Addr += sizeof(SK_U32);
244 AdrReg |= VPD_WRITE; /* WRITE operation */
245
246 VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
247
248 /* Wait for termination */
249 Rtv = VpdWait(pAC, IoC, VPD_WRITE);
250 if (Rtv != 0) {
251 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
252 ("Write Timed Out\n"));
253 return(i - (i%sizeof(SK_U32)));
254 }
255
256 /*
257 * Now re-read to verify
258 */
259 AdrReg &= ~VPD_WRITE; /* READ operation */
260
261 VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
262
263 /* Wait for termination */
264 Rtv = VpdWait(pAC, IoC, VPD_READ);
265 if (Rtv != 0) {
266 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
267 ("Verify Timed Out\n"));
268 return(i - (i%sizeof(SK_U32)));
269 }
270
271 for (j = 0; j <= (int)(i%sizeof(SK_U32)); j++, pComp++) {
272
273 VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + j, &Data);
274
275 if (Data != *pComp) {
276 /* Verify Error */
277 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
278 ("WriteStream Verify Error\n"));
279 return(i - (i%sizeof(SK_U32)) + j);
280 }
281 }
282 }
283 }
284
285 return(Len);
286}
287
288
289/*
290 * Read one Stream of 'len' bytes of VPD data, starting at 'addr' from
291 * or to the I2C EEPROM.
292 *
293 * Returns number of bytes read / written.
294 */
295static int VpdReadStream(
296SK_AC *pAC, /* Adapters context */
297SK_IOC IoC, /* IO Context */
298char *buf, /* data buffer */
299int Addr, /* VPD start address */
300int Len) /* number of bytes to read / to write */
301{
302 int i;
303 SK_U16 AdrReg;
304 int Rtv;
305
306 for (i = 0; i < Len; i++, buf++) {
307 if ((i%sizeof(SK_U32)) == 0) {
308 /* New Address needs to be written to VPD_ADDR reg */
309 AdrReg = (SK_U16) Addr;
310 Addr += sizeof(SK_U32);
311 AdrReg &= ~VPD_WRITE; /* READ operation */
312
313 VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
314
315 /* Wait for termination */
316 Rtv = VpdWait(pAC, IoC, VPD_READ);
317 if (Rtv != 0) {
318 return(i);
319 }
320 }
321 VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)),
322 (SK_U8 *)buf);
323 }
324
325 return(Len);
326}
327
328/*
329 * Read ore writes 'len' bytes of VPD data, starting at 'addr' from
330 * or to the I2C EEPROM.
331 *
332 * Returns number of bytes read / written.
333 */
334static int VpdTransferBlock(
335SK_AC *pAC, /* Adapters context */
336SK_IOC IoC, /* IO Context */
337char *buf, /* data buffer */
338int addr, /* VPD start address */
339int len, /* number of bytes to read / to write */
340int dir) /* transfer direction may be VPD_READ or VPD_WRITE */
341{
342 int Rtv; /* Return value */
343 int vpd_rom_size;
344
345 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
346 ("VPD %s block, addr = 0x%x, len = %d\n",
347 dir ? "write" : "read", addr, len));
348
349 if (len == 0)
350 return(0);
351
352 vpd_rom_size = pAC->vpd.rom_size;
353
354 if (addr > vpd_rom_size - 4) {
355 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
356 ("Address error: 0x%x, exp. < 0x%x\n",
357 addr, vpd_rom_size - 4));
358 return(0);
359 }
360
361 if (addr + len > vpd_rom_size) {
362 len = vpd_rom_size - addr;
363 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
364 ("Warning: len was cut to %d\n", len));
365 }
366
367 if (dir == VPD_READ) {
368 Rtv = VpdReadStream(pAC, IoC, buf, addr, len);
369 }
370 else {
371 Rtv = VpdWriteStream(pAC, IoC, buf, addr, len);
372 }
373
374 return(Rtv);
375}
376
377#ifdef SKDIAG
378
379/*
380 * Read 'len' bytes of VPD data, starting at 'addr'.
381 *
382 * Returns number of bytes read.
383 */
384int VpdReadBlock(
385SK_AC *pAC, /* pAC pointer */
386SK_IOC IoC, /* IO Context */
387char *buf, /* buffer were the data should be stored */
388int addr, /* start reading at the VPD address */
389int len) /* number of bytes to read */
390{
391 return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_READ));
392}
393
394/*
395 * Write 'len' bytes of *but to the VPD EEPROM, starting at 'addr'.
396 *
397 * Returns number of bytes writes.
398 */
399int VpdWriteBlock(
400SK_AC *pAC, /* pAC pointer */
401SK_IOC IoC, /* IO Context */
402char *buf, /* buffer, holds the data to write */
403int addr, /* start writing at the VPD address */
404int len) /* number of bytes to write */
405{
406 return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_WRITE));
407}
408#endif /* SKDIAG */
409
410/*
411 * (re)initialize the VPD buffer
412 *
413 * Reads the VPD data from the EEPROM into the VPD buffer.
414 * Get the remaining read only and read / write space.
415 *
416 * return 0: success
417 * 1: fatal VPD error
418 */
419static int VpdInit(
420SK_AC *pAC, /* Adapters context */
421SK_IOC IoC) /* IO Context */
422{
423 SK_VPD_PARA *r, rp; /* RW or RV */
424 int i;
425 unsigned char x;
426 int vpd_size;
427 SK_U16 dev_id;
428 SK_U32 our_reg2;
429
430 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT, ("VpdInit .. "));
431
432 VPD_IN16(pAC, IoC, PCI_DEVICE_ID, &dev_id);
433
434 VPD_IN32(pAC, IoC, PCI_OUR_REG_2, &our_reg2);
435
436 pAC->vpd.rom_size = 256 << ((our_reg2 & PCI_VPD_ROM_SZ) >> 14);
437
438 /*
439 * this function might get used before the hardware is initialized
440 * therefore we cannot always trust in GIChipId
441 */
442 if (((pAC->vpd.v.vpd_status & VPD_VALID) == 0 &&
443 dev_id != VPD_DEV_ID_GENESIS) ||
444 ((pAC->vpd.v.vpd_status & VPD_VALID) != 0 &&
445 !pAC->GIni.GIGenesis)) {
446
447 /* for Yukon the VPD size is always 256 */
448 vpd_size = VPD_SIZE_YUKON;
449 }
450 else {
451 /* Genesis uses the maximum ROM size up to 512 for VPD */
452 if (pAC->vpd.rom_size > VPD_SIZE_GENESIS) {
453 vpd_size = VPD_SIZE_GENESIS;
454 }
455 else {
456 vpd_size = pAC->vpd.rom_size;
457 }
458 }
459
460 /* read the VPD data into the VPD buffer */
461 if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf, 0, vpd_size, VPD_READ)
462 != vpd_size) {
463
464 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
465 ("Block Read Error\n"));
466 return(1);
467 }
468
469 pAC->vpd.vpd_size = vpd_size;
470
471 /* Asus K8V Se Deluxe bugfix. Correct VPD content */
472 /* MBo April 2004 */
473 if (((unsigned char)pAC->vpd.vpd_buf[0x3f] == 0x38) &&
474 ((unsigned char)pAC->vpd.vpd_buf[0x40] == 0x3c) &&
475 ((unsigned char)pAC->vpd.vpd_buf[0x41] == 0x45)) {
476 printk("sk98lin: Asus mainboard with buggy VPD? "
477 "Correcting data.\n");
478 pAC->vpd.vpd_buf[0x40] = 0x38;
479 }
480
481
482 /* find the end tag of the RO area */
483 if (!(r = vpd_find_para(pAC, VPD_RV, &rp))) {
484 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
485 ("Encoding Error: RV Tag not found\n"));
486 return(1);
487 }
488
489 if (r->p_val + r->p_len > pAC->vpd.vpd_buf + vpd_size/2) {
490 SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
491 ("Encoding Error: Invalid VPD struct size\n"));
492 return(1);
493 }
494 pAC->vpd.v.vpd_free_ro = r->p_len - 1;
495
496 /* test the checksum */
497 for (i = 0, x = 0; (unsigned)i <= (unsigned)vpd_size/2 - r->p_len; i++) {
498 x += pAC->vpd.vpd_buf[i];
499 }
500
501 if (x != 0) {
502 /* checksum error */
503 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
504 ("VPD Checksum Error\n"));
505 return(1);
506 }
507
508 /* find and check the end tag of the RW area */
509 if (!(r = vpd_find_para(pAC, VPD_RW, &rp))) {
510 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
511 ("Encoding Error: RV Tag not found\n"));
512 return(1);
513 }
514
515 if (r->p_val < pAC->vpd.vpd_buf + vpd_size/2) {
516 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
517 ("Encoding Error: Invalid VPD struct size\n"));
518 return(1);
519 }
520 pAC->vpd.v.vpd_free_rw = r->p_len;
521
522 /* everything seems to be ok */
523 if (pAC->GIni.GIChipId != 0) {
524 pAC->vpd.v.vpd_status |= VPD_VALID;
525 }
526
527 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT,
528 ("done. Free RO = %d, Free RW = %d\n",
529 pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw));
530
531 return(0);
532}
533
534/*
535 * find the Keyword 'key' in the VPD buffer and fills the
536 * parameter struct 'p' with it's values
537 *
538 * returns *p success
539 * 0: parameter was not found or VPD encoding error
540 */
541static SK_VPD_PARA *vpd_find_para(
542SK_AC *pAC, /* common data base */
543const char *key, /* keyword to find (e.g. "MN") */
544SK_VPD_PARA *p) /* parameter description struct */
545{
546 char *v ; /* points to VPD buffer */
547 int max; /* Maximum Number of Iterations */
548
549 v = pAC->vpd.vpd_buf;
550 max = 128;
551
552 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
553 ("VPD find para %s .. ",key));
554
555 /* check mandatory resource type ID string (Product Name) */
556 if (*v != (char)RES_ID) {
557 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
558 ("Error: 0x%x missing\n", RES_ID));
559 return NULL;
560 }
561
562 if (strcmp(key, VPD_NAME) == 0) {
563 p->p_len = VPD_GET_RES_LEN(v);
564 p->p_val = VPD_GET_VAL(v);
565 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
566 ("found, len = %d\n", p->p_len));
567 return(p);
568 }
569
570 v += 3 + VPD_GET_RES_LEN(v) + 3;
571 for (;; ) {
572 if (SK_MEMCMP(key,v,2) == 0) {
573 p->p_len = VPD_GET_VPD_LEN(v);
574 p->p_val = VPD_GET_VAL(v);
575 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
576 ("found, len = %d\n",p->p_len));
577 return(p);
578 }
579
580 /* exit when reaching the "RW" Tag or the maximum of itera. */
581 max--;
582 if (SK_MEMCMP(VPD_RW,v,2) == 0 || max == 0) {
583 break;
584 }
585
586 if (SK_MEMCMP(VPD_RV,v,2) == 0) {
587 v += 3 + VPD_GET_VPD_LEN(v) + 3; /* skip VPD-W */
588 }
589 else {
590 v += 3 + VPD_GET_VPD_LEN(v);
591 }
592 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
593 ("scanning '%c%c' len = %d\n",v[0],v[1],v[2]));
594 }
595
596#ifdef DEBUG
597 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, ("not found\n"));
598 if (max == 0) {
599 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
600 ("Key/Len Encoding error\n"));
601 }
602#endif /* DEBUG */
603 return NULL;
604}
605
606/*
607 * Move 'n' bytes. Begin with the last byte if 'n' is > 0,
608 * Start with the last byte if n is < 0.
609 *
610 * returns nothing
611 */
612static void vpd_move_para(
613char *start, /* start of memory block */
614char *end, /* end of memory block to move */
615int n) /* number of bytes the memory block has to be moved */
616{
617 char *p;
618 int i; /* number of byte copied */
619
620 if (n == 0)
621 return;
622
623 i = (int) (end - start + 1);
624 if (n < 0) {
625 p = start + n;
626 while (i != 0) {
627 *p++ = *start++;
628 i--;
629 }
630 }
631 else {
632 p = end + n;
633 while (i != 0) {
634 *p-- = *end--;
635 i--;
636 }
637 }
638}
639
640/*
641 * setup the VPD keyword 'key' at 'ip'.
642 *
643 * returns nothing
644 */
645static void vpd_insert_key(
646const char *key, /* keyword to insert */
647const char *buf, /* buffer with the keyword value */
648int len, /* length of the value string */
649char *ip) /* inseration point */
650{
651 SK_VPD_KEY *p;
652
653 p = (SK_VPD_KEY *) ip;
654 p->p_key[0] = key[0];
655 p->p_key[1] = key[1];
656 p->p_len = (unsigned char) len;
657 SK_MEMCPY(&p->p_val,buf,len);
658}
659
660/*
661 * Setup the VPD end tag "RV" / "RW".
662 * Also correct the remaining space variables vpd_free_ro / vpd_free_rw.
663 *
664 * returns 0: success
665 * 1: encoding error
666 */
667static int vpd_mod_endtag(
668SK_AC *pAC, /* common data base */
669char *etp) /* end pointer input position */
670{
671 SK_VPD_KEY *p;
672 unsigned char x;
673 int i;
674 int vpd_size;
675
676 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
677 ("VPD modify endtag at 0x%x = '%c%c'\n",etp,etp[0],etp[1]));
678
679 vpd_size = pAC->vpd.vpd_size;
680
681 p = (SK_VPD_KEY *) etp;
682
683 if (p->p_key[0] != 'R' || (p->p_key[1] != 'V' && p->p_key[1] != 'W')) {
684 /* something wrong here, encoding error */
685 SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
686 ("Encoding Error: invalid end tag\n"));
687 return(1);
688 }
689 if (etp > pAC->vpd.vpd_buf + vpd_size/2) {
690 /* create "RW" tag */
691 p->p_len = (unsigned char)(pAC->vpd.vpd_buf+vpd_size-etp-3-1);
692 pAC->vpd.v.vpd_free_rw = (int) p->p_len;
693 i = pAC->vpd.v.vpd_free_rw;
694 etp += 3;
695 }
696 else {
697 /* create "RV" tag */
698 p->p_len = (unsigned char)(pAC->vpd.vpd_buf+vpd_size/2-etp-3);
699 pAC->vpd.v.vpd_free_ro = (int) p->p_len - 1;
700
701 /* setup checksum */
702 for (i = 0, x = 0; i < vpd_size/2 - p->p_len; i++) {
703 x += pAC->vpd.vpd_buf[i];
704 }
705 p->p_val = (char) 0 - x;
706 i = pAC->vpd.v.vpd_free_ro;
707 etp += 4;
708 }
709 while (i) {
710 *etp++ = 0x00;
711 i--;
712 }
713
714 return(0);
715}
716
717/*
718 * Insert a VPD keyword into the VPD buffer.
719 *
720 * The keyword 'key' is inserted at the position 'ip' in the
721 * VPD buffer.
722 * The keywords behind the input position will
723 * be moved. The VPD end tag "RV" or "RW" is generated again.
724 *
725 * returns 0: success
726 * 2: value string was cut
727 * 4: VPD full, keyword was not written
728 * 6: fatal VPD error
729 *
730 */
731int VpdSetupPara(
732SK_AC *pAC, /* common data base */
733const char *key, /* keyword to insert */
734const char *buf, /* buffer with the keyword value */
735int len, /* length of the keyword value */
736int type, /* VPD_RO_KEY or VPD_RW_KEY */
737int op) /* operation to do: ADD_KEY or OWR_KEY */
738{
739 SK_VPD_PARA vp;
740 char *etp; /* end tag position */
741 int free; /* remaining space in selected area */
742 char *ip; /* input position inside the VPD buffer */
743 int rtv; /* return code */
744 int head; /* additional haeder bytes to move */
745 int found; /* additinoal bytes if the keyword was found */
746 int vpd_size;
747
748 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
749 ("VPD setup para key = %s, val = %s\n",key,buf));
750
751 vpd_size = pAC->vpd.vpd_size;
752
753 rtv = 0;
754 ip = NULL;
755 if (type == VPD_RW_KEY) {
756 /* end tag is "RW" */
757 free = pAC->vpd.v.vpd_free_rw;
758 etp = pAC->vpd.vpd_buf + (vpd_size - free - 1 - 3);
759 }
760 else {
761 /* end tag is "RV" */
762 free = pAC->vpd.v.vpd_free_ro;
763 etp = pAC->vpd.vpd_buf + (vpd_size/2 - free - 4);
764 }
765 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
766 ("Free RO = %d, Free RW = %d\n",
767 pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw));
768
769 head = 0;
770 found = 0;
771 if (op == OWR_KEY) {
772 if (vpd_find_para(pAC, key, &vp)) {
773 found = 3;
774 ip = vp.p_val - 3;
775 free += vp.p_len + 3;
776 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
777 ("Overwrite Key\n"));
778 }
779 else {
780 op = ADD_KEY;
781 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
782 ("Add Key\n"));
783 }
784 }
785 if (op == ADD_KEY) {
786 ip = etp;
787 vp.p_len = 0;
788 head = 3;
789 }
790
791 if (len + 3 > free) {
792 if (free < 7) {
793 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
794 ("VPD Buffer Overflow, keyword not written\n"));
795 return(4);
796 }
797 /* cut it again */
798 len = free - 3;
799 rtv = 2;
800 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
801 ("VPD Buffer Full, Keyword was cut\n"));
802 }
803
804 vpd_move_para(ip + vp.p_len + found, etp+2, len-vp.p_len+head);
805 vpd_insert_key(key, buf, len, ip);
806 if (vpd_mod_endtag(pAC, etp + len - vp.p_len + head)) {
807 pAC->vpd.v.vpd_status &= ~VPD_VALID;
808 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
809 ("VPD Encoding Error\n"));
810 return(6);
811 }
812
813 return(rtv);
814}
815
816
817/*
818 * Read the contents of the VPD EEPROM and copy it to the
819 * VPD buffer if not already done.
820 *
821 * return: A pointer to the vpd_status structure. The structure contains
822 * this fields.
823 */
824SK_VPD_STATUS *VpdStat(
825SK_AC *pAC, /* Adapters context */
826SK_IOC IoC) /* IO Context */
827{
828 if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
829 (void)VpdInit(pAC, IoC);
830 }
831 return(&pAC->vpd.v);
832}
833
834
835/*
836 * Read the contents of the VPD EEPROM and copy it to the VPD
837 * buffer if not already done.
838 * Scan the VPD buffer for VPD keywords and create the VPD
839 * keyword list by copying the keywords to 'buf', all after
840 * each other and terminated with a '\0'.
841 *
842 * Exceptions: o The Resource Type ID String (product name) is called "Name"
843 * o The VPD end tags 'RV' and 'RW' are not listed
844 *
845 * The number of copied keywords is counted in 'elements'.
846 *
847 * returns 0: success
848 * 2: buffer overfull, one or more keywords are missing
849 * 6: fatal VPD error
850 *
851 * example values after returning:
852 *
853 * buf = "Name\0PN\0EC\0MN\0SN\0CP\0VF\0VL\0YA\0"
854 * *len = 30
855 * *elements = 9
856 */
857int VpdKeys(
858SK_AC *pAC, /* common data base */
859SK_IOC IoC, /* IO Context */
860char *buf, /* buffer where to copy the keywords */
861int *len, /* buffer length */
862int *elements) /* number of keywords returned */
863{
864 char *v;
865 int n;
866
867 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("list VPD keys .. "));
868 *elements = 0;
869 if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
870 if (VpdInit(pAC, IoC) != 0) {
871 *len = 0;
872 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
873 ("VPD Init Error, terminated\n"));
874 return(6);
875 }
876 }
877
878 if ((signed)strlen(VPD_NAME) + 1 <= *len) {
879 v = pAC->vpd.vpd_buf;
880 strcpy(buf,VPD_NAME);
881 n = strlen(VPD_NAME) + 1;
882 buf += n;
883 *elements = 1;
884 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
885 ("'%c%c' ",v[0],v[1]));
886 }
887 else {
888 *len = 0;
889 SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
890 ("buffer overflow\n"));
891 return(2);
892 }
893
894 v += 3 + VPD_GET_RES_LEN(v) + 3;
895 for (;; ) {
896 /* exit when reaching the "RW" Tag */
897 if (SK_MEMCMP(VPD_RW,v,2) == 0) {
898 break;
899 }
900
901 if (SK_MEMCMP(VPD_RV,v,2) == 0) {
902 v += 3 + VPD_GET_VPD_LEN(v) + 3; /* skip VPD-W */
903 continue;
904 }
905
906 if (n+3 <= *len) {
907 SK_MEMCPY(buf,v,2);
908 buf += 2;
909 *buf++ = '\0';
910 n += 3;
911 v += 3 + VPD_GET_VPD_LEN(v);
912 *elements += 1;
913 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
914 ("'%c%c' ",v[0],v[1]));
915 }
916 else {
917 *len = n;
918 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
919 ("buffer overflow\n"));
920 return(2);
921 }
922 }
923
924 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("\n"));
925 *len = n;
926 return(0);
927}
928
929
930/*
931 * Read the contents of the VPD EEPROM and copy it to the
932 * VPD buffer if not already done. Search for the VPD keyword
933 * 'key' and copy its value to 'buf'. Add a terminating '\0'.
934 * If the value does not fit into the buffer cut it after
935 * 'len' - 1 bytes.
936 *
937 * returns 0: success
938 * 1: keyword not found
939 * 2: value string was cut
940 * 3: VPD transfer timeout
941 * 6: fatal VPD error
942 */
943int VpdRead(
944SK_AC *pAC, /* common data base */
945SK_IOC IoC, /* IO Context */
946const char *key, /* keyword to read (e.g. "MN") */
947char *buf, /* buffer where to copy the keyword value */
948int *len) /* buffer length */
949{
950 SK_VPD_PARA *p, vp;
951
952 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("VPD read %s .. ", key));
953 if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
954 if (VpdInit(pAC, IoC) != 0) {
955 *len = 0;
956 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
957 ("VPD init error\n"));
958 return(6);
959 }
960 }
961
962 if ((p = vpd_find_para(pAC, key, &vp)) != NULL) {
963 if (p->p_len > (*(unsigned *)len)-1) {
964 p->p_len = *len - 1;
965 }
966 SK_MEMCPY(buf, p->p_val, p->p_len);
967 buf[p->p_len] = '\0';
968 *len = p->p_len;
969 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
970 ("%c%c%c%c.., len = %d\n",
971 buf[0],buf[1],buf[2],buf[3],*len));
972 }
973 else {
974 *len = 0;
975 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("not found\n"));
976 return(1);
977 }
978 return(0);
979}
980
981
982/*
983 * Check whether a given key may be written
984 *
985 * returns
986 * SK_TRUE Yes it may be written
987 * SK_FALSE No it may be written
988 */
989SK_BOOL VpdMayWrite(
990char *key) /* keyword to write (allowed values "Yx", "Vx") */
991{
992 if ((*key != 'Y' && *key != 'V') ||
993 key[1] < '0' || key[1] > 'Z' ||
994 (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) {
995
996 return(SK_FALSE);
997 }
998 return(SK_TRUE);
999}
1000
1001/*
1002 * Read the contents of the VPD EEPROM and copy it to the VPD
1003 * buffer if not already done. Insert/overwrite the keyword 'key'
1004 * in the VPD buffer. Cut the keyword value if it does not fit
1005 * into the VPD read / write area.
1006 *
1007 * returns 0: success
1008 * 2: value string was cut
1009 * 3: VPD transfer timeout
1010 * 4: VPD full, keyword was not written
1011 * 5: keyword cannot be written
1012 * 6: fatal VPD error
1013 */
1014int VpdWrite(
1015SK_AC *pAC, /* common data base */
1016SK_IOC IoC, /* IO Context */
1017const char *key, /* keyword to write (allowed values "Yx", "Vx") */
1018const char *buf) /* buffer where the keyword value can be read from */
1019{
1020 int len; /* length of the keyword to write */
1021 int rtv; /* return code */
1022 int rtv2;
1023
1024 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX,
1025 ("VPD write %s = %s\n",key,buf));
1026
1027 if ((*key != 'Y' && *key != 'V') ||
1028 key[1] < '0' || key[1] > 'Z' ||
1029 (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) {
1030
1031 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
1032 ("illegal key tag, keyword not written\n"));
1033 return(5);
1034 }
1035
1036 if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
1037 if (VpdInit(pAC, IoC) != 0) {
1038 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
1039 ("VPD init error\n"));
1040 return(6);
1041 }
1042 }
1043
1044 rtv = 0;
1045 len = strlen(buf);
1046 if (len > VPD_MAX_LEN) {
1047 /* cut it */
1048 len = VPD_MAX_LEN;
1049 rtv = 2;
1050 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
1051 ("keyword too long, cut after %d bytes\n",VPD_MAX_LEN));
1052 }
1053 if ((rtv2 = VpdSetupPara(pAC, key, buf, len, VPD_RW_KEY, OWR_KEY)) != 0) {
1054 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
1055 ("VPD write error\n"));
1056 return(rtv2);
1057 }
1058
1059 return(rtv);
1060}
1061
1062/*
1063 * Read the contents of the VPD EEPROM and copy it to the
1064 * VPD buffer if not already done. Remove the VPD keyword
1065 * 'key' from the VPD buffer.
1066 * Only the keywords in the read/write area can be deleted.
1067 * Keywords in the read only area cannot be deleted.
1068 *
1069 * returns 0: success, keyword was removed
1070 * 1: keyword not found
1071 * 5: keyword cannot be deleted
1072 * 6: fatal VPD error
1073 */
1074int VpdDelete(
1075SK_AC *pAC, /* common data base */
1076SK_IOC IoC, /* IO Context */
1077char *key) /* keyword to read (e.g. "MN") */
1078{
1079 SK_VPD_PARA *p, vp;
1080 char *etp;
1081 int vpd_size;
1082
1083 vpd_size = pAC->vpd.vpd_size;
1084
1085 SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("VPD delete key %s\n",key));
1086 if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
1087 if (VpdInit(pAC, IoC) != 0) {
1088 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
1089 ("VPD init error\n"));
1090 return(6);
1091 }
1092 }
1093
1094 if ((p = vpd_find_para(pAC, key, &vp)) != NULL) {
1095 if (p->p_val < pAC->vpd.vpd_buf + vpd_size/2) {
1096 /* try to delete read only keyword */
1097 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
1098 ("cannot delete RO keyword\n"));
1099 return(5);
1100 }
1101
1102 etp = pAC->vpd.vpd_buf + (vpd_size-pAC->vpd.v.vpd_free_rw-1-3);
1103
1104 vpd_move_para(vp.p_val+vp.p_len, etp+2,
1105 - ((int)(vp.p_len + 3)));
1106 if (vpd_mod_endtag(pAC, etp - vp.p_len - 3)) {
1107 pAC->vpd.v.vpd_status &= ~VPD_VALID;
1108 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
1109 ("VPD encoding error\n"));
1110 return(6);
1111 }
1112 }
1113 else {
1114 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
1115 ("keyword not found\n"));
1116 return(1);
1117 }
1118
1119 return(0);
1120}
1121
1122/*
1123 * If the VPD buffer contains valid data write the VPD
1124 * read/write area back to the VPD EEPROM.
1125 *
1126 * returns 0: success
1127 * 3: VPD transfer timeout
1128 */
1129int VpdUpdate(
1130SK_AC *pAC, /* Adapters context */
1131SK_IOC IoC) /* IO Context */
1132{
1133 int vpd_size;
1134
1135 vpd_size = pAC->vpd.vpd_size;
1136
1137 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("VPD update .. "));
1138 if ((pAC->vpd.v.vpd_status & VPD_VALID) != 0) {
1139 if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf + vpd_size/2,
1140 vpd_size/2, vpd_size/2, VPD_WRITE) != vpd_size/2) {
1141
1142 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
1143 ("transfer timed out\n"));
1144 return(3);
1145 }
1146 }
1147 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("done\n"));
1148 return(0);
1149}
1150
1151
1152
1153/*
1154 * Read the contents of the VPD EEPROM and copy it to the VPD buffer
1155 * if not already done. If the keyword "VF" is not present it will be
1156 * created and the error log message will be stored to this keyword.
1157 * If "VF" is not present the error log message will be stored to the
1158 * keyword "VL". "VL" will created or overwritten if "VF" is present.
1159 * The VPD read/write area is saved to the VPD EEPROM.
1160 *
1161 * returns nothing, errors will be ignored.
1162 */
1163void VpdErrLog(
1164SK_AC *pAC, /* common data base */
1165SK_IOC IoC, /* IO Context */
1166char *msg) /* error log message */
1167{
1168 SK_VPD_PARA *v, vf; /* VF */
1169 int len;
1170
1171 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX,
1172 ("VPD error log msg %s\n", msg));
1173 if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
1174 if (VpdInit(pAC, IoC) != 0) {
1175 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
1176 ("VPD init error\n"));
1177 return;
1178 }
1179 }
1180
1181 len = strlen(msg);
1182 if (len > VPD_MAX_LEN) {
1183 /* cut it */
1184 len = VPD_MAX_LEN;
1185 }
1186 if ((v = vpd_find_para(pAC, VPD_VF, &vf)) != NULL) {
1187 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("overwrite VL\n"));
1188 (void)VpdSetupPara(pAC, VPD_VL, msg, len, VPD_RW_KEY, OWR_KEY);
1189 }
1190 else {
1191 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("write VF\n"));
1192 (void)VpdSetupPara(pAC, VPD_VF, msg, len, VPD_RW_KEY, ADD_KEY);
1193 }
1194
1195 (void)VpdUpdate(pAC, IoC);
1196}
1197
diff --git a/drivers/net/sk98lin/skxmac2.c b/drivers/net/sk98lin/skxmac2.c
new file mode 100644
index 000000000000..94a09deecb32
--- /dev/null
+++ b/drivers/net/sk98lin/skxmac2.c
@@ -0,0 +1,4607 @@
1/******************************************************************************
2 *
3 * Name: skxmac2.c
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.102 $
6 * Date: $Date: 2003/10/02 16:53:58 $
7 * Purpose: Contains functions to initialize the MACs and PHYs
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#include "h/skdrv1st.h"
26#include "h/skdrv2nd.h"
27
28/* typedefs *******************************************************************/
29
30/* BCOM PHY magic pattern list */
31typedef struct s_PhyHack {
32 int PhyReg; /* Phy register */
33 SK_U16 PhyVal; /* Value to write */
34} BCOM_HACK;
35
36/* local variables ************************************************************/
37
38#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
39static const char SysKonnectFileId[] =
40 "@(#) $Id: skxmac2.c,v 1.102 2003/10/02 16:53:58 rschmidt Exp $ (C) Marvell.";
41#endif
42
43#ifdef GENESIS
44BCOM_HACK BcomRegA1Hack[] = {
45 { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 }, { 0x17, 0x0013 },
46 { 0x15, 0x0404 }, { 0x17, 0x8006 }, { 0x15, 0x0132 }, { 0x17, 0x8006 },
47 { 0x15, 0x0232 }, { 0x17, 0x800D }, { 0x15, 0x000F }, { 0x18, 0x0420 },
48 { 0, 0 }
49};
50BCOM_HACK BcomRegC0Hack[] = {
51 { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1204 }, { 0x17, 0x0013 },
52 { 0x15, 0x0A04 }, { 0x18, 0x0420 },
53 { 0, 0 }
54};
55#endif
56
57/* function prototypes ********************************************************/
58#ifdef GENESIS
59static void SkXmInitPhyXmac(SK_AC*, SK_IOC, int, SK_BOOL);
60static void SkXmInitPhyBcom(SK_AC*, SK_IOC, int, SK_BOOL);
61static int SkXmAutoNegDoneXmac(SK_AC*, SK_IOC, int);
62static int SkXmAutoNegDoneBcom(SK_AC*, SK_IOC, int);
63#endif /* GENESIS */
64#ifdef YUKON
65static void SkGmInitPhyMarv(SK_AC*, SK_IOC, int, SK_BOOL);
66static int SkGmAutoNegDoneMarv(SK_AC*, SK_IOC, int);
67#endif /* YUKON */
68#ifdef OTHER_PHY
69static void SkXmInitPhyLone(SK_AC*, SK_IOC, int, SK_BOOL);
70static void SkXmInitPhyNat (SK_AC*, SK_IOC, int, SK_BOOL);
71static int SkXmAutoNegDoneLone(SK_AC*, SK_IOC, int);
72static int SkXmAutoNegDoneNat (SK_AC*, SK_IOC, int);
73#endif /* OTHER_PHY */
74
75
76#ifdef GENESIS
77/******************************************************************************
78 *
79 * SkXmPhyRead() - Read from XMAC PHY register
80 *
81 * Description: reads a 16-bit word from XMAC PHY or ext. PHY
82 *
83 * Returns:
84 * nothing
85 */
86void SkXmPhyRead(
87SK_AC *pAC, /* Adapter Context */
88SK_IOC IoC, /* I/O Context */
89int Port, /* Port Index (MAC_1 + n) */
90int PhyReg, /* Register Address (Offset) */
91SK_U16 SK_FAR *pVal) /* Pointer to Value */
92{
93 SK_U16 Mmu;
94 SK_GEPORT *pPrt;
95
96 pPrt = &pAC->GIni.GP[Port];
97
98 /* write the PHY register's address */
99 XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr);
100
101 /* get the PHY register's value */
102 XM_IN16(IoC, Port, XM_PHY_DATA, pVal);
103
104 if (pPrt->PhyType != SK_PHY_XMAC) {
105 do {
106 XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
107 /* wait until 'Ready' is set */
108 } while ((Mmu & XM_MMU_PHY_RDY) == 0);
109
110 /* get the PHY register's value */
111 XM_IN16(IoC, Port, XM_PHY_DATA, pVal);
112 }
113} /* SkXmPhyRead */
114
115
116/******************************************************************************
117 *
118 * SkXmPhyWrite() - Write to XMAC PHY register
119 *
120 * Description: writes a 16-bit word to XMAC PHY or ext. PHY
121 *
122 * Returns:
123 * nothing
124 */
125void SkXmPhyWrite(
126SK_AC *pAC, /* Adapter Context */
127SK_IOC IoC, /* I/O Context */
128int Port, /* Port Index (MAC_1 + n) */
129int PhyReg, /* Register Address (Offset) */
130SK_U16 Val) /* Value */
131{
132 SK_U16 Mmu;
133 SK_GEPORT *pPrt;
134
135 pPrt = &pAC->GIni.GP[Port];
136
137 if (pPrt->PhyType != SK_PHY_XMAC) {
138 do {
139 XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
140 /* wait until 'Busy' is cleared */
141 } while ((Mmu & XM_MMU_PHY_BUSY) != 0);
142 }
143
144 /* write the PHY register's address */
145 XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr);
146
147 /* write the PHY register's value */
148 XM_OUT16(IoC, Port, XM_PHY_DATA, Val);
149
150 if (pPrt->PhyType != SK_PHY_XMAC) {
151 do {
152 XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
153 /* wait until 'Busy' is cleared */
154 } while ((Mmu & XM_MMU_PHY_BUSY) != 0);
155 }
156} /* SkXmPhyWrite */
157#endif /* GENESIS */
158
159
160#ifdef YUKON
161/******************************************************************************
162 *
163 * SkGmPhyRead() - Read from GPHY register
164 *
165 * Description: reads a 16-bit word from GPHY through MDIO
166 *
167 * Returns:
168 * nothing
169 */
170void SkGmPhyRead(
171SK_AC *pAC, /* Adapter Context */
172SK_IOC IoC, /* I/O Context */
173int Port, /* Port Index (MAC_1 + n) */
174int PhyReg, /* Register Address (Offset) */
175SK_U16 SK_FAR *pVal) /* Pointer to Value */
176{
177 SK_U16 Ctrl;
178 SK_GEPORT *pPrt;
179#ifdef VCPU
180 u_long SimCyle;
181 u_long SimLowTime;
182
183 VCPUgetTime(&SimCyle, &SimLowTime);
184 VCPUprintf(0, "SkGmPhyRead(%u), SimCyle=%u, SimLowTime=%u\n",
185 PhyReg, SimCyle, SimLowTime);
186#endif /* VCPU */
187
188 pPrt = &pAC->GIni.GP[Port];
189
190 /* set PHY-Register offset and 'Read' OpCode (= 1) */
191 *pVal = (SK_U16)(GM_SMI_CT_PHY_AD(pPrt->PhyAddr) |
192 GM_SMI_CT_REG_AD(PhyReg) | GM_SMI_CT_OP_RD);
193
194 GM_OUT16(IoC, Port, GM_SMI_CTRL, *pVal);
195
196 GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
197
198 /* additional check for MDC/MDIO activity */
199 if ((Ctrl & GM_SMI_CT_BUSY) == 0) {
200 *pVal = 0;
201 return;
202 }
203
204 *pVal |= GM_SMI_CT_BUSY;
205
206 do {
207#ifdef VCPU
208 VCPUwaitTime(1000);
209#endif /* VCPU */
210
211 GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
212
213 /* wait until 'ReadValid' is set */
214 } while (Ctrl == *pVal);
215
216 /* get the PHY register's value */
217 GM_IN16(IoC, Port, GM_SMI_DATA, pVal);
218
219#ifdef VCPU
220 VCPUgetTime(&SimCyle, &SimLowTime);
221 VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n",
222 SimCyle, SimLowTime);
223#endif /* VCPU */
224
225} /* SkGmPhyRead */
226
227
228/******************************************************************************
229 *
230 * SkGmPhyWrite() - Write to GPHY register
231 *
232 * Description: writes a 16-bit word to GPHY through MDIO
233 *
234 * Returns:
235 * nothing
236 */
237void SkGmPhyWrite(
238SK_AC *pAC, /* Adapter Context */
239SK_IOC IoC, /* I/O Context */
240int Port, /* Port Index (MAC_1 + n) */
241int PhyReg, /* Register Address (Offset) */
242SK_U16 Val) /* Value */
243{
244 SK_U16 Ctrl;
245 SK_GEPORT *pPrt;
246#ifdef VCPU
247 SK_U32 DWord;
248 u_long SimCyle;
249 u_long SimLowTime;
250
251 VCPUgetTime(&SimCyle, &SimLowTime);
252 VCPUprintf(0, "SkGmPhyWrite(Reg=%u, Val=0x%04x), SimCyle=%u, SimLowTime=%u\n",
253 PhyReg, Val, SimCyle, SimLowTime);
254#endif /* VCPU */
255
256 pPrt = &pAC->GIni.GP[Port];
257
258 /* write the PHY register's value */
259 GM_OUT16(IoC, Port, GM_SMI_DATA, Val);
260
261 /* set PHY-Register offset and 'Write' OpCode (= 0) */
262 Val = GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | GM_SMI_CT_REG_AD(PhyReg);
263
264 GM_OUT16(IoC, Port, GM_SMI_CTRL, Val);
265
266 GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
267
268 /* additional check for MDC/MDIO activity */
269 if ((Ctrl & GM_SMI_CT_BUSY) == 0) {
270 return;
271 }
272
273 Val |= GM_SMI_CT_BUSY;
274
275 do {
276#ifdef VCPU
277 /* read Timer value */
278 SK_IN32(IoC, B2_TI_VAL, &DWord);
279
280 VCPUwaitTime(1000);
281#endif /* VCPU */
282
283 GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
284
285 /* wait until 'Busy' is cleared */
286 } while (Ctrl == Val);
287
288#ifdef VCPU
289 VCPUgetTime(&SimCyle, &SimLowTime);
290 VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n",
291 SimCyle, SimLowTime);
292#endif /* VCPU */
293
294} /* SkGmPhyWrite */
295#endif /* YUKON */
296
297
298#ifdef SK_DIAG
299/******************************************************************************
300 *
301 * SkGePhyRead() - Read from PHY register
302 *
303 * Description: calls a read PHY routine dep. on board type
304 *
305 * Returns:
306 * nothing
307 */
308void SkGePhyRead(
309SK_AC *pAC, /* Adapter Context */
310SK_IOC IoC, /* I/O Context */
311int Port, /* Port Index (MAC_1 + n) */
312int PhyReg, /* Register Address (Offset) */
313SK_U16 *pVal) /* Pointer to Value */
314{
315 void (*r_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 *pVal);
316
317 if (pAC->GIni.GIGenesis) {
318 r_func = SkXmPhyRead;
319 }
320 else {
321 r_func = SkGmPhyRead;
322 }
323
324 r_func(pAC, IoC, Port, PhyReg, pVal);
325} /* SkGePhyRead */
326
327
328/******************************************************************************
329 *
330 * SkGePhyWrite() - Write to PHY register
331 *
332 * Description: calls a write PHY routine dep. on board type
333 *
334 * Returns:
335 * nothing
336 */
337void SkGePhyWrite(
338SK_AC *pAC, /* Adapter Context */
339SK_IOC IoC, /* I/O Context */
340int Port, /* Port Index (MAC_1 + n) */
341int PhyReg, /* Register Address (Offset) */
342SK_U16 Val) /* Value */
343{
344 void (*w_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 Val);
345
346 if (pAC->GIni.GIGenesis) {
347 w_func = SkXmPhyWrite;
348 }
349 else {
350 w_func = SkGmPhyWrite;
351 }
352
353 w_func(pAC, IoC, Port, PhyReg, Val);
354} /* SkGePhyWrite */
355#endif /* SK_DIAG */
356
357
358/******************************************************************************
359 *
360 * SkMacPromiscMode() - Enable / Disable Promiscuous Mode
361 *
362 * Description:
363 * enables / disables promiscuous mode by setting Mode Register (XMAC) or
364 * Receive Control Register (GMAC) dep. on board type
365 *
366 * Returns:
367 * nothing
368 */
369void SkMacPromiscMode(
370SK_AC *pAC, /* adapter context */
371SK_IOC IoC, /* IO context */
372int Port, /* Port Index (MAC_1 + n) */
373SK_BOOL Enable) /* Enable / Disable */
374{
375#ifdef YUKON
376 SK_U16 RcReg;
377#endif
378#ifdef GENESIS
379 SK_U32 MdReg;
380#endif
381
382#ifdef GENESIS
383 if (pAC->GIni.GIGenesis) {
384
385 XM_IN32(IoC, Port, XM_MODE, &MdReg);
386 /* enable or disable promiscuous mode */
387 if (Enable) {
388 MdReg |= XM_MD_ENA_PROM;
389 }
390 else {
391 MdReg &= ~XM_MD_ENA_PROM;
392 }
393 /* setup Mode Register */
394 XM_OUT32(IoC, Port, XM_MODE, MdReg);
395 }
396#endif /* GENESIS */
397
398#ifdef YUKON
399 if (pAC->GIni.GIYukon) {
400
401 GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg);
402
403 /* enable or disable unicast and multicast filtering */
404 if (Enable) {
405 RcReg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
406 }
407 else {
408 RcReg |= (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
409 }
410 /* setup Receive Control Register */
411 GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg);
412 }
413#endif /* YUKON */
414
415} /* SkMacPromiscMode*/
416
417
418/******************************************************************************
419 *
420 * SkMacHashing() - Enable / Disable Hashing
421 *
422 * Description:
423 * enables / disables hashing by setting Mode Register (XMAC) or
424 * Receive Control Register (GMAC) dep. on board type
425 *
426 * Returns:
427 * nothing
428 */
429void SkMacHashing(
430SK_AC *pAC, /* adapter context */
431SK_IOC IoC, /* IO context */
432int Port, /* Port Index (MAC_1 + n) */
433SK_BOOL Enable) /* Enable / Disable */
434{
435#ifdef YUKON
436 SK_U16 RcReg;
437#endif
438#ifdef GENESIS
439 SK_U32 MdReg;
440#endif
441
442#ifdef GENESIS
443 if (pAC->GIni.GIGenesis) {
444
445 XM_IN32(IoC, Port, XM_MODE, &MdReg);
446 /* enable or disable hashing */
447 if (Enable) {
448 MdReg |= XM_MD_ENA_HASH;
449 }
450 else {
451 MdReg &= ~XM_MD_ENA_HASH;
452 }
453 /* setup Mode Register */
454 XM_OUT32(IoC, Port, XM_MODE, MdReg);
455 }
456#endif /* GENESIS */
457
458#ifdef YUKON
459 if (pAC->GIni.GIYukon) {
460
461 GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg);
462
463 /* enable or disable multicast filtering */
464 if (Enable) {
465 RcReg |= GM_RXCR_MCF_ENA;
466 }
467 else {
468 RcReg &= ~GM_RXCR_MCF_ENA;
469 }
470 /* setup Receive Control Register */
471 GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg);
472 }
473#endif /* YUKON */
474
475} /* SkMacHashing*/
476
477
478#ifdef SK_DIAG
479/******************************************************************************
480 *
481 * SkXmSetRxCmd() - Modify the value of the XMAC's Rx Command Register
482 *
483 * Description:
484 * The features
485 * - FCS stripping, SK_STRIP_FCS_ON/OFF
486 * - pad byte stripping, SK_STRIP_PAD_ON/OFF
487 * - don't set XMR_FS_ERR in status SK_LENERR_OK_ON/OFF
488 * for inrange length error frames
489 * - don't set XMR_FS_ERR in status SK_BIG_PK_OK_ON/OFF
490 * for frames > 1514 bytes
491 * - enable Rx of own packets SK_SELF_RX_ON/OFF
492 *
493 * for incoming packets may be enabled/disabled by this function.
494 * Additional modes may be added later.
495 * Multiple modes can be enabled/disabled at the same time.
496 * The new configuration is written to the Rx Command register immediately.
497 *
498 * Returns:
499 * nothing
500 */
501static void SkXmSetRxCmd(
502SK_AC *pAC, /* adapter context */
503SK_IOC IoC, /* IO context */
504int Port, /* Port Index (MAC_1 + n) */
505int Mode) /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF,
506 SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
507{
508 SK_U16 OldRxCmd;
509 SK_U16 RxCmd;
510
511 XM_IN16(IoC, Port, XM_RX_CMD, &OldRxCmd);
512
513 RxCmd = OldRxCmd;
514
515 switch (Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) {
516 case SK_STRIP_FCS_ON:
517 RxCmd |= XM_RX_STRIP_FCS;
518 break;
519 case SK_STRIP_FCS_OFF:
520 RxCmd &= ~XM_RX_STRIP_FCS;
521 break;
522 }
523
524 switch (Mode & (SK_STRIP_PAD_ON | SK_STRIP_PAD_OFF)) {
525 case SK_STRIP_PAD_ON:
526 RxCmd |= XM_RX_STRIP_PAD;
527 break;
528 case SK_STRIP_PAD_OFF:
529 RxCmd &= ~XM_RX_STRIP_PAD;
530 break;
531 }
532
533 switch (Mode & (SK_LENERR_OK_ON | SK_LENERR_OK_OFF)) {
534 case SK_LENERR_OK_ON:
535 RxCmd |= XM_RX_LENERR_OK;
536 break;
537 case SK_LENERR_OK_OFF:
538 RxCmd &= ~XM_RX_LENERR_OK;
539 break;
540 }
541
542 switch (Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) {
543 case SK_BIG_PK_OK_ON:
544 RxCmd |= XM_RX_BIG_PK_OK;
545 break;
546 case SK_BIG_PK_OK_OFF:
547 RxCmd &= ~XM_RX_BIG_PK_OK;
548 break;
549 }
550
551 switch (Mode & (SK_SELF_RX_ON | SK_SELF_RX_OFF)) {
552 case SK_SELF_RX_ON:
553 RxCmd |= XM_RX_SELF_RX;
554 break;
555 case SK_SELF_RX_OFF:
556 RxCmd &= ~XM_RX_SELF_RX;
557 break;
558 }
559
560 /* Write the new mode to the Rx command register if required */
561 if (OldRxCmd != RxCmd) {
562 XM_OUT16(IoC, Port, XM_RX_CMD, RxCmd);
563 }
564} /* SkXmSetRxCmd */
565
566
567/******************************************************************************
568 *
569 * SkGmSetRxCmd() - Modify the value of the GMAC's Rx Control Register
570 *
571 * Description:
572 * The features
573 * - FCS (CRC) stripping, SK_STRIP_FCS_ON/OFF
574 * - don't set GMR_FS_LONG_ERR SK_BIG_PK_OK_ON/OFF
575 * for frames > 1514 bytes
576 * - enable Rx of own packets SK_SELF_RX_ON/OFF
577 *
578 * for incoming packets may be enabled/disabled by this function.
579 * Additional modes may be added later.
580 * Multiple modes can be enabled/disabled at the same time.
581 * The new configuration is written to the Rx Command register immediately.
582 *
583 * Returns:
584 * nothing
585 */
586static void SkGmSetRxCmd(
587SK_AC *pAC, /* adapter context */
588SK_IOC IoC, /* IO context */
589int Port, /* Port Index (MAC_1 + n) */
590int Mode) /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF,
591 SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
592{
593 SK_U16 OldRxCmd;
594 SK_U16 RxCmd;
595
596 if ((Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) != 0) {
597
598 GM_IN16(IoC, Port, GM_RX_CTRL, &OldRxCmd);
599
600 RxCmd = OldRxCmd;
601
602 if ((Mode & SK_STRIP_FCS_ON) != 0) {
603 RxCmd |= GM_RXCR_CRC_DIS;
604 }
605 else {
606 RxCmd &= ~GM_RXCR_CRC_DIS;
607 }
608 /* Write the new mode to the Rx control register if required */
609 if (OldRxCmd != RxCmd) {
610 GM_OUT16(IoC, Port, GM_RX_CTRL, RxCmd);
611 }
612 }
613
614 if ((Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) != 0) {
615
616 GM_IN16(IoC, Port, GM_SERIAL_MODE, &OldRxCmd);
617
618 RxCmd = OldRxCmd;
619
620 if ((Mode & SK_BIG_PK_OK_ON) != 0) {
621 RxCmd |= GM_SMOD_JUMBO_ENA;
622 }
623 else {
624 RxCmd &= ~GM_SMOD_JUMBO_ENA;
625 }
626 /* Write the new mode to the Rx control register if required */
627 if (OldRxCmd != RxCmd) {
628 GM_OUT16(IoC, Port, GM_SERIAL_MODE, RxCmd);
629 }
630 }
631} /* SkGmSetRxCmd */
632
633
634/******************************************************************************
635 *
636 * SkMacSetRxCmd() - Modify the value of the MAC's Rx Control Register
637 *
638 * Description: modifies the MAC's Rx Control reg. dep. on board type
639 *
640 * Returns:
641 * nothing
642 */
643void SkMacSetRxCmd(
644SK_AC *pAC, /* adapter context */
645SK_IOC IoC, /* IO context */
646int Port, /* Port Index (MAC_1 + n) */
647int Mode) /* Rx Mode */
648{
649 if (pAC->GIni.GIGenesis) {
650
651 SkXmSetRxCmd(pAC, IoC, Port, Mode);
652 }
653 else {
654
655 SkGmSetRxCmd(pAC, IoC, Port, Mode);
656 }
657
658} /* SkMacSetRxCmd */
659
660
661/******************************************************************************
662 *
663 * SkMacCrcGener() - Enable / Disable CRC Generation
664 *
665 * Description: enables / disables CRC generation dep. on board type
666 *
667 * Returns:
668 * nothing
669 */
670void SkMacCrcGener(
671SK_AC *pAC, /* adapter context */
672SK_IOC IoC, /* IO context */
673int Port, /* Port Index (MAC_1 + n) */
674SK_BOOL Enable) /* Enable / Disable */
675{
676 SK_U16 Word;
677
678 if (pAC->GIni.GIGenesis) {
679
680 XM_IN16(IoC, Port, XM_TX_CMD, &Word);
681
682 if (Enable) {
683 Word &= ~XM_TX_NO_CRC;
684 }
685 else {
686 Word |= XM_TX_NO_CRC;
687 }
688 /* setup Tx Command Register */
689 XM_OUT16(IoC, Port, XM_TX_CMD, Word);
690 }
691 else {
692
693 GM_IN16(IoC, Port, GM_TX_CTRL, &Word);
694
695 if (Enable) {
696 Word &= ~GM_TXCR_CRC_DIS;
697 }
698 else {
699 Word |= GM_TXCR_CRC_DIS;
700 }
701 /* setup Tx Control Register */
702 GM_OUT16(IoC, Port, GM_TX_CTRL, Word);
703 }
704
705} /* SkMacCrcGener*/
706
707#endif /* SK_DIAG */
708
709
710#ifdef GENESIS
711/******************************************************************************
712 *
713 * SkXmClrExactAddr() - Clear Exact Match Address Registers
714 *
715 * Description:
716 * All Exact Match Address registers of the XMAC 'Port' will be
717 * cleared starting with 'StartNum' up to (and including) the
718 * Exact Match address number of 'StopNum'.
719 *
720 * Returns:
721 * nothing
722 */
723void SkXmClrExactAddr(
724SK_AC *pAC, /* adapter context */
725SK_IOC IoC, /* IO context */
726int Port, /* Port Index (MAC_1 + n) */
727int StartNum, /* Begin with this Address Register Index (0..15) */
728int StopNum) /* Stop after finished with this Register Idx (0..15) */
729{
730 int i;
731 SK_U16 ZeroAddr[3] = {0x0000, 0x0000, 0x0000};
732
733 if ((unsigned)StartNum > 15 || (unsigned)StopNum > 15 ||
734 StartNum > StopNum) {
735
736 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E001, SKERR_HWI_E001MSG);
737 return;
738 }
739
740 for (i = StartNum; i <= StopNum; i++) {
741 XM_OUTADDR(IoC, Port, XM_EXM(i), &ZeroAddr[0]);
742 }
743} /* SkXmClrExactAddr */
744#endif /* GENESIS */
745
746
747/******************************************************************************
748 *
749 * SkMacFlushTxFifo() - Flush the MAC's transmit FIFO
750 *
751 * Description:
752 * Flush the transmit FIFO of the MAC specified by the index 'Port'
753 *
754 * Returns:
755 * nothing
756 */
757void SkMacFlushTxFifo(
758SK_AC *pAC, /* adapter context */
759SK_IOC IoC, /* IO context */
760int Port) /* Port Index (MAC_1 + n) */
761{
762#ifdef GENESIS
763 SK_U32 MdReg;
764
765 if (pAC->GIni.GIGenesis) {
766
767 XM_IN32(IoC, Port, XM_MODE, &MdReg);
768
769 XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FTF);
770 }
771#endif /* GENESIS */
772
773#ifdef YUKON
774 if (pAC->GIni.GIYukon) {
775 /* no way to flush the FIFO we have to issue a reset */
776 /* TBD */
777 }
778#endif /* YUKON */
779
780} /* SkMacFlushTxFifo */
781
782
783/******************************************************************************
784 *
785 * SkMacFlushRxFifo() - Flush the MAC's receive FIFO
786 *
787 * Description:
788 * Flush the receive FIFO of the MAC specified by the index 'Port'
789 *
790 * Returns:
791 * nothing
792 */
793void SkMacFlushRxFifo(
794SK_AC *pAC, /* adapter context */
795SK_IOC IoC, /* IO context */
796int Port) /* Port Index (MAC_1 + n) */
797{
798#ifdef GENESIS
799 SK_U32 MdReg;
800
801 if (pAC->GIni.GIGenesis) {
802
803 XM_IN32(IoC, Port, XM_MODE, &MdReg);
804
805 XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FRF);
806 }
807#endif /* GENESIS */
808
809#ifdef YUKON
810 if (pAC->GIni.GIYukon) {
811 /* no way to flush the FIFO we have to issue a reset */
812 /* TBD */
813 }
814#endif /* YUKON */
815
816} /* SkMacFlushRxFifo */
817
818
819#ifdef GENESIS
820/******************************************************************************
821 *
822 * SkXmSoftRst() - Do a XMAC software reset
823 *
824 * Description:
825 * The PHY registers should not be destroyed during this
826 * kind of software reset. Therefore the XMAC Software Reset
827 * (XM_GP_RES_MAC bit in XM_GP_PORT) must not be used!
828 *
829 * The software reset is done by
830 * - disabling the Rx and Tx state machine,
831 * - resetting the statistics module,
832 * - clear all other significant XMAC Mode,
833 * Command, and Control Registers
834 * - clearing the Hash Register and the
835 * Exact Match Address registers, and
836 * - flushing the XMAC's Rx and Tx FIFOs.
837 *
838 * Note:
839 * Another requirement when stopping the XMAC is to
840 * avoid sending corrupted frames on the network.
841 * Disabling the Tx state machine will NOT interrupt
842 * the currently transmitted frame. But we must take care
843 * that the Tx FIFO is cleared AFTER the current frame
844 * is complete sent to the network.
845 *
846 * It takes about 12ns to send a frame with 1538 bytes.
847 * One PCI clock goes at least 15ns (66MHz). Therefore
848 * after reading XM_GP_PORT back, we are sure that the
849 * transmitter is disabled AND idle. And this means
850 * we may flush the transmit FIFO now.
851 *
852 * Returns:
853 * nothing
854 */
855static void SkXmSoftRst(
856SK_AC *pAC, /* adapter context */
857SK_IOC IoC, /* IO context */
858int Port) /* Port Index (MAC_1 + n) */
859{
860 SK_U16 ZeroAddr[4] = {0x0000, 0x0000, 0x0000, 0x0000};
861
862 /* reset the statistics module */
863 XM_OUT32(IoC, Port, XM_GP_PORT, XM_GP_RES_STAT);
864
865 /* disable all XMAC IRQs */
866 XM_OUT16(IoC, Port, XM_IMSK, 0xffff);
867
868 XM_OUT32(IoC, Port, XM_MODE, 0); /* clear Mode Reg */
869
870 XM_OUT16(IoC, Port, XM_TX_CMD, 0); /* reset TX CMD Reg */
871 XM_OUT16(IoC, Port, XM_RX_CMD, 0); /* reset RX CMD Reg */
872
873 /* disable all PHY IRQs */
874 switch (pAC->GIni.GP[Port].PhyType) {
875 case SK_PHY_BCOM:
876 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, 0xffff);
877 break;
878#ifdef OTHER_PHY
879 case SK_PHY_LONE:
880 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, 0);
881 break;
882 case SK_PHY_NAT:
883 /* todo: National
884 SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, 0xffff); */
885 break;
886#endif /* OTHER_PHY */
887 }
888
889 /* clear the Hash Register */
890 XM_OUTHASH(IoC, Port, XM_HSM, &ZeroAddr);
891
892 /* clear the Exact Match Address registers */
893 SkXmClrExactAddr(pAC, IoC, Port, 0, 15);
894
895 /* clear the Source Check Address registers */
896 XM_OUTHASH(IoC, Port, XM_SRC_CHK, &ZeroAddr);
897
898} /* SkXmSoftRst */
899
900
901/******************************************************************************
902 *
903 * SkXmHardRst() - Do a XMAC hardware reset
904 *
905 * Description:
906 * The XMAC of the specified 'Port' and all connected devices
907 * (PHY and SERDES) will receive a reset signal on its *Reset pins.
908 * External PHYs must be reset by clearing a bit in the GPIO register
909 * (Timing requirements: Broadcom: 400ns, Level One: none, National: 80ns).
910 *
911 * ATTENTION:
912 * It is absolutely necessary to reset the SW_RST Bit first
913 * before calling this function.
914 *
915 * Returns:
916 * nothing
917 */
918static void SkXmHardRst(
919SK_AC *pAC, /* adapter context */
920SK_IOC IoC, /* IO context */
921int Port) /* Port Index (MAC_1 + n) */
922{
923 SK_U32 Reg;
924 int i;
925 int TOut;
926 SK_U16 Word;
927
928 for (i = 0; i < 4; i++) {
929 /* TX_MFF_CTRL1 has 32 bits, but only the lowest 16 bits are used */
930 SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
931
932 TOut = 0;
933 do {
934 if (TOut++ > 10000) {
935 /*
936 * Adapter seems to be in RESET state.
937 * Registers cannot be written.
938 */
939 return;
940 }
941
942 SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_SET_MAC_RST);
943
944 SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &Word);
945
946 } while ((Word & MFF_SET_MAC_RST) == 0);
947 }
948
949 /* For external PHYs there must be special handling */
950 if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
951
952 SK_IN32(IoC, B2_GP_IO, &Reg);
953
954 if (Port == 0) {
955 Reg |= GP_DIR_0; /* set to output */
956 Reg &= ~GP_IO_0; /* set PHY reset (active low) */
957 }
958 else {
959 Reg |= GP_DIR_2; /* set to output */
960 Reg &= ~GP_IO_2; /* set PHY reset (active low) */
961 }
962 /* reset external PHY */
963 SK_OUT32(IoC, B2_GP_IO, Reg);
964
965 /* short delay */
966 SK_IN32(IoC, B2_GP_IO, &Reg);
967 }
968} /* SkXmHardRst */
969
970
971/******************************************************************************
972 *
973 * SkXmClearRst() - Release the PHY & XMAC reset
974 *
975 * Description:
976 *
977 * Returns:
978 * nothing
979 */
980static void SkXmClearRst(
981SK_AC *pAC, /* adapter context */
982SK_IOC IoC, /* IO context */
983int Port) /* Port Index (MAC_1 + n) */
984{
985 SK_U32 DWord;
986
987 /* clear HW reset */
988 SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
989
990 if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
991
992 SK_IN32(IoC, B2_GP_IO, &DWord);
993
994 if (Port == 0) {
995 DWord |= (GP_DIR_0 | GP_IO_0); /* set to output */
996 }
997 else {
998 DWord |= (GP_DIR_2 | GP_IO_2); /* set to output */
999 }
1000 /* Clear PHY reset */
1001 SK_OUT32(IoC, B2_GP_IO, DWord);
1002
1003 /* Enable GMII interface */
1004 XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD);
1005 }
1006} /* SkXmClearRst */
1007#endif /* GENESIS */
1008
1009
1010#ifdef YUKON
1011/******************************************************************************
1012 *
1013 * SkGmSoftRst() - Do a GMAC software reset
1014 *
1015 * Description:
1016 * The GPHY registers should not be destroyed during this
1017 * kind of software reset.
1018 *
1019 * Returns:
1020 * nothing
1021 */
1022static void SkGmSoftRst(
1023SK_AC *pAC, /* adapter context */
1024SK_IOC IoC, /* IO context */
1025int Port) /* Port Index (MAC_1 + n) */
1026{
1027 SK_U16 EmptyHash[4] = {0x0000, 0x0000, 0x0000, 0x0000};
1028 SK_U16 RxCtrl;
1029
1030 /* reset the statistics module */
1031
1032 /* disable all GMAC IRQs */
1033 SK_OUT8(IoC, GMAC_IRQ_MSK, 0);
1034
1035 /* disable all PHY IRQs */
1036 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0);
1037
1038 /* clear the Hash Register */
1039 GM_OUTHASH(IoC, Port, GM_MC_ADDR_H1, EmptyHash);
1040
1041 /* Enable Unicast and Multicast filtering */
1042 GM_IN16(IoC, Port, GM_RX_CTRL, &RxCtrl);
1043
1044 GM_OUT16(IoC, Port, GM_RX_CTRL,
1045 (SK_U16)(RxCtrl | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA));
1046
1047} /* SkGmSoftRst */
1048
1049
1050/******************************************************************************
1051 *
1052 * SkGmHardRst() - Do a GMAC hardware reset
1053 *
1054 * Description:
1055 *
1056 * Returns:
1057 * nothing
1058 */
1059static void SkGmHardRst(
1060SK_AC *pAC, /* adapter context */
1061SK_IOC IoC, /* IO context */
1062int Port) /* Port Index (MAC_1 + n) */
1063{
1064 SK_U32 DWord;
1065
1066 /* WA code for COMA mode */
1067 if (pAC->GIni.GIYukonLite &&
1068 pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
1069
1070 SK_IN32(IoC, B2_GP_IO, &DWord);
1071
1072 DWord |= (GP_DIR_9 | GP_IO_9);
1073
1074 /* set PHY reset */
1075 SK_OUT32(IoC, B2_GP_IO, DWord);
1076 }
1077
1078 /* set GPHY Control reset */
1079 SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET);
1080
1081 /* set GMAC Control reset */
1082 SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
1083
1084} /* SkGmHardRst */
1085
1086
1087/******************************************************************************
1088 *
1089 * SkGmClearRst() - Release the GPHY & GMAC reset
1090 *
1091 * Description:
1092 *
1093 * Returns:
1094 * nothing
1095 */
1096static void SkGmClearRst(
1097SK_AC *pAC, /* adapter context */
1098SK_IOC IoC, /* IO context */
1099int Port) /* Port Index (MAC_1 + n) */
1100{
1101 SK_U32 DWord;
1102
1103#ifdef XXX
1104 /* clear GMAC Control reset */
1105 SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR);
1106
1107 /* set GMAC Control reset */
1108 SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
1109#endif /* XXX */
1110
1111 /* WA code for COMA mode */
1112 if (pAC->GIni.GIYukonLite &&
1113 pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
1114
1115 SK_IN32(IoC, B2_GP_IO, &DWord);
1116
1117 DWord |= GP_DIR_9; /* set to output */
1118 DWord &= ~GP_IO_9; /* clear PHY reset (active high) */
1119
1120 /* clear PHY reset */
1121 SK_OUT32(IoC, B2_GP_IO, DWord);
1122 }
1123
1124 /* set HWCFG_MODE */
1125 DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |
1126 GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE |
1127 (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP :
1128 GPC_HWCFG_GMII_FIB);
1129
1130 /* set GPHY Control reset */
1131 SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET);
1132
1133 /* release GPHY Control reset */
1134 SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR);
1135
1136#ifdef VCPU
1137 VCpuWait(9000);
1138#endif /* VCPU */
1139
1140 /* clear GMAC Control reset */
1141 SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);
1142
1143#ifdef VCPU
1144 VCpuWait(2000);
1145
1146 SK_IN32(IoC, MR_ADDR(Port, GPHY_CTRL), &DWord);
1147
1148 SK_IN32(IoC, B0_ISRC, &DWord);
1149#endif /* VCPU */
1150
1151} /* SkGmClearRst */
1152#endif /* YUKON */
1153
1154
1155/******************************************************************************
1156 *
1157 * SkMacSoftRst() - Do a MAC software reset
1158 *
1159 * Description: calls a MAC software reset routine dep. on board type
1160 *
1161 * Returns:
1162 * nothing
1163 */
1164void SkMacSoftRst(
1165SK_AC *pAC, /* adapter context */
1166SK_IOC IoC, /* IO context */
1167int Port) /* Port Index (MAC_1 + n) */
1168{
1169 SK_GEPORT *pPrt;
1170
1171 pPrt = &pAC->GIni.GP[Port];
1172
1173 /* disable receiver and transmitter */
1174 SkMacRxTxDisable(pAC, IoC, Port);
1175
1176#ifdef GENESIS
1177 if (pAC->GIni.GIGenesis) {
1178
1179 SkXmSoftRst(pAC, IoC, Port);
1180 }
1181#endif /* GENESIS */
1182
1183#ifdef YUKON
1184 if (pAC->GIni.GIYukon) {
1185
1186 SkGmSoftRst(pAC, IoC, Port);
1187 }
1188#endif /* YUKON */
1189
1190 /* flush the MAC's Rx and Tx FIFOs */
1191 SkMacFlushTxFifo(pAC, IoC, Port);
1192
1193 SkMacFlushRxFifo(pAC, IoC, Port);
1194
1195 pPrt->PState = SK_PRT_STOP;
1196
1197} /* SkMacSoftRst */
1198
1199
1200/******************************************************************************
1201 *
1202 * SkMacHardRst() - Do a MAC hardware reset
1203 *
1204 * Description: calls a MAC hardware reset routine dep. on board type
1205 *
1206 * Returns:
1207 * nothing
1208 */
1209void SkMacHardRst(
1210SK_AC *pAC, /* adapter context */
1211SK_IOC IoC, /* IO context */
1212int Port) /* Port Index (MAC_1 + n) */
1213{
1214
1215#ifdef GENESIS
1216 if (pAC->GIni.GIGenesis) {
1217
1218 SkXmHardRst(pAC, IoC, Port);
1219 }
1220#endif /* GENESIS */
1221
1222#ifdef YUKON
1223 if (pAC->GIni.GIYukon) {
1224
1225 SkGmHardRst(pAC, IoC, Port);
1226 }
1227#endif /* YUKON */
1228
1229 pAC->GIni.GP[Port].PState = SK_PRT_RESET;
1230
1231} /* SkMacHardRst */
1232
1233
1234/******************************************************************************
1235 *
1236 * SkMacClearRst() - Clear the MAC reset
1237 *
1238 * Description: calls a clear MAC reset routine dep. on board type
1239 *
1240 * Returns:
1241 * nothing
1242 */
1243void SkMacClearRst(
1244SK_AC *pAC, /* adapter context */
1245SK_IOC IoC, /* IO context */
1246int Port) /* Port Index (MAC_1 + n) */
1247{
1248
1249#ifdef GENESIS
1250 if (pAC->GIni.GIGenesis) {
1251
1252 SkXmClearRst(pAC, IoC, Port);
1253 }
1254#endif /* GENESIS */
1255
1256#ifdef YUKON
1257 if (pAC->GIni.GIYukon) {
1258
1259 SkGmClearRst(pAC, IoC, Port);
1260 }
1261#endif /* YUKON */
1262
1263} /* SkMacClearRst */
1264
1265
1266#ifdef GENESIS
1267/******************************************************************************
1268 *
1269 * SkXmInitMac() - Initialize the XMAC II
1270 *
1271 * Description:
1272 * Initialize the XMAC of the specified port.
1273 * The XMAC must be reset or stopped before calling this function.
1274 *
1275 * Note:
1276 * The XMAC's Rx and Tx state machine is still disabled when returning.
1277 *
1278 * Returns:
1279 * nothing
1280 */
1281void SkXmInitMac(
1282SK_AC *pAC, /* adapter context */
1283SK_IOC IoC, /* IO context */
1284int Port) /* Port Index (MAC_1 + n) */
1285{
1286 SK_GEPORT *pPrt;
1287 int i;
1288 SK_U16 SWord;
1289
1290 pPrt = &pAC->GIni.GP[Port];
1291
1292 if (pPrt->PState == SK_PRT_STOP) {
1293 /* Port State: SK_PRT_STOP */
1294 /* Verify that the reset bit is cleared */
1295 SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord);
1296
1297 if ((SWord & MFF_SET_MAC_RST) != 0) {
1298 /* PState does not match HW state */
1299 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG);
1300 /* Correct it */
1301 pPrt->PState = SK_PRT_RESET;
1302 }
1303 }
1304
1305 if (pPrt->PState == SK_PRT_RESET) {
1306
1307 SkXmClearRst(pAC, IoC, Port);
1308
1309 if (pPrt->PhyType != SK_PHY_XMAC) {
1310 /* read Id from external PHY (all have the same address) */
1311 SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_ID1, &pPrt->PhyId1);
1312
1313 /*
1314 * Optimize MDIO transfer by suppressing preamble.
1315 * Must be done AFTER first access to BCOM chip.
1316 */
1317 XM_IN16(IoC, Port, XM_MMU_CMD, &SWord);
1318
1319 XM_OUT16(IoC, Port, XM_MMU_CMD, SWord | XM_MMU_NO_PRE);
1320
1321 if (pPrt->PhyId1 == PHY_BCOM_ID1_C0) {
1322 /*
1323 * Workaround BCOM Errata for the C0 type.
1324 * Write magic patterns to reserved registers.
1325 */
1326 i = 0;
1327 while (BcomRegC0Hack[i].PhyReg != 0) {
1328 SkXmPhyWrite(pAC, IoC, Port, BcomRegC0Hack[i].PhyReg,
1329 BcomRegC0Hack[i].PhyVal);
1330 i++;
1331 }
1332 }
1333 else if (pPrt->PhyId1 == PHY_BCOM_ID1_A1) {
1334 /*
1335 * Workaround BCOM Errata for the A1 type.
1336 * Write magic patterns to reserved registers.
1337 */
1338 i = 0;
1339 while (BcomRegA1Hack[i].PhyReg != 0) {
1340 SkXmPhyWrite(pAC, IoC, Port, BcomRegA1Hack[i].PhyReg,
1341 BcomRegA1Hack[i].PhyVal);
1342 i++;
1343 }
1344 }
1345
1346 /*
1347 * Workaround BCOM Errata (#10523) for all BCom PHYs.
1348 * Disable Power Management after reset.
1349 */
1350 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord);
1351
1352 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
1353 (SK_U16)(SWord | PHY_B_AC_DIS_PM));
1354
1355 /* PHY LED initialization is done in SkGeXmitLED() */
1356 }
1357
1358 /* Dummy read the Interrupt source register */
1359 XM_IN16(IoC, Port, XM_ISRC, &SWord);
1360
1361 /*
1362 * The auto-negotiation process starts immediately after
1363 * clearing the reset. The auto-negotiation process should be
1364 * started by the SIRQ, therefore stop it here immediately.
1365 */
1366 SkMacInitPhy(pAC, IoC, Port, SK_FALSE);
1367
1368#ifdef TEST_ONLY
1369 /* temp. code: enable signal detect */
1370 /* WARNING: do not override GMII setting above */
1371 XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_COM4SIG);
1372#endif
1373 }
1374
1375 /*
1376 * configure the XMACs Station Address
1377 * B2_MAC_2 = xx xx xx xx xx x1 is programmed to XMAC A
1378 * B2_MAC_3 = xx xx xx xx xx x2 is programmed to XMAC B
1379 */
1380 for (i = 0; i < 3; i++) {
1381 /*
1382 * The following 2 statements are together endianess
1383 * independent. Remember this when changing.
1384 */
1385 SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);
1386
1387 XM_OUT16(IoC, Port, (XM_SA + i * 2), SWord);
1388 }
1389
1390 /* Tx Inter Packet Gap (XM_TX_IPG): use default */
1391 /* Tx High Water Mark (XM_TX_HI_WM): use default */
1392 /* Tx Low Water Mark (XM_TX_LO_WM): use default */
1393 /* Host Request Threshold (XM_HT_THR): use default */
1394 /* Rx Request Threshold (XM_RX_THR): use default */
1395 /* Rx Low Water Mark (XM_RX_LO_WM): use default */
1396
1397 /* configure Rx High Water Mark (XM_RX_HI_WM) */
1398 XM_OUT16(IoC, Port, XM_RX_HI_WM, SK_XM_RX_HI_WM);
1399
1400 /* Configure Tx Request Threshold */
1401 SWord = SK_XM_THR_SL; /* for single port */
1402
1403 if (pAC->GIni.GIMacsFound > 1) {
1404 switch (pAC->GIni.GIPortUsage) {
1405 case SK_RED_LINK:
1406 SWord = SK_XM_THR_REDL; /* redundant link */
1407 break;
1408 case SK_MUL_LINK:
1409 SWord = SK_XM_THR_MULL; /* load balancing */
1410 break;
1411 case SK_JUMBO_LINK:
1412 SWord = SK_XM_THR_JUMBO; /* jumbo frames */
1413 break;
1414 default:
1415 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E014, SKERR_HWI_E014MSG);
1416 break;
1417 }
1418 }
1419 XM_OUT16(IoC, Port, XM_TX_THR, SWord);
1420
1421 /* setup register defaults for the Tx Command Register */
1422 XM_OUT16(IoC, Port, XM_TX_CMD, XM_TX_AUTO_PAD);
1423
1424 /* setup register defaults for the Rx Command Register */
1425 SWord = XM_RX_STRIP_FCS | XM_RX_LENERR_OK;
1426
1427 if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
1428 SWord |= XM_RX_BIG_PK_OK;
1429 }
1430
1431 if (pPrt->PLinkMode == SK_LMODE_HALF) {
1432 /*
1433 * If in manual half duplex mode the other side might be in
1434 * full duplex mode, so ignore if a carrier extension is not seen
1435 * on frames received
1436 */
1437 SWord |= XM_RX_DIS_CEXT;
1438 }
1439
1440 XM_OUT16(IoC, Port, XM_RX_CMD, SWord);
1441
1442 /*
1443 * setup register defaults for the Mode Register
1444 * - Don't strip error frames to avoid Store & Forward
1445 * on the Rx side.
1446 * - Enable 'Check Station Address' bit
1447 * - Enable 'Check Address Array' bit
1448 */
1449 XM_OUT32(IoC, Port, XM_MODE, XM_DEF_MODE);
1450
1451 /*
1452 * Initialize the Receive Counter Event Mask (XM_RX_EV_MSK)
1453 * - Enable all bits excepting 'Octets Rx OK Low CntOv'
1454 * and 'Octets Rx OK Hi Cnt Ov'.
1455 */
1456 XM_OUT32(IoC, Port, XM_RX_EV_MSK, XMR_DEF_MSK);
1457
1458 /*
1459 * Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK)
1460 * - Enable all bits excepting 'Octets Tx OK Low CntOv'
1461 * and 'Octets Tx OK Hi Cnt Ov'.
1462 */
1463 XM_OUT32(IoC, Port, XM_TX_EV_MSK, XMT_DEF_MSK);
1464
1465 /*
1466 * Do NOT init XMAC interrupt mask here.
1467 * All interrupts remain disable until link comes up!
1468 */
1469
1470 /*
1471 * Any additional configuration changes may be done now.
1472 * The last action is to enable the Rx and Tx state machine.
1473 * This should be done after the auto-negotiation process
1474 * has been completed successfully.
1475 */
1476} /* SkXmInitMac */
1477#endif /* GENESIS */
1478
1479
1480#ifdef YUKON
1481/******************************************************************************
1482 *
1483 * SkGmInitMac() - Initialize the GMAC
1484 *
1485 * Description:
1486 * Initialize the GMAC of the specified port.
1487 * The GMAC must be reset or stopped before calling this function.
1488 *
1489 * Note:
1490 * The GMAC's Rx and Tx state machine is still disabled when returning.
1491 *
1492 * Returns:
1493 * nothing
1494 */
1495void SkGmInitMac(
1496SK_AC *pAC, /* adapter context */
1497SK_IOC IoC, /* IO context */
1498int Port) /* Port Index (MAC_1 + n) */
1499{
1500 SK_GEPORT *pPrt;
1501 int i;
1502 SK_U16 SWord;
1503 SK_U32 DWord;
1504
1505 pPrt = &pAC->GIni.GP[Port];
1506
1507 if (pPrt->PState == SK_PRT_STOP) {
1508 /* Port State: SK_PRT_STOP */
1509 /* Verify that the reset bit is cleared */
1510 SK_IN32(IoC, MR_ADDR(Port, GMAC_CTRL), &DWord);
1511
1512 if ((DWord & GMC_RST_SET) != 0) {
1513 /* PState does not match HW state */
1514 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG);
1515 /* Correct it */
1516 pPrt->PState = SK_PRT_RESET;
1517 }
1518 }
1519
1520 if (pPrt->PState == SK_PRT_RESET) {
1521
1522 SkGmHardRst(pAC, IoC, Port);
1523
1524 SkGmClearRst(pAC, IoC, Port);
1525
1526 /* Auto-negotiation ? */
1527 if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
1528 /* Auto-negotiation disabled */
1529
1530 /* get General Purpose Control */
1531 GM_IN16(IoC, Port, GM_GP_CTRL, &SWord);
1532
1533 /* disable auto-update for speed, duplex and flow-control */
1534 SWord |= GM_GPCR_AU_ALL_DIS;
1535
1536 /* setup General Purpose Control Register */
1537 GM_OUT16(IoC, Port, GM_GP_CTRL, SWord);
1538
1539 SWord = GM_GPCR_AU_ALL_DIS;
1540 }
1541 else {
1542 SWord = 0;
1543 }
1544
1545 /* speed settings */
1546 switch (pPrt->PLinkSpeed) {
1547 case SK_LSPEED_AUTO:
1548 case SK_LSPEED_1000MBPS:
1549 SWord |= GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100;
1550 break;
1551 case SK_LSPEED_100MBPS:
1552 SWord |= GM_GPCR_SPEED_100;
1553 break;
1554 case SK_LSPEED_10MBPS:
1555 break;
1556 }
1557
1558 /* duplex settings */
1559 if (pPrt->PLinkMode != SK_LMODE_HALF) {
1560 /* set full duplex */
1561 SWord |= GM_GPCR_DUP_FULL;
1562 }
1563
1564 /* flow-control settings */
1565 switch (pPrt->PFlowCtrlMode) {
1566 case SK_FLOW_MODE_NONE:
1567 /* set Pause Off */
1568 SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_OFF);
1569 /* disable Tx & Rx flow-control */
1570 SWord |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
1571 break;
1572 case SK_FLOW_MODE_LOC_SEND:
1573 /* disable Rx flow-control */
1574 SWord |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
1575 break;
1576 case SK_FLOW_MODE_SYMMETRIC:
1577 case SK_FLOW_MODE_SYM_OR_REM:
1578 /* enable Tx & Rx flow-control */
1579 break;
1580 }
1581
1582 /* setup General Purpose Control Register */
1583 GM_OUT16(IoC, Port, GM_GP_CTRL, SWord);
1584
1585 /* dummy read the Interrupt Source Register */
1586 SK_IN16(IoC, GMAC_IRQ_SRC, &SWord);
1587
1588#ifndef VCPU
1589 /* read Id from PHY */
1590 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_ID1, &pPrt->PhyId1);
1591
1592 SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
1593#endif /* VCPU */
1594 }
1595
1596 (void)SkGmResetCounter(pAC, IoC, Port);
1597
1598 /* setup Transmit Control Register */
1599 GM_OUT16(IoC, Port, GM_TX_CTRL, TX_COL_THR(pPrt->PMacColThres));
1600
1601 /* setup Receive Control Register */
1602 GM_OUT16(IoC, Port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA |
1603 GM_RXCR_CRC_DIS);
1604
1605 /* setup Transmit Flow Control Register */
1606 GM_OUT16(IoC, Port, GM_TX_FLOW_CTRL, 0xffff);
1607
1608 /* setup Transmit Parameter Register */
1609#ifdef VCPU
1610 GM_IN16(IoC, Port, GM_TX_PARAM, &SWord);
1611#endif /* VCPU */
1612
1613 SWord = TX_JAM_LEN_VAL(pPrt->PMacJamLen) |
1614 TX_JAM_IPG_VAL(pPrt->PMacJamIpgVal) |
1615 TX_IPG_JAM_DATA(pPrt->PMacJamIpgData);
1616
1617 GM_OUT16(IoC, Port, GM_TX_PARAM, SWord);
1618
1619 /* configure the Serial Mode Register */
1620#ifdef VCPU
1621 GM_IN16(IoC, Port, GM_SERIAL_MODE, &SWord);
1622#endif /* VCPU */
1623
1624 SWord = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(pPrt->PMacIpgData);
1625
1626 if (pPrt->PMacLimit4) {
1627 /* reset of collision counter after 4 consecutive collisions */
1628 SWord |= GM_SMOD_LIMIT_4;
1629 }
1630
1631 if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
1632 /* enable jumbo mode (Max. Frame Length = 9018) */
1633 SWord |= GM_SMOD_JUMBO_ENA;
1634 }
1635
1636 GM_OUT16(IoC, Port, GM_SERIAL_MODE, SWord);
1637
1638 /*
1639 * configure the GMACs Station Addresses
1640 * in PROM you can find our addresses at:
1641 * B2_MAC_1 = xx xx xx xx xx x0 virtual address
1642 * B2_MAC_2 = xx xx xx xx xx x1 is programmed to GMAC A
1643 * B2_MAC_3 = xx xx xx xx xx x2 is reserved for DualPort
1644 */
1645
1646 for (i = 0; i < 3; i++) {
1647 /*
1648 * The following 2 statements are together endianess
1649 * independent. Remember this when changing.
1650 */
1651 /* physical address: will be used for pause frames */
1652 SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);
1653
1654#ifdef WA_DEV_16
1655 /* WA for deviation #16 */
1656 if (pAC->GIni.GIChipId == CHIP_ID_YUKON && pAC->GIni.GIChipRev == 0) {
1657 /* swap the address bytes */
1658 SWord = ((SWord & 0xff00) >> 8) | ((SWord & 0x00ff) << 8);
1659
1660 /* write to register in reversed order */
1661 GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + (2 - i) * 4), SWord);
1662 }
1663 else {
1664 GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);
1665 }
1666#else
1667 GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);
1668#endif /* WA_DEV_16 */
1669
1670 /* virtual address: will be used for data */
1671 SK_IN16(IoC, (B2_MAC_1 + Port * 8 + i * 2), &SWord);
1672
1673 GM_OUT16(IoC, Port, (GM_SRC_ADDR_2L + i * 4), SWord);
1674
1675 /* reset Multicast filtering Hash registers 1-3 */
1676 GM_OUT16(IoC, Port, GM_MC_ADDR_H1 + 4*i, 0);
1677 }
1678
1679 /* reset Multicast filtering Hash register 4 */
1680 GM_OUT16(IoC, Port, GM_MC_ADDR_H4, 0);
1681
1682 /* enable interrupt mask for counter overflows */
1683 GM_OUT16(IoC, Port, GM_TX_IRQ_MSK, 0);
1684 GM_OUT16(IoC, Port, GM_RX_IRQ_MSK, 0);
1685 GM_OUT16(IoC, Port, GM_TR_IRQ_MSK, 0);
1686
1687#if defined(SK_DIAG) || defined(DEBUG)
1688 /* read General Purpose Status */
1689 GM_IN16(IoC, Port, GM_GP_STAT, &SWord);
1690
1691 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1692 ("MAC Stat Reg.=0x%04X\n", SWord));
1693#endif /* SK_DIAG || DEBUG */
1694
1695#ifdef SK_DIAG
1696 c_print("MAC Stat Reg=0x%04X\n", SWord);
1697#endif /* SK_DIAG */
1698
1699} /* SkGmInitMac */
1700#endif /* YUKON */
1701
1702
1703#ifdef GENESIS
1704/******************************************************************************
1705 *
1706 * SkXmInitDupMd() - Initialize the XMACs Duplex Mode
1707 *
1708 * Description:
1709 * This function initializes the XMACs Duplex Mode.
1710 * It should be called after successfully finishing
1711 * the Auto-negotiation Process
1712 *
1713 * Returns:
1714 * nothing
1715 */
1716void SkXmInitDupMd(
1717SK_AC *pAC, /* adapter context */
1718SK_IOC IoC, /* IO context */
1719int Port) /* Port Index (MAC_1 + n) */
1720{
1721 switch (pAC->GIni.GP[Port].PLinkModeStatus) {
1722 case SK_LMODE_STAT_AUTOHALF:
1723 case SK_LMODE_STAT_HALF:
1724 /* Configuration Actions for Half Duplex Mode */
1725 /*
1726 * XM_BURST = default value. We are probable not quick
1727 * enough at the 'XMAC' bus to burst 8kB.
1728 * The XMAC stops bursting if no transmit frames
1729 * are available or the burst limit is exceeded.
1730 */
1731 /* XM_TX_RT_LIM = default value (15) */
1732 /* XM_TX_STIME = default value (0xff = 4096 bit times) */
1733 break;
1734 case SK_LMODE_STAT_AUTOFULL:
1735 case SK_LMODE_STAT_FULL:
1736 /* Configuration Actions for Full Duplex Mode */
1737 /*
1738 * The duplex mode is configured by the PHY,
1739 * therefore it seems to be that there is nothing
1740 * to do here.
1741 */
1742 break;
1743 case SK_LMODE_STAT_UNKNOWN:
1744 default:
1745 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E007, SKERR_HWI_E007MSG);
1746 break;
1747 }
1748} /* SkXmInitDupMd */
1749
1750
1751/******************************************************************************
1752 *
1753 * SkXmInitPauseMd() - initialize the Pause Mode to be used for this port
1754 *
1755 * Description:
1756 * This function initializes the Pause Mode which should
1757 * be used for this port.
1758 * It should be called after successfully finishing
1759 * the Auto-negotiation Process
1760 *
1761 * Returns:
1762 * nothing
1763 */
1764void SkXmInitPauseMd(
1765SK_AC *pAC, /* adapter context */
1766SK_IOC IoC, /* IO context */
1767int Port) /* Port Index (MAC_1 + n) */
1768{
1769 SK_GEPORT *pPrt;
1770 SK_U32 DWord;
1771 SK_U16 Word;
1772
1773 pPrt = &pAC->GIni.GP[Port];
1774
1775 XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
1776
1777 if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_NONE ||
1778 pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) {
1779
1780 /* Disable Pause Frame Reception */
1781 Word |= XM_MMU_IGN_PF;
1782 }
1783 else {
1784 /*
1785 * enabling pause frame reception is required for 1000BT
1786 * because the XMAC is not reset if the link is going down
1787 */
1788 /* Enable Pause Frame Reception */
1789 Word &= ~XM_MMU_IGN_PF;
1790 }
1791
1792 XM_OUT16(IoC, Port, XM_MMU_CMD, Word);
1793
1794 XM_IN32(IoC, Port, XM_MODE, &DWord);
1795
1796 if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_SYMMETRIC ||
1797 pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) {
1798
1799 /*
1800 * Configure Pause Frame Generation
1801 * Use internal and external Pause Frame Generation.
1802 * Sending pause frames is edge triggered.
1803 * Send a Pause frame with the maximum pause time if
1804 * internal oder external FIFO full condition occurs.
1805 * Send a zero pause time frame to re-start transmission.
1806 */
1807
1808 /* XM_PAUSE_DA = '010000C28001' (default) */
1809
1810 /* XM_MAC_PTIME = 0xffff (maximum) */
1811 /* remember this value is defined in big endian (!) */
1812 XM_OUT16(IoC, Port, XM_MAC_PTIME, 0xffff);
1813
1814 /* Set Pause Mode in Mode Register */
1815 DWord |= XM_PAUSE_MODE;
1816
1817 /* Set Pause Mode in MAC Rx FIFO */
1818 SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_PAUSE);
1819 }
1820 else {
1821 /*
1822 * disable pause frame generation is required for 1000BT
1823 * because the XMAC is not reset if the link is going down
1824 */
1825 /* Disable Pause Mode in Mode Register */
1826 DWord &= ~XM_PAUSE_MODE;
1827
1828 /* Disable Pause Mode in MAC Rx FIFO */
1829 SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_DIS_PAUSE);
1830 }
1831
1832 XM_OUT32(IoC, Port, XM_MODE, DWord);
1833} /* SkXmInitPauseMd*/
1834
1835
1836/******************************************************************************
1837 *
1838 * SkXmInitPhyXmac() - Initialize the XMAC Phy registers
1839 *
1840 * Description: initializes all the XMACs Phy registers
1841 *
1842 * Note:
1843 *
1844 * Returns:
1845 * nothing
1846 */
1847static void SkXmInitPhyXmac(
1848SK_AC *pAC, /* adapter context */
1849SK_IOC IoC, /* IO context */
1850int Port, /* Port Index (MAC_1 + n) */
1851SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
1852{
1853 SK_GEPORT *pPrt;
1854 SK_U16 Ctrl;
1855
1856 pPrt = &pAC->GIni.GP[Port];
1857 Ctrl = 0;
1858
1859 /* Auto-negotiation ? */
1860 if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
1861 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1862 ("InitPhyXmac: no auto-negotiation Port %d\n", Port));
1863 /* Set DuplexMode in Config register */
1864 if (pPrt->PLinkMode == SK_LMODE_FULL) {
1865 Ctrl |= PHY_CT_DUP_MD;
1866 }
1867
1868 /*
1869 * Do NOT enable Auto-negotiation here. This would hold
1870 * the link down because no IDLEs are transmitted
1871 */
1872 }
1873 else {
1874 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1875 ("InitPhyXmac: with auto-negotiation Port %d\n", Port));
1876 /* Set Auto-negotiation advertisement */
1877
1878 /* Set Full/half duplex capabilities */
1879 switch (pPrt->PLinkMode) {
1880 case SK_LMODE_AUTOHALF:
1881 Ctrl |= PHY_X_AN_HD;
1882 break;
1883 case SK_LMODE_AUTOFULL:
1884 Ctrl |= PHY_X_AN_FD;
1885 break;
1886 case SK_LMODE_AUTOBOTH:
1887 Ctrl |= PHY_X_AN_FD | PHY_X_AN_HD;
1888 break;
1889 default:
1890 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
1891 SKERR_HWI_E015MSG);
1892 }
1893
1894 /* Set Flow-control capabilities */
1895 switch (pPrt->PFlowCtrlMode) {
1896 case SK_FLOW_MODE_NONE:
1897 Ctrl |= PHY_X_P_NO_PAUSE;
1898 break;
1899 case SK_FLOW_MODE_LOC_SEND:
1900 Ctrl |= PHY_X_P_ASYM_MD;
1901 break;
1902 case SK_FLOW_MODE_SYMMETRIC:
1903 Ctrl |= PHY_X_P_SYM_MD;
1904 break;
1905 case SK_FLOW_MODE_SYM_OR_REM:
1906 Ctrl |= PHY_X_P_BOTH_MD;
1907 break;
1908 default:
1909 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
1910 SKERR_HWI_E016MSG);
1911 }
1912
1913 /* Write AutoNeg Advertisement Register */
1914 SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_AUNE_ADV, Ctrl);
1915
1916 /* Restart Auto-negotiation */
1917 Ctrl = PHY_CT_ANE | PHY_CT_RE_CFG;
1918 }
1919
1920 if (DoLoop) {
1921 /* Set the Phy Loopback bit, too */
1922 Ctrl |= PHY_CT_LOOP;
1923 }
1924
1925 /* Write to the Phy control register */
1926 SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_CTRL, Ctrl);
1927} /* SkXmInitPhyXmac */
1928
1929
1930/******************************************************************************
1931 *
1932 * SkXmInitPhyBcom() - Initialize the Broadcom Phy registers
1933 *
1934 * Description: initializes all the Broadcom Phy registers
1935 *
1936 * Note:
1937 *
1938 * Returns:
1939 * nothing
1940 */
1941static void SkXmInitPhyBcom(
1942SK_AC *pAC, /* adapter context */
1943SK_IOC IoC, /* IO context */
1944int Port, /* Port Index (MAC_1 + n) */
1945SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
1946{
1947 SK_GEPORT *pPrt;
1948 SK_U16 Ctrl1;
1949 SK_U16 Ctrl2;
1950 SK_U16 Ctrl3;
1951 SK_U16 Ctrl4;
1952 SK_U16 Ctrl5;
1953
1954 Ctrl1 = PHY_CT_SP1000;
1955 Ctrl2 = 0;
1956 Ctrl3 = PHY_SEL_TYPE;
1957 Ctrl4 = PHY_B_PEC_EN_LTR;
1958 Ctrl5 = PHY_B_AC_TX_TST;
1959
1960 pPrt = &pAC->GIni.GP[Port];
1961
1962 /* manually Master/Slave ? */
1963 if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
1964 Ctrl2 |= PHY_B_1000C_MSE;
1965
1966 if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
1967 Ctrl2 |= PHY_B_1000C_MSC;
1968 }
1969 }
1970 /* Auto-negotiation ? */
1971 if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
1972 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1973 ("InitPhyBcom: no auto-negotiation Port %d\n", Port));
1974 /* Set DuplexMode in Config register */
1975 if (pPrt->PLinkMode == SK_LMODE_FULL) {
1976 Ctrl1 |= PHY_CT_DUP_MD;
1977 }
1978
1979 /* Determine Master/Slave manually if not already done */
1980 if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
1981 Ctrl2 |= PHY_B_1000C_MSE; /* set it to Slave */
1982 }
1983
1984 /*
1985 * Do NOT enable Auto-negotiation here. This would hold
1986 * the link down because no IDLES are transmitted
1987 */
1988 }
1989 else {
1990 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1991 ("InitPhyBcom: with auto-negotiation Port %d\n", Port));
1992 /* Set Auto-negotiation advertisement */
1993
1994 /*
1995 * Workaround BCOM Errata #1 for the C5 type.
1996 * 1000Base-T Link Acquisition Failure in Slave Mode
1997 * Set Repeater/DTE bit 10 of the 1000Base-T Control Register
1998 */
1999 Ctrl2 |= PHY_B_1000C_RD;
2000
2001 /* Set Full/half duplex capabilities */
2002 switch (pPrt->PLinkMode) {
2003 case SK_LMODE_AUTOHALF:
2004 Ctrl2 |= PHY_B_1000C_AHD;
2005 break;
2006 case SK_LMODE_AUTOFULL:
2007 Ctrl2 |= PHY_B_1000C_AFD;
2008 break;
2009 case SK_LMODE_AUTOBOTH:
2010 Ctrl2 |= PHY_B_1000C_AFD | PHY_B_1000C_AHD;
2011 break;
2012 default:
2013 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
2014 SKERR_HWI_E015MSG);
2015 }
2016
2017 /* Set Flow-control capabilities */
2018 switch (pPrt->PFlowCtrlMode) {
2019 case SK_FLOW_MODE_NONE:
2020 Ctrl3 |= PHY_B_P_NO_PAUSE;
2021 break;
2022 case SK_FLOW_MODE_LOC_SEND:
2023 Ctrl3 |= PHY_B_P_ASYM_MD;
2024 break;
2025 case SK_FLOW_MODE_SYMMETRIC:
2026 Ctrl3 |= PHY_B_P_SYM_MD;
2027 break;
2028 case SK_FLOW_MODE_SYM_OR_REM:
2029 Ctrl3 |= PHY_B_P_BOTH_MD;
2030 break;
2031 default:
2032 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
2033 SKERR_HWI_E016MSG);
2034 }
2035
2036 /* Restart Auto-negotiation */
2037 Ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG;
2038 }
2039
2040 /* Initialize LED register here? */
2041 /* No. Please do it in SkDgXmitLed() (if required) and swap
2042 init order of LEDs and XMAC. (MAl) */
2043
2044 /* Write 1000Base-T Control Register */
2045 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, Ctrl2);
2046 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2047 ("Set 1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
2048
2049 /* Write AutoNeg Advertisement Register */
2050 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, Ctrl3);
2051 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2052 ("Set Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3));
2053
2054 if (DoLoop) {
2055 /* Set the Phy Loopback bit, too */
2056 Ctrl1 |= PHY_CT_LOOP;
2057 }
2058
2059 if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
2060 /* configure FIFO to high latency for transmission of ext. packets */
2061 Ctrl4 |= PHY_B_PEC_HIGH_LA;
2062
2063 /* configure reception of extended packets */
2064 Ctrl5 |= PHY_B_AC_LONG_PACK;
2065
2066 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, Ctrl5);
2067 }
2068
2069 /* Configure LED Traffic Mode and Jumbo Frame usage if specified */
2070 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, Ctrl4);
2071
2072 /* Write to the Phy control register */
2073 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL, Ctrl1);
2074 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2075 ("PHY Control Reg=0x%04X\n", Ctrl1));
2076} /* SkXmInitPhyBcom */
2077#endif /* GENESIS */
2078
2079
2080#ifdef YUKON
2081#ifndef SK_SLIM
2082/******************************************************************************
2083 *
2084 * SkGmEnterLowPowerMode()
2085 *
2086 * Description:
2087 * This function sets the Marvell Alaska PHY to the low power mode
2088 * given by parameter mode.
2089 * The following low power modes are available:
2090 *
2091 * - Coma Mode (Deep Sleep):
2092 * Power consumption: ~15 - 30 mW
2093 * The PHY cannot wake up on its own.
2094 *
2095 * - IEEE 22.2.4.1.5 compatible power down mode
2096 * Power consumption: ~240 mW
2097 * The PHY cannot wake up on its own.
2098 *
2099 * - energy detect mode
2100 * Power consumption: ~160 mW
2101 * The PHY can wake up on its own by detecting activity
2102 * on the CAT 5 cable.
2103 *
2104 * - energy detect plus mode
2105 * Power consumption: ~150 mW
2106 * The PHY can wake up on its own by detecting activity
2107 * on the CAT 5 cable.
2108 * Connected devices can be woken up by sending normal link
2109 * pulses every one second.
2110 *
2111 * Note:
2112 *
2113 * Returns:
2114 * 0: ok
2115 * 1: error
2116 */
2117int SkGmEnterLowPowerMode(
2118SK_AC *pAC, /* adapter context */
2119SK_IOC IoC, /* IO context */
2120int Port, /* Port Index (e.g. MAC_1) */
2121SK_U8 Mode) /* low power mode */
2122{
2123 SK_U16 Word;
2124 SK_U32 DWord;
2125 SK_U8 LastMode;
2126 int Ret = 0;
2127
2128 if (pAC->GIni.GIYukonLite &&
2129 pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
2130
2131 /* save current power mode */
2132 LastMode = pAC->GIni.GP[Port].PPhyPowerState;
2133 pAC->GIni.GP[Port].PPhyPowerState = Mode;
2134
2135 switch (Mode) {
2136 /* coma mode (deep sleep) */
2137 case PHY_PM_DEEP_SLEEP:
2138 /* setup General Purpose Control Register */
2139 GM_OUT16(IoC, 0, GM_GP_CTRL, GM_GPCR_FL_PASS |
2140 GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS);
2141
2142 /* apply COMA mode workaround */
2143 SkGmPhyWrite(pAC, IoC, Port, 29, 0x001f);
2144 SkGmPhyWrite(pAC, IoC, Port, 30, 0xfff3);
2145
2146 SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord);
2147
2148 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
2149
2150 /* Set PHY to Coma Mode */
2151 SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord | PCI_PHY_COMA);
2152
2153 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
2154
2155 break;
2156
2157 /* IEEE 22.2.4.1.5 compatible power down mode */
2158 case PHY_PM_IEEE_POWER_DOWN:
2159 /*
2160 * - disable MAC 125 MHz clock
2161 * - allow MAC power down
2162 */
2163 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
2164 Word |= PHY_M_PC_DIS_125CLK;
2165 Word &= ~PHY_M_PC_MAC_POW_UP;
2166 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
2167
2168 /*
2169 * register changes must be followed by a software
2170 * reset to take effect
2171 */
2172 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
2173 Word |= PHY_CT_RESET;
2174 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
2175
2176 /* switch IEEE compatible power down mode on */
2177 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
2178 Word |= PHY_CT_PDOWN;
2179 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
2180 break;
2181
2182 /* energy detect and energy detect plus mode */
2183 case PHY_PM_ENERGY_DETECT:
2184 case PHY_PM_ENERGY_DETECT_PLUS:
2185 /*
2186 * - disable MAC 125 MHz clock
2187 */
2188 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
2189 Word |= PHY_M_PC_DIS_125CLK;
2190 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
2191
2192 /* activate energy detect mode 1 */
2193 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
2194
2195 /* energy detect mode */
2196 if (Mode == PHY_PM_ENERGY_DETECT) {
2197 Word |= PHY_M_PC_EN_DET;
2198 }
2199 /* energy detect plus mode */
2200 else {
2201 Word |= PHY_M_PC_EN_DET_PLUS;
2202 }
2203
2204 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
2205
2206 /*
2207 * reinitialize the PHY to force a software reset
2208 * which is necessary after the register settings
2209 * for the energy detect modes.
2210 * Furthermore reinitialisation prevents that the
2211 * PHY is running out of a stable state.
2212 */
2213 SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
2214 break;
2215
2216 /* don't change current power mode */
2217 default:
2218 pAC->GIni.GP[Port].PPhyPowerState = LastMode;
2219 Ret = 1;
2220 break;
2221 }
2222 }
2223 /* low power modes are not supported by this chip */
2224 else {
2225 Ret = 1;
2226 }
2227
2228 return(Ret);
2229
2230} /* SkGmEnterLowPowerMode */
2231
2232/******************************************************************************
2233 *
2234 * SkGmLeaveLowPowerMode()
2235 *
2236 * Description:
2237 * Leave the current low power mode and switch to normal mode
2238 *
2239 * Note:
2240 *
2241 * Returns:
2242 * 0: ok
2243 * 1: error
2244 */
2245int SkGmLeaveLowPowerMode(
2246SK_AC *pAC, /* adapter context */
2247SK_IOC IoC, /* IO context */
2248int Port) /* Port Index (e.g. MAC_1) */
2249{
2250 SK_U32 DWord;
2251 SK_U16 Word;
2252 SK_U8 LastMode;
2253 int Ret = 0;
2254
2255 if (pAC->GIni.GIYukonLite &&
2256 pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
2257
2258 /* save current power mode */
2259 LastMode = pAC->GIni.GP[Port].PPhyPowerState;
2260 pAC->GIni.GP[Port].PPhyPowerState = PHY_PM_OPERATIONAL_MODE;
2261
2262 switch (LastMode) {
2263 /* coma mode (deep sleep) */
2264 case PHY_PM_DEEP_SLEEP:
2265 SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord);
2266
2267 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
2268
2269 /* Release PHY from Coma Mode */
2270 SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord & ~PCI_PHY_COMA);
2271
2272 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
2273
2274 SK_IN32(IoC, B2_GP_IO, &DWord);
2275
2276 /* set to output */
2277 DWord |= (GP_DIR_9 | GP_IO_9);
2278
2279 /* set PHY reset */
2280 SK_OUT32(IoC, B2_GP_IO, DWord);
2281
2282 DWord &= ~GP_IO_9; /* clear PHY reset (active high) */
2283
2284 /* clear PHY reset */
2285 SK_OUT32(IoC, B2_GP_IO, DWord);
2286 break;
2287
2288 /* IEEE 22.2.4.1.5 compatible power down mode */
2289 case PHY_PM_IEEE_POWER_DOWN:
2290 /*
2291 * - enable MAC 125 MHz clock
2292 * - set MAC power up
2293 */
2294 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
2295 Word &= ~PHY_M_PC_DIS_125CLK;
2296 Word |= PHY_M_PC_MAC_POW_UP;
2297 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
2298
2299 /*
2300 * register changes must be followed by a software
2301 * reset to take effect
2302 */
2303 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
2304 Word |= PHY_CT_RESET;
2305 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
2306
2307 /* switch IEEE compatible power down mode off */
2308 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
2309 Word &= ~PHY_CT_PDOWN;
2310 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
2311 break;
2312
2313 /* energy detect and energy detect plus mode */
2314 case PHY_PM_ENERGY_DETECT:
2315 case PHY_PM_ENERGY_DETECT_PLUS:
2316 /*
2317 * - enable MAC 125 MHz clock
2318 */
2319 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
2320 Word &= ~PHY_M_PC_DIS_125CLK;
2321 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
2322
2323 /* disable energy detect mode */
2324 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
2325 Word &= ~PHY_M_PC_EN_DET_MSK;
2326 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
2327
2328 /*
2329 * reinitialize the PHY to force a software reset
2330 * which is necessary after the register settings
2331 * for the energy detect modes.
2332 * Furthermore reinitialisation prevents that the
2333 * PHY is running out of a stable state.
2334 */
2335 SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
2336 break;
2337
2338 /* don't change current power mode */
2339 default:
2340 pAC->GIni.GP[Port].PPhyPowerState = LastMode;
2341 Ret = 1;
2342 break;
2343 }
2344 }
2345 /* low power modes are not supported by this chip */
2346 else {
2347 Ret = 1;
2348 }
2349
2350 return(Ret);
2351
2352} /* SkGmLeaveLowPowerMode */
2353#endif /* !SK_SLIM */
2354
2355
2356/******************************************************************************
2357 *
2358 * SkGmInitPhyMarv() - Initialize the Marvell Phy registers
2359 *
2360 * Description: initializes all the Marvell Phy registers
2361 *
2362 * Note:
2363 *
2364 * Returns:
2365 * nothing
2366 */
2367static void SkGmInitPhyMarv(
2368SK_AC *pAC, /* adapter context */
2369SK_IOC IoC, /* IO context */
2370int Port, /* Port Index (MAC_1 + n) */
2371SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
2372{
2373 SK_GEPORT *pPrt;
2374 SK_U16 PhyCtrl;
2375 SK_U16 C1000BaseT;
2376 SK_U16 AutoNegAdv;
2377 SK_U16 ExtPhyCtrl;
2378 SK_U16 LedCtrl;
2379 SK_BOOL AutoNeg;
2380#if defined(SK_DIAG) || defined(DEBUG)
2381 SK_U16 PhyStat;
2382 SK_U16 PhyStat1;
2383 SK_U16 PhySpecStat;
2384#endif /* SK_DIAG || DEBUG */
2385
2386 pPrt = &pAC->GIni.GP[Port];
2387
2388 /* Auto-negotiation ? */
2389 if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
2390 AutoNeg = SK_FALSE;
2391 }
2392 else {
2393 AutoNeg = SK_TRUE;
2394 }
2395
2396 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2397 ("InitPhyMarv: Port %d, auto-negotiation %s\n",
2398 Port, AutoNeg ? "ON" : "OFF"));
2399
2400#ifdef VCPU
2401 VCPUprintf(0, "SkGmInitPhyMarv(), Port=%u, DoLoop=%u\n",
2402 Port, DoLoop);
2403#else /* VCPU */
2404 if (DoLoop) {
2405 /* Set 'MAC Power up'-bit, set Manual MDI configuration */
2406 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL,
2407 PHY_M_PC_MAC_POW_UP);
2408 }
2409 else if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO) {
2410 /* Read Ext. PHY Specific Control */
2411 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
2412
2413 ExtPhyCtrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
2414 PHY_M_EC_MAC_S_MSK);
2415
2416 ExtPhyCtrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ) |
2417 PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1);
2418
2419 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl);
2420 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2421 ("Set Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
2422 }
2423
2424 /* Read PHY Control */
2425 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);
2426
2427 if (!AutoNeg) {
2428 /* Disable Auto-negotiation */
2429 PhyCtrl &= ~PHY_CT_ANE;
2430 }
2431
2432 PhyCtrl |= PHY_CT_RESET;
2433 /* Assert software reset */
2434 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);
2435#endif /* VCPU */
2436
2437 PhyCtrl = 0 /* PHY_CT_COL_TST */;
2438 C1000BaseT = 0;
2439 AutoNegAdv = PHY_SEL_TYPE;
2440
2441 /* manually Master/Slave ? */
2442 if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
2443 /* enable Manual Master/Slave */
2444 C1000BaseT |= PHY_M_1000C_MSE;
2445
2446 if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
2447 C1000BaseT |= PHY_M_1000C_MSC; /* set it to Master */
2448 }
2449 }
2450
2451 /* Auto-negotiation ? */
2452 if (!AutoNeg) {
2453
2454 if (pPrt->PLinkMode == SK_LMODE_FULL) {
2455 /* Set Full Duplex Mode */
2456 PhyCtrl |= PHY_CT_DUP_MD;
2457 }
2458
2459 /* Set Master/Slave manually if not already done */
2460 if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
2461 C1000BaseT |= PHY_M_1000C_MSE; /* set it to Slave */
2462 }
2463
2464 /* Set Speed */
2465 switch (pPrt->PLinkSpeed) {
2466 case SK_LSPEED_AUTO:
2467 case SK_LSPEED_1000MBPS:
2468 PhyCtrl |= PHY_CT_SP1000;
2469 break;
2470 case SK_LSPEED_100MBPS:
2471 PhyCtrl |= PHY_CT_SP100;
2472 break;
2473 case SK_LSPEED_10MBPS:
2474 break;
2475 default:
2476 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019,
2477 SKERR_HWI_E019MSG);
2478 }
2479
2480 if (!DoLoop) {
2481 PhyCtrl |= PHY_CT_RESET;
2482 }
2483 }
2484 else {
2485 /* Set Auto-negotiation advertisement */
2486
2487 if (pAC->GIni.GICopperType) {
2488 /* Set Speed capabilities */
2489 switch (pPrt->PLinkSpeed) {
2490 case SK_LSPEED_AUTO:
2491 C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD;
2492 AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
2493 PHY_M_AN_10_FD | PHY_M_AN_10_HD;
2494 break;
2495 case SK_LSPEED_1000MBPS:
2496 C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD;
2497 break;
2498 case SK_LSPEED_100MBPS:
2499 AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
2500 /* advertise 10Base-T also */
2501 PHY_M_AN_10_FD | PHY_M_AN_10_HD;
2502 break;
2503 case SK_LSPEED_10MBPS:
2504 AutoNegAdv |= PHY_M_AN_10_FD | PHY_M_AN_10_HD;
2505 break;
2506 default:
2507 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019,
2508 SKERR_HWI_E019MSG);
2509 }
2510
2511 /* Set Full/half duplex capabilities */
2512 switch (pPrt->PLinkMode) {
2513 case SK_LMODE_AUTOHALF:
2514 C1000BaseT &= ~PHY_M_1000C_AFD;
2515 AutoNegAdv &= ~(PHY_M_AN_100_FD | PHY_M_AN_10_FD);
2516 break;
2517 case SK_LMODE_AUTOFULL:
2518 C1000BaseT &= ~PHY_M_1000C_AHD;
2519 AutoNegAdv &= ~(PHY_M_AN_100_HD | PHY_M_AN_10_HD);
2520 break;
2521 case SK_LMODE_AUTOBOTH:
2522 break;
2523 default:
2524 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
2525 SKERR_HWI_E015MSG);
2526 }
2527
2528 /* Set Flow-control capabilities */
2529 switch (pPrt->PFlowCtrlMode) {
2530 case SK_FLOW_MODE_NONE:
2531 AutoNegAdv |= PHY_B_P_NO_PAUSE;
2532 break;
2533 case SK_FLOW_MODE_LOC_SEND:
2534 AutoNegAdv |= PHY_B_P_ASYM_MD;
2535 break;
2536 case SK_FLOW_MODE_SYMMETRIC:
2537 AutoNegAdv |= PHY_B_P_SYM_MD;
2538 break;
2539 case SK_FLOW_MODE_SYM_OR_REM:
2540 AutoNegAdv |= PHY_B_P_BOTH_MD;
2541 break;
2542 default:
2543 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
2544 SKERR_HWI_E016MSG);
2545 }
2546 }
2547 else { /* special defines for FIBER (88E1011S only) */
2548
2549 /* Set Full/half duplex capabilities */
2550 switch (pPrt->PLinkMode) {
2551 case SK_LMODE_AUTOHALF:
2552 AutoNegAdv |= PHY_M_AN_1000X_AHD;
2553 break;
2554 case SK_LMODE_AUTOFULL:
2555 AutoNegAdv |= PHY_M_AN_1000X_AFD;
2556 break;
2557 case SK_LMODE_AUTOBOTH:
2558 AutoNegAdv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD;
2559 break;
2560 default:
2561 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
2562 SKERR_HWI_E015MSG);
2563 }
2564
2565 /* Set Flow-control capabilities */
2566 switch (pPrt->PFlowCtrlMode) {
2567 case SK_FLOW_MODE_NONE:
2568 AutoNegAdv |= PHY_M_P_NO_PAUSE_X;
2569 break;
2570 case SK_FLOW_MODE_LOC_SEND:
2571 AutoNegAdv |= PHY_M_P_ASYM_MD_X;
2572 break;
2573 case SK_FLOW_MODE_SYMMETRIC:
2574 AutoNegAdv |= PHY_M_P_SYM_MD_X;
2575 break;
2576 case SK_FLOW_MODE_SYM_OR_REM:
2577 AutoNegAdv |= PHY_M_P_BOTH_MD_X;
2578 break;
2579 default:
2580 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
2581 SKERR_HWI_E016MSG);
2582 }
2583 }
2584
2585 if (!DoLoop) {
2586 /* Restart Auto-negotiation */
2587 PhyCtrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
2588 }
2589 }
2590
2591#ifdef VCPU
2592 /*
2593 * E-mail from Gu Lin (08-03-2002):
2594 */
2595
2596 /* Program PHY register 30 as 16'h0708 for simulation speed up */
2597 SkGmPhyWrite(pAC, IoC, Port, 30, 0x0700 /* 0x0708 */);
2598
2599 VCpuWait(2000);
2600
2601#else /* VCPU */
2602
2603 /* Write 1000Base-T Control Register */
2604 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT);
2605 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2606 ("Set 1000B-T Ctrl =0x%04X\n", C1000BaseT));
2607
2608 /* Write AutoNeg Advertisement Register */
2609 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, AutoNegAdv);
2610 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2611 ("Set Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));
2612#endif /* VCPU */
2613
2614 if (DoLoop) {
2615 /* Set the PHY Loopback bit */
2616 PhyCtrl |= PHY_CT_LOOP;
2617
2618#ifdef XXX
2619 /* Program PHY register 16 as 16'h0400 to force link good */
2620 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_FL_GOOD);
2621#endif /* XXX */
2622
2623#ifndef VCPU
2624 if (pPrt->PLinkSpeed != SK_LSPEED_AUTO) {
2625 /* Write Ext. PHY Specific Control */
2626 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL,
2627 (SK_U16)((pPrt->PLinkSpeed + 2) << 4));
2628 }
2629#endif /* VCPU */
2630 }
2631#ifdef TEST_ONLY
2632 else if (pPrt->PLinkSpeed == SK_LSPEED_10MBPS) {
2633 /* Write PHY Specific Control */
2634 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL,
2635 PHY_M_PC_EN_DET_MSK);
2636 }
2637#endif
2638
2639 /* Write to the PHY Control register */
2640 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);
2641 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2642 ("Set PHY Ctrl Reg.=0x%04X\n", PhyCtrl));
2643
2644#ifdef VCPU
2645 VCpuWait(2000);
2646#else
2647
2648 LedCtrl = PHY_M_LED_PULS_DUR(PULS_170MS) | PHY_M_LED_BLINK_RT(BLINK_84MS);
2649
2650 if ((pAC->GIni.GILedBlinkCtrl & SK_ACT_LED_BLINK) != 0) {
2651 LedCtrl |= PHY_M_LEDC_RX_CTRL | PHY_M_LEDC_TX_CTRL;
2652 }
2653
2654 if ((pAC->GIni.GILedBlinkCtrl & SK_DUP_LED_NORMAL) != 0) {
2655 LedCtrl |= PHY_M_LEDC_DP_CTRL;
2656 }
2657
2658 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_CTRL, LedCtrl);
2659
2660 if ((pAC->GIni.GILedBlinkCtrl & SK_LED_LINK100_ON) != 0) {
2661 /* only in forced 100 Mbps mode */
2662 if (!AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_100MBPS) {
2663
2664 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_OVER,
2665 PHY_M_LED_MO_100(MO_LED_ON));
2666 }
2667 }
2668
2669#ifdef SK_DIAG
2670 c_print("Set PHY Ctrl=0x%04X\n", PhyCtrl);
2671 c_print("Set 1000 B-T=0x%04X\n", C1000BaseT);
2672 c_print("Set Auto-Neg=0x%04X\n", AutoNegAdv);
2673 c_print("Set Ext Ctrl=0x%04X\n", ExtPhyCtrl);
2674#endif /* SK_DIAG */
2675
2676#if defined(SK_DIAG) || defined(DEBUG)
2677 /* Read PHY Control */
2678 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);
2679 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2680 ("PHY Ctrl Reg.=0x%04X\n", PhyCtrl));
2681
2682 /* Read 1000Base-T Control Register */
2683 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_CTRL, &C1000BaseT);
2684 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2685 ("1000B-T Ctrl =0x%04X\n", C1000BaseT));
2686
2687 /* Read AutoNeg Advertisement Register */
2688 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &AutoNegAdv);
2689 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2690 ("Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));
2691
2692 /* Read Ext. PHY Specific Control */
2693 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
2694 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2695 ("Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
2696
2697 /* Read PHY Status */
2698 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
2699 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2700 ("PHY Stat Reg.=0x%04X\n", PhyStat));
2701 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat1);
2702 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2703 ("PHY Stat Reg.=0x%04X\n", PhyStat1));
2704
2705 /* Read PHY Specific Status */
2706 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
2707 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2708 ("PHY Spec Stat=0x%04X\n", PhySpecStat));
2709#endif /* SK_DIAG || DEBUG */
2710
2711#ifdef SK_DIAG
2712 c_print("PHY Ctrl Reg=0x%04X\n", PhyCtrl);
2713 c_print("PHY 1000 Reg=0x%04X\n", C1000BaseT);
2714 c_print("PHY AnAd Reg=0x%04X\n", AutoNegAdv);
2715 c_print("Ext Ctrl Reg=0x%04X\n", ExtPhyCtrl);
2716 c_print("PHY Stat Reg=0x%04X\n", PhyStat);
2717 c_print("PHY Stat Reg=0x%04X\n", PhyStat1);
2718 c_print("PHY Spec Reg=0x%04X\n", PhySpecStat);
2719#endif /* SK_DIAG */
2720
2721#endif /* VCPU */
2722
2723} /* SkGmInitPhyMarv */
2724#endif /* YUKON */
2725
2726
2727#ifdef OTHER_PHY
2728/******************************************************************************
2729 *
2730 * SkXmInitPhyLone() - Initialize the Level One Phy registers
2731 *
2732 * Description: initializes all the Level One Phy registers
2733 *
2734 * Note:
2735 *
2736 * Returns:
2737 * nothing
2738 */
2739static void SkXmInitPhyLone(
2740SK_AC *pAC, /* adapter context */
2741SK_IOC IoC, /* IO context */
2742int Port, /* Port Index (MAC_1 + n) */
2743SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
2744{
2745 SK_GEPORT *pPrt;
2746 SK_U16 Ctrl1;
2747 SK_U16 Ctrl2;
2748 SK_U16 Ctrl3;
2749
2750 Ctrl1 = PHY_CT_SP1000;
2751 Ctrl2 = 0;
2752 Ctrl3 = PHY_SEL_TYPE;
2753
2754 pPrt = &pAC->GIni.GP[Port];
2755
2756 /* manually Master/Slave ? */
2757 if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
2758 Ctrl2 |= PHY_L_1000C_MSE;
2759
2760 if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
2761 Ctrl2 |= PHY_L_1000C_MSC;
2762 }
2763 }
2764 /* Auto-negotiation ? */
2765 if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
2766 /*
2767 * level one spec say: "1000 Mbps: manual mode not allowed"
2768 * but lets see what happens...
2769 */
2770 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2771 ("InitPhyLone: no auto-negotiation Port %d\n", Port));
2772 /* Set DuplexMode in Config register */
2773 if (pPrt->PLinkMode == SK_LMODE_FULL) {
2774 Ctrl1 |= PHY_CT_DUP_MD;
2775 }
2776
2777 /* Determine Master/Slave manually if not already done */
2778 if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
2779 Ctrl2 |= PHY_L_1000C_MSE; /* set it to Slave */
2780 }
2781
2782 /*
2783 * Do NOT enable Auto-negotiation here. This would hold
2784 * the link down because no IDLES are transmitted
2785 */
2786 }
2787 else {
2788 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2789 ("InitPhyLone: with auto-negotiation Port %d\n", Port));
2790 /* Set Auto-negotiation advertisement */
2791
2792 /* Set Full/half duplex capabilities */
2793 switch (pPrt->PLinkMode) {
2794 case SK_LMODE_AUTOHALF:
2795 Ctrl2 |= PHY_L_1000C_AHD;
2796 break;
2797 case SK_LMODE_AUTOFULL:
2798 Ctrl2 |= PHY_L_1000C_AFD;
2799 break;
2800 case SK_LMODE_AUTOBOTH:
2801 Ctrl2 |= PHY_L_1000C_AFD | PHY_L_1000C_AHD;
2802 break;
2803 default:
2804 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
2805 SKERR_HWI_E015MSG);
2806 }
2807
2808 /* Set Flow-control capabilities */
2809 switch (pPrt->PFlowCtrlMode) {
2810 case SK_FLOW_MODE_NONE:
2811 Ctrl3 |= PHY_L_P_NO_PAUSE;
2812 break;
2813 case SK_FLOW_MODE_LOC_SEND:
2814 Ctrl3 |= PHY_L_P_ASYM_MD;
2815 break;
2816 case SK_FLOW_MODE_SYMMETRIC:
2817 Ctrl3 |= PHY_L_P_SYM_MD;
2818 break;
2819 case SK_FLOW_MODE_SYM_OR_REM:
2820 Ctrl3 |= PHY_L_P_BOTH_MD;
2821 break;
2822 default:
2823 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
2824 SKERR_HWI_E016MSG);
2825 }
2826
2827 /* Restart Auto-negotiation */
2828 Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG;
2829 }
2830
2831 /* Write 1000Base-T Control Register */
2832 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_1000T_CTRL, Ctrl2);
2833 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2834 ("1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
2835
2836 /* Write AutoNeg Advertisement Register */
2837 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_AUNE_ADV, Ctrl3);
2838 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2839 ("Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3));
2840
2841 if (DoLoop) {
2842 /* Set the Phy Loopback bit, too */
2843 Ctrl1 |= PHY_CT_LOOP;
2844 }
2845
2846 /* Write to the Phy control register */
2847 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_CTRL, Ctrl1);
2848 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2849 ("PHY Control Reg=0x%04X\n", Ctrl1));
2850} /* SkXmInitPhyLone */
2851
2852
2853/******************************************************************************
2854 *
2855 * SkXmInitPhyNat() - Initialize the National Phy registers
2856 *
2857 * Description: initializes all the National Phy registers
2858 *
2859 * Note:
2860 *
2861 * Returns:
2862 * nothing
2863 */
2864static void SkXmInitPhyNat(
2865SK_AC *pAC, /* adapter context */
2866SK_IOC IoC, /* IO context */
2867int Port, /* Port Index (MAC_1 + n) */
2868SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
2869{
2870/* todo: National */
2871} /* SkXmInitPhyNat */
2872#endif /* OTHER_PHY */
2873
2874
2875/******************************************************************************
2876 *
2877 * SkMacInitPhy() - Initialize the PHY registers
2878 *
2879 * Description: calls the Init PHY routines dep. on board type
2880 *
2881 * Note:
2882 *
2883 * Returns:
2884 * nothing
2885 */
2886void SkMacInitPhy(
2887SK_AC *pAC, /* adapter context */
2888SK_IOC IoC, /* IO context */
2889int Port, /* Port Index (MAC_1 + n) */
2890SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
2891{
2892 SK_GEPORT *pPrt;
2893
2894 pPrt = &pAC->GIni.GP[Port];
2895
2896#ifdef GENESIS
2897 if (pAC->GIni.GIGenesis) {
2898
2899 switch (pPrt->PhyType) {
2900 case SK_PHY_XMAC:
2901 SkXmInitPhyXmac(pAC, IoC, Port, DoLoop);
2902 break;
2903 case SK_PHY_BCOM:
2904 SkXmInitPhyBcom(pAC, IoC, Port, DoLoop);
2905 break;
2906#ifdef OTHER_PHY
2907 case SK_PHY_LONE:
2908 SkXmInitPhyLone(pAC, IoC, Port, DoLoop);
2909 break;
2910 case SK_PHY_NAT:
2911 SkXmInitPhyNat(pAC, IoC, Port, DoLoop);
2912 break;
2913#endif /* OTHER_PHY */
2914 }
2915 }
2916#endif /* GENESIS */
2917
2918#ifdef YUKON
2919 if (pAC->GIni.GIYukon) {
2920
2921 SkGmInitPhyMarv(pAC, IoC, Port, DoLoop);
2922 }
2923#endif /* YUKON */
2924
2925} /* SkMacInitPhy */
2926
2927
2928#ifdef GENESIS
2929/******************************************************************************
2930 *
2931 * SkXmAutoNegDoneXmac() - Auto-negotiation handling
2932 *
2933 * Description:
2934 * This function handles the auto-negotiation if the Done bit is set.
2935 *
2936 * Returns:
2937 * SK_AND_OK o.k.
2938 * SK_AND_DUP_CAP Duplex capability error happened
2939 * SK_AND_OTHER Other error happened
2940 */
2941static int SkXmAutoNegDoneXmac(
2942SK_AC *pAC, /* adapter context */
2943SK_IOC IoC, /* IO context */
2944int Port) /* Port Index (MAC_1 + n) */
2945{
2946 SK_GEPORT *pPrt;
2947 SK_U16 ResAb; /* Resolved Ability */
2948 SK_U16 LPAb; /* Link Partner Ability */
2949
2950 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2951 ("AutoNegDoneXmac, Port %d\n", Port));
2952
2953 pPrt = &pAC->GIni.GP[Port];
2954
2955 /* Get PHY parameters */
2956 SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LPAb);
2957 SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb);
2958
2959 if ((LPAb & PHY_X_AN_RFB) != 0) {
2960 /* At least one of the remote fault bit is set */
2961 /* Error */
2962 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2963 ("AutoNegFail: Remote fault bit set Port %d\n", Port));
2964 pPrt->PAutoNegFail = SK_TRUE;
2965 return(SK_AND_OTHER);
2966 }
2967
2968 /* Check Duplex mismatch */
2969 if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_FD) {
2970 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
2971 }
2972 else if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_HD) {
2973 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
2974 }
2975 else {
2976 /* Error */
2977 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2978 ("AutoNegFail: Duplex mode mismatch Port %d\n", Port));
2979 pPrt->PAutoNegFail = SK_TRUE;
2980 return(SK_AND_DUP_CAP);
2981 }
2982
2983 /* Check PAUSE mismatch */
2984 /* We are NOT using chapter 4.23 of the Xaqti manual */
2985 /* We are using IEEE 802.3z/D5.0 Table 37-4 */
2986 if ((pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC ||
2987 pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) &&
2988 (LPAb & PHY_X_P_SYM_MD) != 0) {
2989 /* Symmetric PAUSE */
2990 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
2991 }
2992 else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM &&
2993 (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) {
2994 /* Enable PAUSE receive, disable PAUSE transmit */
2995 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
2996 }
2997 else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND &&
2998 (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) {
2999 /* Disable PAUSE receive, enable PAUSE transmit */
3000 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
3001 }
3002 else {
3003 /* PAUSE mismatch -> no PAUSE */
3004 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
3005 }
3006 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
3007
3008 return(SK_AND_OK);
3009} /* SkXmAutoNegDoneXmac */
3010
3011
3012/******************************************************************************
3013 *
3014 * SkXmAutoNegDoneBcom() - Auto-negotiation handling
3015 *
3016 * Description:
3017 * This function handles the auto-negotiation if the Done bit is set.
3018 *
3019 * Returns:
3020 * SK_AND_OK o.k.
3021 * SK_AND_DUP_CAP Duplex capability error happened
3022 * SK_AND_OTHER Other error happened
3023 */
3024static int SkXmAutoNegDoneBcom(
3025SK_AC *pAC, /* adapter context */
3026SK_IOC IoC, /* IO context */
3027int Port) /* Port Index (MAC_1 + n) */
3028{
3029 SK_GEPORT *pPrt;
3030 SK_U16 LPAb; /* Link Partner Ability */
3031 SK_U16 AuxStat; /* Auxiliary Status */
3032
3033#ifdef TEST_ONLY
303401-Sep-2000 RA;:;:
3035 SK_U16 ResAb; /* Resolved Ability */
3036#endif /* 0 */
3037
3038 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3039 ("AutoNegDoneBcom, Port %d\n", Port));
3040 pPrt = &pAC->GIni.GP[Port];
3041
3042 /* Get PHY parameters */
3043 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LPAb);
3044#ifdef TEST_ONLY
304501-Sep-2000 RA;:;:
3046 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
3047#endif /* 0 */
3048
3049 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &AuxStat);
3050
3051 if ((LPAb & PHY_B_AN_RF) != 0) {
3052 /* Remote fault bit is set: Error */
3053 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3054 ("AutoNegFail: Remote fault bit set Port %d\n", Port));
3055 pPrt->PAutoNegFail = SK_TRUE;
3056 return(SK_AND_OTHER);
3057 }
3058
3059 /* Check Duplex mismatch */
3060 if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000FD) {
3061 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
3062 }
3063 else if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000HD) {
3064 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
3065 }
3066 else {
3067 /* Error */
3068 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3069 ("AutoNegFail: Duplex mode mismatch Port %d\n", Port));
3070 pPrt->PAutoNegFail = SK_TRUE;
3071 return(SK_AND_DUP_CAP);
3072 }
3073
3074#ifdef TEST_ONLY
307501-Sep-2000 RA;:;:
3076 /* Check Master/Slave resolution */
3077 if ((ResAb & PHY_B_1000S_MSF) != 0) {
3078 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3079 ("Master/Slave Fault Port %d\n", Port));
3080 pPrt->PAutoNegFail = SK_TRUE;
3081 pPrt->PMSStatus = SK_MS_STAT_FAULT;
3082 return(SK_AND_OTHER);
3083 }
3084
3085 pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
3086 SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
3087#endif /* 0 */
3088
3089 /* Check PAUSE mismatch ??? */
3090 /* We are using IEEE 802.3z/D5.0 Table 37-4 */
3091 if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PAUSE_MSK) {
3092 /* Symmetric PAUSE */
3093 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
3094 }
3095 else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRR) {
3096 /* Enable PAUSE receive, disable PAUSE transmit */
3097 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
3098 }
3099 else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRT) {
3100 /* Disable PAUSE receive, enable PAUSE transmit */
3101 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
3102 }
3103 else {
3104 /* PAUSE mismatch -> no PAUSE */
3105 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
3106 }
3107 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
3108
3109 return(SK_AND_OK);
3110} /* SkXmAutoNegDoneBcom */
3111#endif /* GENESIS */
3112
3113
3114#ifdef YUKON
3115/******************************************************************************
3116 *
3117 * SkGmAutoNegDoneMarv() - Auto-negotiation handling
3118 *
3119 * Description:
3120 * This function handles the auto-negotiation if the Done bit is set.
3121 *
3122 * Returns:
3123 * SK_AND_OK o.k.
3124 * SK_AND_DUP_CAP Duplex capability error happened
3125 * SK_AND_OTHER Other error happened
3126 */
3127static int SkGmAutoNegDoneMarv(
3128SK_AC *pAC, /* adapter context */
3129SK_IOC IoC, /* IO context */
3130int Port) /* Port Index (MAC_1 + n) */
3131{
3132 SK_GEPORT *pPrt;
3133 SK_U16 LPAb; /* Link Partner Ability */
3134 SK_U16 ResAb; /* Resolved Ability */
3135 SK_U16 AuxStat; /* Auxiliary Status */
3136
3137 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3138 ("AutoNegDoneMarv, Port %d\n", Port));
3139 pPrt = &pAC->GIni.GP[Port];
3140
3141 /* Get PHY parameters */
3142 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_LP, &LPAb);
3143 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3144 ("Link P.Abil.=0x%04X\n", LPAb));
3145
3146 if ((LPAb & PHY_M_AN_RF) != 0) {
3147 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3148 ("AutoNegFail: Remote fault bit set Port %d\n", Port));
3149 pPrt->PAutoNegFail = SK_TRUE;
3150 return(SK_AND_OTHER);
3151 }
3152
3153 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
3154
3155 /* Check Master/Slave resolution */
3156 if ((ResAb & PHY_B_1000S_MSF) != 0) {
3157 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3158 ("Master/Slave Fault Port %d\n", Port));
3159 pPrt->PAutoNegFail = SK_TRUE;
3160 pPrt->PMSStatus = SK_MS_STAT_FAULT;
3161 return(SK_AND_OTHER);
3162 }
3163
3164 pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
3165 (SK_U8)SK_MS_STAT_MASTER : (SK_U8)SK_MS_STAT_SLAVE;
3166
3167 /* Read PHY Specific Status */
3168 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &AuxStat);
3169
3170 /* Check Speed & Duplex resolved */
3171 if ((AuxStat & PHY_M_PS_SPDUP_RES) == 0) {
3172 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3173 ("AutoNegFail: Speed & Duplex not resolved, Port %d\n", Port));
3174 pPrt->PAutoNegFail = SK_TRUE;
3175 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
3176 return(SK_AND_DUP_CAP);
3177 }
3178
3179 if ((AuxStat & PHY_M_PS_FULL_DUP) != 0) {
3180 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
3181 }
3182 else {
3183 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
3184 }
3185
3186 /* Check PAUSE mismatch ??? */
3187 /* We are using IEEE 802.3z/D5.0 Table 37-4 */
3188 if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_PAUSE_MSK) {
3189 /* Symmetric PAUSE */
3190 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
3191 }
3192 else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_RX_P_EN) {
3193 /* Enable PAUSE receive, disable PAUSE transmit */
3194 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
3195 }
3196 else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_TX_P_EN) {
3197 /* Disable PAUSE receive, enable PAUSE transmit */
3198 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
3199 }
3200 else {
3201 /* PAUSE mismatch -> no PAUSE */
3202 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
3203 }
3204
3205 /* set used link speed */
3206 switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) {
3207 case (unsigned)PHY_M_PS_SPEED_1000:
3208 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
3209 break;
3210 case PHY_M_PS_SPEED_100:
3211 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS;
3212 break;
3213 default:
3214 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS;
3215 }
3216
3217 return(SK_AND_OK);
3218} /* SkGmAutoNegDoneMarv */
3219#endif /* YUKON */
3220
3221
3222#ifdef OTHER_PHY
3223/******************************************************************************
3224 *
3225 * SkXmAutoNegDoneLone() - Auto-negotiation handling
3226 *
3227 * Description:
3228 * This function handles the auto-negotiation if the Done bit is set.
3229 *
3230 * Returns:
3231 * SK_AND_OK o.k.
3232 * SK_AND_DUP_CAP Duplex capability error happened
3233 * SK_AND_OTHER Other error happened
3234 */
3235static int SkXmAutoNegDoneLone(
3236SK_AC *pAC, /* adapter context */
3237SK_IOC IoC, /* IO context */
3238int Port) /* Port Index (MAC_1 + n) */
3239{
3240 SK_GEPORT *pPrt;
3241 SK_U16 ResAb; /* Resolved Ability */
3242 SK_U16 LPAb; /* Link Partner Ability */
3243 SK_U16 QuickStat; /* Auxiliary Status */
3244
3245 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3246 ("AutoNegDoneLone, Port %d\n", Port));
3247 pPrt = &pAC->GIni.GP[Port];
3248
3249 /* Get PHY parameters */
3250 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LPAb);
3251 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ResAb);
3252 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_Q_STAT, &QuickStat);
3253
3254 if ((LPAb & PHY_L_AN_RF) != 0) {
3255 /* Remote fault bit is set */
3256 /* Error */
3257 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3258 ("AutoNegFail: Remote fault bit set Port %d\n", Port));
3259 pPrt->PAutoNegFail = SK_TRUE;
3260 return(SK_AND_OTHER);
3261 }
3262
3263 /* Check Duplex mismatch */
3264 if ((QuickStat & PHY_L_QS_DUP_MOD) != 0) {
3265 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
3266 }
3267 else {
3268 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
3269 }
3270
3271 /* Check Master/Slave resolution */
3272 if ((ResAb & PHY_L_1000S_MSF) != 0) {
3273 /* Error */
3274 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3275 ("Master/Slave Fault Port %d\n", Port));
3276 pPrt->PAutoNegFail = SK_TRUE;
3277 pPrt->PMSStatus = SK_MS_STAT_FAULT;
3278 return(SK_AND_OTHER);
3279 }
3280 else if (ResAb & PHY_L_1000S_MSR) {
3281 pPrt->PMSStatus = SK_MS_STAT_MASTER;
3282 }
3283 else {
3284 pPrt->PMSStatus = SK_MS_STAT_SLAVE;
3285 }
3286
3287 /* Check PAUSE mismatch */
3288 /* We are using IEEE 802.3z/D5.0 Table 37-4 */
3289 /* we must manually resolve the abilities here */
3290 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
3291
3292 switch (pPrt->PFlowCtrlMode) {
3293 case SK_FLOW_MODE_NONE:
3294 /* default */
3295 break;
3296 case SK_FLOW_MODE_LOC_SEND:
3297 if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) ==
3298 (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) {
3299 /* Disable PAUSE receive, enable PAUSE transmit */
3300 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
3301 }
3302 break;
3303 case SK_FLOW_MODE_SYMMETRIC:
3304 if ((QuickStat & PHY_L_QS_PAUSE) != 0) {
3305 /* Symmetric PAUSE */
3306 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
3307 }
3308 break;
3309 case SK_FLOW_MODE_SYM_OR_REM:
3310 if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) ==
3311 PHY_L_QS_AS_PAUSE) {
3312 /* Enable PAUSE receive, disable PAUSE transmit */
3313 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
3314 }
3315 else if ((QuickStat & PHY_L_QS_PAUSE) != 0) {
3316 /* Symmetric PAUSE */
3317 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
3318 }
3319 break;
3320 default:
3321 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
3322 SKERR_HWI_E016MSG);
3323 }
3324
3325 return(SK_AND_OK);
3326} /* SkXmAutoNegDoneLone */
3327
3328
3329/******************************************************************************
3330 *
3331 * SkXmAutoNegDoneNat() - Auto-negotiation handling
3332 *
3333 * Description:
3334 * This function handles the auto-negotiation if the Done bit is set.
3335 *
3336 * Returns:
3337 * SK_AND_OK o.k.
3338 * SK_AND_DUP_CAP Duplex capability error happened
3339 * SK_AND_OTHER Other error happened
3340 */
3341static int SkXmAutoNegDoneNat(
3342SK_AC *pAC, /* adapter context */
3343SK_IOC IoC, /* IO context */
3344int Port) /* Port Index (MAC_1 + n) */
3345{
3346/* todo: National */
3347 return(SK_AND_OK);
3348} /* SkXmAutoNegDoneNat */
3349#endif /* OTHER_PHY */
3350
3351
3352/******************************************************************************
3353 *
3354 * SkMacAutoNegDone() - Auto-negotiation handling
3355 *
3356 * Description: calls the auto-negotiation done routines dep. on board type
3357 *
3358 * Returns:
3359 * SK_AND_OK o.k.
3360 * SK_AND_DUP_CAP Duplex capability error happened
3361 * SK_AND_OTHER Other error happened
3362 */
3363int SkMacAutoNegDone(
3364SK_AC *pAC, /* adapter context */
3365SK_IOC IoC, /* IO context */
3366int Port) /* Port Index (MAC_1 + n) */
3367{
3368 SK_GEPORT *pPrt;
3369 int Rtv;
3370
3371 Rtv = SK_AND_OK;
3372
3373 pPrt = &pAC->GIni.GP[Port];
3374
3375#ifdef GENESIS
3376 if (pAC->GIni.GIGenesis) {
3377
3378 switch (pPrt->PhyType) {
3379
3380 case SK_PHY_XMAC:
3381 Rtv = SkXmAutoNegDoneXmac(pAC, IoC, Port);
3382 break;
3383 case SK_PHY_BCOM:
3384 Rtv = SkXmAutoNegDoneBcom(pAC, IoC, Port);
3385 break;
3386#ifdef OTHER_PHY
3387 case SK_PHY_LONE:
3388 Rtv = SkXmAutoNegDoneLone(pAC, IoC, Port);
3389 break;
3390 case SK_PHY_NAT:
3391 Rtv = SkXmAutoNegDoneNat(pAC, IoC, Port);
3392 break;
3393#endif /* OTHER_PHY */
3394 default:
3395 return(SK_AND_OTHER);
3396 }
3397 }
3398#endif /* GENESIS */
3399
3400#ifdef YUKON
3401 if (pAC->GIni.GIYukon) {
3402
3403 Rtv = SkGmAutoNegDoneMarv(pAC, IoC, Port);
3404 }
3405#endif /* YUKON */
3406
3407 if (Rtv != SK_AND_OK) {
3408 return(Rtv);
3409 }
3410
3411 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3412 ("AutoNeg done Port %d\n", Port));
3413
3414 /* We checked everything and may now enable the link */
3415 pPrt->PAutoNegFail = SK_FALSE;
3416
3417 SkMacRxTxEnable(pAC, IoC, Port);
3418
3419 return(SK_AND_OK);
3420} /* SkMacAutoNegDone */
3421
3422
3423#ifdef GENESIS
3424/******************************************************************************
3425 *
3426 * SkXmSetRxTxEn() - Special Set Rx/Tx Enable and some features in XMAC
3427 *
3428 * Description:
3429 * sets MAC or PHY LoopBack and Duplex Mode in the MMU Command Reg.
3430 * enables Rx/Tx
3431 *
3432 * Returns: N/A
3433 */
3434static void SkXmSetRxTxEn(
3435SK_AC *pAC, /* Adapter Context */
3436SK_IOC IoC, /* IO context */
3437int Port, /* Port Index (MAC_1 + n) */
3438int Para) /* Parameter to set: MAC or PHY LoopBack, Duplex Mode */
3439{
3440 SK_U16 Word;
3441
3442 XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
3443
3444 switch (Para & (SK_MAC_LOOPB_ON | SK_MAC_LOOPB_OFF)) {
3445 case SK_MAC_LOOPB_ON:
3446 Word |= XM_MMU_MAC_LB;
3447 break;
3448 case SK_MAC_LOOPB_OFF:
3449 Word &= ~XM_MMU_MAC_LB;
3450 break;
3451 }
3452
3453 switch (Para & (SK_PHY_LOOPB_ON | SK_PHY_LOOPB_OFF)) {
3454 case SK_PHY_LOOPB_ON:
3455 Word |= XM_MMU_GMII_LOOP;
3456 break;
3457 case SK_PHY_LOOPB_OFF:
3458 Word &= ~XM_MMU_GMII_LOOP;
3459 break;
3460 }
3461
3462 switch (Para & (SK_PHY_FULLD_ON | SK_PHY_FULLD_OFF)) {
3463 case SK_PHY_FULLD_ON:
3464 Word |= XM_MMU_GMII_FD;
3465 break;
3466 case SK_PHY_FULLD_OFF:
3467 Word &= ~XM_MMU_GMII_FD;
3468 break;
3469 }
3470
3471 XM_OUT16(IoC, Port, XM_MMU_CMD, Word | XM_MMU_ENA_RX | XM_MMU_ENA_TX);
3472
3473 /* dummy read to ensure writing */
3474 XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
3475
3476} /* SkXmSetRxTxEn */
3477#endif /* GENESIS */
3478
3479
3480#ifdef YUKON
3481/******************************************************************************
3482 *
3483 * SkGmSetRxTxEn() - Special Set Rx/Tx Enable and some features in GMAC
3484 *
3485 * Description:
3486 * sets MAC LoopBack and Duplex Mode in the General Purpose Control Reg.
3487 * enables Rx/Tx
3488 *
3489 * Returns: N/A
3490 */
3491static void SkGmSetRxTxEn(
3492SK_AC *pAC, /* Adapter Context */
3493SK_IOC IoC, /* IO context */
3494int Port, /* Port Index (MAC_1 + n) */
3495int Para) /* Parameter to set: MAC LoopBack, Duplex Mode */
3496{
3497 SK_U16 Ctrl;
3498
3499 GM_IN16(IoC, Port, GM_GP_CTRL, &Ctrl);
3500
3501 switch (Para & (SK_MAC_LOOPB_ON | SK_MAC_LOOPB_OFF)) {
3502 case SK_MAC_LOOPB_ON:
3503 Ctrl |= GM_GPCR_LOOP_ENA;
3504 break;
3505 case SK_MAC_LOOPB_OFF:
3506 Ctrl &= ~GM_GPCR_LOOP_ENA;
3507 break;
3508 }
3509
3510 switch (Para & (SK_PHY_FULLD_ON | SK_PHY_FULLD_OFF)) {
3511 case SK_PHY_FULLD_ON:
3512 Ctrl |= GM_GPCR_DUP_FULL;
3513 break;
3514 case SK_PHY_FULLD_OFF:
3515 Ctrl &= ~GM_GPCR_DUP_FULL;
3516 break;
3517 }
3518
3519 GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Ctrl | GM_GPCR_RX_ENA |
3520 GM_GPCR_TX_ENA));
3521
3522 /* dummy read to ensure writing */
3523 GM_IN16(IoC, Port, GM_GP_CTRL, &Ctrl);
3524
3525} /* SkGmSetRxTxEn */
3526#endif /* YUKON */
3527
3528
3529#ifndef SK_SLIM
3530/******************************************************************************
3531 *
3532 * SkMacSetRxTxEn() - Special Set Rx/Tx Enable and parameters
3533 *
3534 * Description: calls the Special Set Rx/Tx Enable routines dep. on board type
3535 *
3536 * Returns: N/A
3537 */
3538void SkMacSetRxTxEn(
3539SK_AC *pAC, /* Adapter Context */
3540SK_IOC IoC, /* IO context */
3541int Port, /* Port Index (MAC_1 + n) */
3542int Para)
3543{
3544#ifdef GENESIS
3545 if (pAC->GIni.GIGenesis) {
3546
3547 SkXmSetRxTxEn(pAC, IoC, Port, Para);
3548 }
3549#endif /* GENESIS */
3550
3551#ifdef YUKON
3552 if (pAC->GIni.GIYukon) {
3553
3554 SkGmSetRxTxEn(pAC, IoC, Port, Para);
3555 }
3556#endif /* YUKON */
3557
3558} /* SkMacSetRxTxEn */
3559#endif /* !SK_SLIM */
3560
3561
3562/******************************************************************************
3563 *
3564 * SkMacRxTxEnable() - Enable Rx/Tx activity if port is up
3565 *
3566 * Description: enables Rx/Tx dep. on board type
3567 *
3568 * Returns:
3569 * 0 o.k.
3570 * != 0 Error happened
3571 */
3572int SkMacRxTxEnable(
3573SK_AC *pAC, /* adapter context */
3574SK_IOC IoC, /* IO context */
3575int Port) /* Port Index (MAC_1 + n) */
3576{
3577 SK_GEPORT *pPrt;
3578 SK_U16 Reg; /* 16-bit register value */
3579 SK_U16 IntMask; /* MAC interrupt mask */
3580#ifdef GENESIS
3581 SK_U16 SWord;
3582#endif
3583
3584 pPrt = &pAC->GIni.GP[Port];
3585
3586 if (!pPrt->PHWLinkUp) {
3587 /* The Hardware link is NOT up */
3588 return(0);
3589 }
3590
3591 if ((pPrt->PLinkMode == SK_LMODE_AUTOHALF ||
3592 pPrt->PLinkMode == SK_LMODE_AUTOFULL ||
3593 pPrt->PLinkMode == SK_LMODE_AUTOBOTH) &&
3594 pPrt->PAutoNegFail) {
3595 /* Auto-negotiation is not done or failed */
3596 return(0);
3597 }
3598
3599#ifdef GENESIS
3600 if (pAC->GIni.GIGenesis) {
3601 /* set Duplex Mode and Pause Mode */
3602 SkXmInitDupMd(pAC, IoC, Port);
3603
3604 SkXmInitPauseMd(pAC, IoC, Port);
3605
3606 /*
3607 * Initialize the Interrupt Mask Register. Default IRQs are...
3608 * - Link Asynchronous Event
3609 * - Link Partner requests config
3610 * - Auto Negotiation Done
3611 * - Rx Counter Event Overflow
3612 * - Tx Counter Event Overflow
3613 * - Transmit FIFO Underrun
3614 */
3615 IntMask = XM_DEF_MSK;
3616
3617#ifdef DEBUG
3618 /* add IRQ for Receive FIFO Overflow */
3619 IntMask &= ~XM_IS_RXF_OV;
3620#endif /* DEBUG */
3621
3622 if (pPrt->PhyType != SK_PHY_XMAC) {
3623 /* disable GP0 interrupt bit */
3624 IntMask |= XM_IS_INP_ASS;
3625 }
3626 XM_OUT16(IoC, Port, XM_IMSK, IntMask);
3627
3628 /* get MMU Command Reg. */
3629 XM_IN16(IoC, Port, XM_MMU_CMD, &Reg);
3630
3631 if (pPrt->PhyType != SK_PHY_XMAC &&
3632 (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL ||
3633 pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL)) {
3634 /* set to Full Duplex */
3635 Reg |= XM_MMU_GMII_FD;
3636 }
3637
3638 switch (pPrt->PhyType) {
3639 case SK_PHY_BCOM:
3640 /*
3641 * Workaround BCOM Errata (#10523) for all BCom Phys
3642 * Enable Power Management after link up
3643 */
3644 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord);
3645 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
3646 (SK_U16)(SWord & ~PHY_B_AC_DIS_PM));
3647 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK,
3648 (SK_U16)PHY_B_DEF_MSK);
3649 break;
3650#ifdef OTHER_PHY
3651 case SK_PHY_LONE:
3652 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, PHY_L_DEF_MSK);
3653 break;
3654 case SK_PHY_NAT:
3655 /* todo National:
3656 SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, PHY_N_DEF_MSK); */
3657 /* no interrupts possible from National ??? */
3658 break;
3659#endif /* OTHER_PHY */
3660 }
3661
3662 /* enable Rx/Tx */
3663 XM_OUT16(IoC, Port, XM_MMU_CMD, Reg | XM_MMU_ENA_RX | XM_MMU_ENA_TX);
3664 }
3665#endif /* GENESIS */
3666
3667#ifdef YUKON
3668 if (pAC->GIni.GIYukon) {
3669 /*
3670 * Initialize the Interrupt Mask Register. Default IRQs are...
3671 * - Rx Counter Event Overflow
3672 * - Tx Counter Event Overflow
3673 * - Transmit FIFO Underrun
3674 */
3675 IntMask = GMAC_DEF_MSK;
3676
3677#ifdef DEBUG
3678 /* add IRQ for Receive FIFO Overrun */
3679 IntMask |= GM_IS_RX_FF_OR;
3680#endif /* DEBUG */
3681
3682 SK_OUT8(IoC, GMAC_IRQ_MSK, (SK_U8)IntMask);
3683
3684 /* get General Purpose Control */
3685 GM_IN16(IoC, Port, GM_GP_CTRL, &Reg);
3686
3687 if (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL ||
3688 pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) {
3689 /* set to Full Duplex */
3690 Reg |= GM_GPCR_DUP_FULL;
3691 }
3692
3693 /* enable Rx/Tx */
3694 GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Reg | GM_GPCR_RX_ENA |
3695 GM_GPCR_TX_ENA));
3696
3697#ifndef VCPU
3698 /* Enable all PHY interrupts */
3699 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK,
3700 (SK_U16)PHY_M_DEF_MSK);
3701#endif /* VCPU */
3702 }
3703#endif /* YUKON */
3704
3705 return(0);
3706
3707} /* SkMacRxTxEnable */
3708
3709
3710/******************************************************************************
3711 *
3712 * SkMacRxTxDisable() - Disable Receiver and Transmitter
3713 *
3714 * Description: disables Rx/Tx dep. on board type
3715 *
3716 * Returns: N/A
3717 */
3718void SkMacRxTxDisable(
3719SK_AC *pAC, /* Adapter Context */
3720SK_IOC IoC, /* IO context */
3721int Port) /* Port Index (MAC_1 + n) */
3722{
3723 SK_U16 Word;
3724
3725#ifdef GENESIS
3726 if (pAC->GIni.GIGenesis) {
3727
3728 XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
3729
3730 XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX));
3731
3732 /* dummy read to ensure writing */
3733 XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
3734 }
3735#endif /* GENESIS */
3736
3737#ifdef YUKON
3738 if (pAC->GIni.GIYukon) {
3739
3740 GM_IN16(IoC, Port, GM_GP_CTRL, &Word);
3741
3742 GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Word & ~(GM_GPCR_RX_ENA |
3743 GM_GPCR_TX_ENA)));
3744
3745 /* dummy read to ensure writing */
3746 GM_IN16(IoC, Port, GM_GP_CTRL, &Word);
3747 }
3748#endif /* YUKON */
3749
3750} /* SkMacRxTxDisable */
3751
3752
3753/******************************************************************************
3754 *
3755 * SkMacIrqDisable() - Disable IRQ from MAC
3756 *
3757 * Description: sets the IRQ-mask to disable IRQ dep. on board type
3758 *
3759 * Returns: N/A
3760 */
3761void SkMacIrqDisable(
3762SK_AC *pAC, /* Adapter Context */
3763SK_IOC IoC, /* IO context */
3764int Port) /* Port Index (MAC_1 + n) */
3765{
3766 SK_GEPORT *pPrt;
3767#ifdef GENESIS
3768 SK_U16 Word;
3769#endif
3770
3771 pPrt = &pAC->GIni.GP[Port];
3772
3773#ifdef GENESIS
3774 if (pAC->GIni.GIGenesis) {
3775
3776 /* disable all XMAC IRQs */
3777 XM_OUT16(IoC, Port, XM_IMSK, 0xffff);
3778
3779 /* Disable all PHY interrupts */
3780 switch (pPrt->PhyType) {
3781 case SK_PHY_BCOM:
3782 /* Make sure that PHY is initialized */
3783 if (pPrt->PState != SK_PRT_RESET) {
3784 /* NOT allowed if BCOM is in RESET state */
3785 /* Workaround BCOM Errata (#10523) all BCom */
3786 /* Disable Power Management if link is down */
3787 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Word);
3788 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
3789 (SK_U16)(Word | PHY_B_AC_DIS_PM));
3790 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, 0xffff);
3791 }
3792 break;
3793#ifdef OTHER_PHY
3794 case SK_PHY_LONE:
3795 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, 0);
3796 break;
3797 case SK_PHY_NAT:
3798 /* todo: National
3799 SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, 0xffff); */
3800 break;
3801#endif /* OTHER_PHY */
3802 }
3803 }
3804#endif /* GENESIS */
3805
3806#ifdef YUKON
3807 if (pAC->GIni.GIYukon) {
3808 /* disable all GMAC IRQs */
3809 SK_OUT8(IoC, GMAC_IRQ_MSK, 0);
3810
3811#ifndef VCPU
3812 /* Disable all PHY interrupts */
3813 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0);
3814#endif /* VCPU */
3815 }
3816#endif /* YUKON */
3817
3818} /* SkMacIrqDisable */
3819
3820
3821#ifdef SK_DIAG
3822/******************************************************************************
3823 *
3824 * SkXmSendCont() - Enable / Disable Send Continuous Mode
3825 *
3826 * Description: enable / disable Send Continuous Mode on XMAC
3827 *
3828 * Returns:
3829 * nothing
3830 */
3831void SkXmSendCont(
3832SK_AC *pAC, /* adapter context */
3833SK_IOC IoC, /* IO context */
3834int Port, /* Port Index (MAC_1 + n) */
3835SK_BOOL Enable) /* Enable / Disable */
3836{
3837 SK_U32 MdReg;
3838
3839 XM_IN32(IoC, Port, XM_MODE, &MdReg);
3840
3841 if (Enable) {
3842 MdReg |= XM_MD_TX_CONT;
3843 }
3844 else {
3845 MdReg &= ~XM_MD_TX_CONT;
3846 }
3847 /* setup Mode Register */
3848 XM_OUT32(IoC, Port, XM_MODE, MdReg);
3849
3850} /* SkXmSendCont */
3851
3852
3853/******************************************************************************
3854 *
3855 * SkMacTimeStamp() - Enable / Disable Time Stamp
3856 *
3857 * Description: enable / disable Time Stamp generation for Rx packets
3858 *
3859 * Returns:
3860 * nothing
3861 */
3862void SkMacTimeStamp(
3863SK_AC *pAC, /* adapter context */
3864SK_IOC IoC, /* IO context */
3865int Port, /* Port Index (MAC_1 + n) */
3866SK_BOOL Enable) /* Enable / Disable */
3867{
3868 SK_U32 MdReg;
3869 SK_U8 TimeCtrl;
3870
3871 if (pAC->GIni.GIGenesis) {
3872
3873 XM_IN32(IoC, Port, XM_MODE, &MdReg);
3874
3875 if (Enable) {
3876 MdReg |= XM_MD_ATS;
3877 }
3878 else {
3879 MdReg &= ~XM_MD_ATS;
3880 }
3881 /* setup Mode Register */
3882 XM_OUT32(IoC, Port, XM_MODE, MdReg);
3883 }
3884 else {
3885 if (Enable) {
3886 TimeCtrl = GMT_ST_START | GMT_ST_CLR_IRQ;
3887 }
3888 else {
3889 TimeCtrl = GMT_ST_STOP | GMT_ST_CLR_IRQ;
3890 }
3891 /* Start/Stop Time Stamp Timer */
3892 SK_OUT8(IoC, GMAC_TI_ST_CTRL, TimeCtrl);
3893 }
3894
3895} /* SkMacTimeStamp*/
3896
3897#else /* !SK_DIAG */
3898
3899#ifdef GENESIS
3900/******************************************************************************
3901 *
3902 * SkXmAutoNegLipaXmac() - Decides whether Link Partner could do auto-neg
3903 *
3904 * This function analyses the Interrupt status word. If any of the
3905 * Auto-negotiating interrupt bits are set, the PLipaAutoNeg variable
3906 * is set true.
3907 */
3908void SkXmAutoNegLipaXmac(
3909SK_AC *pAC, /* adapter context */
3910SK_IOC IoC, /* IO context */
3911int Port, /* Port Index (MAC_1 + n) */
3912SK_U16 IStatus) /* Interrupt Status word to analyse */
3913{
3914 SK_GEPORT *pPrt;
3915
3916 pPrt = &pAC->GIni.GP[Port];
3917
3918 if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO &&
3919 (IStatus & (XM_IS_LIPA_RC | XM_IS_RX_PAGE | XM_IS_AND)) != 0) {
3920
3921 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3922 ("AutoNegLipa: AutoNeg detected on Port %d, IStatus=0x%04X\n",
3923 Port, IStatus));
3924 pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
3925 }
3926} /* SkXmAutoNegLipaXmac */
3927#endif /* GENESIS */
3928
3929
3930/******************************************************************************
3931 *
3932 * SkMacAutoNegLipaPhy() - Decides whether Link Partner could do auto-neg
3933 *
3934 * This function analyses the PHY status word.
3935 * If any of the Auto-negotiating bits are set, the PLipaAutoNeg variable
3936 * is set true.
3937 */
3938void SkMacAutoNegLipaPhy(
3939SK_AC *pAC, /* adapter context */
3940SK_IOC IoC, /* IO context */
3941int Port, /* Port Index (MAC_1 + n) */
3942SK_U16 PhyStat) /* PHY Status word to analyse */
3943{
3944 SK_GEPORT *pPrt;
3945
3946 pPrt = &pAC->GIni.GP[Port];
3947
3948 if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO &&
3949 (PhyStat & PHY_ST_AN_OVER) != 0) {
3950
3951 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3952 ("AutoNegLipa: AutoNeg detected on Port %d, PhyStat=0x%04X\n",
3953 Port, PhyStat));
3954 pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
3955 }
3956} /* SkMacAutoNegLipaPhy */
3957
3958
3959#ifdef GENESIS
3960/******************************************************************************
3961 *
3962 * SkXmIrq() - Interrupt Service Routine
3963 *
3964 * Description: services an Interrupt Request of the XMAC
3965 *
3966 * Note:
3967 * With an external PHY, some interrupt bits are not meaningfull any more:
3968 * - LinkAsyncEvent (bit #14) XM_IS_LNK_AE
3969 * - LinkPartnerReqConfig (bit #10) XM_IS_LIPA_RC
3970 * - Page Received (bit #9) XM_IS_RX_PAGE
3971 * - NextPageLoadedForXmt (bit #8) XM_IS_TX_PAGE
3972 * - AutoNegDone (bit #7) XM_IS_AND
3973 * Also probably not valid any more is the GP0 input bit:
3974 * - GPRegisterBit0set XM_IS_INP_ASS
3975 *
3976 * Returns:
3977 * nothing
3978 */
3979void SkXmIrq(
3980SK_AC *pAC, /* adapter context */
3981SK_IOC IoC, /* IO context */
3982int Port) /* Port Index (MAC_1 + n) */
3983{
3984 SK_GEPORT *pPrt;
3985 SK_EVPARA Para;
3986 SK_U16 IStatus; /* Interrupt status read from the XMAC */
3987 SK_U16 IStatus2;
3988#ifdef SK_SLIM
3989 SK_U64 OverflowStatus;
3990#endif
3991
3992 pPrt = &pAC->GIni.GP[Port];
3993
3994 XM_IN16(IoC, Port, XM_ISRC, &IStatus);
3995
3996 /* LinkPartner Auto-negable? */
3997 if (pPrt->PhyType == SK_PHY_XMAC) {
3998 SkXmAutoNegLipaXmac(pAC, IoC, Port, IStatus);
3999 }
4000 else {
4001 /* mask bits that are not used with ext. PHY */
4002 IStatus &= ~(XM_IS_LNK_AE | XM_IS_LIPA_RC |
4003 XM_IS_RX_PAGE | XM_IS_TX_PAGE |
4004 XM_IS_AND | XM_IS_INP_ASS);
4005 }
4006
4007 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
4008 ("XmacIrq Port %d Isr 0x%04X\n", Port, IStatus));
4009
4010 if (!pPrt->PHWLinkUp) {
4011 /* Spurious XMAC interrupt */
4012 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
4013 ("SkXmIrq: spurious interrupt on Port %d\n", Port));
4014 return;
4015 }
4016
4017 if ((IStatus & XM_IS_INP_ASS) != 0) {
4018 /* Reread ISR Register if link is not in sync */
4019 XM_IN16(IoC, Port, XM_ISRC, &IStatus2);
4020
4021 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
4022 ("SkXmIrq: Link async. Double check Port %d 0x%04X 0x%04X\n",
4023 Port, IStatus, IStatus2));
4024 IStatus &= ~XM_IS_INP_ASS;
4025 IStatus |= IStatus2;
4026 }
4027
4028 if ((IStatus & XM_IS_LNK_AE) != 0) {
4029 /* not used, GP0 is used instead */
4030 }
4031
4032 if ((IStatus & XM_IS_TX_ABORT) != 0) {
4033 /* not used */
4034 }
4035
4036 if ((IStatus & XM_IS_FRC_INT) != 0) {
4037 /* not used, use ASIC IRQ instead if needed */
4038 }
4039
4040 if ((IStatus & (XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE)) != 0) {
4041 SkHWLinkDown(pAC, IoC, Port);
4042
4043 /* Signal to RLMT */
4044 Para.Para32[0] = (SK_U32)Port;
4045 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
4046
4047 /* Start workaround Errata #2 timer */
4048 SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
4049 SKGE_HWAC, SK_HWEV_WATIM, Para);
4050 }
4051
4052 if ((IStatus & XM_IS_RX_PAGE) != 0) {
4053 /* not used */
4054 }
4055
4056 if ((IStatus & XM_IS_TX_PAGE) != 0) {
4057 /* not used */
4058 }
4059
4060 if ((IStatus & XM_IS_AND) != 0) {
4061 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
4062 ("SkXmIrq: AND on link that is up Port %d\n", Port));
4063 }
4064
4065 if ((IStatus & XM_IS_TSC_OV) != 0) {
4066 /* not used */
4067 }
4068
4069 /* Combined Tx & Rx Counter Overflow SIRQ Event */
4070 if ((IStatus & (XM_IS_RXC_OV | XM_IS_TXC_OV)) != 0) {
4071#ifdef SK_SLIM
4072 SkXmOverflowStatus(pAC, IoC, Port, IStatus, &OverflowStatus);
4073#else
4074 Para.Para32[0] = (SK_U32)Port;
4075 Para.Para32[1] = (SK_U32)IStatus;
4076 SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para);
4077#endif /* SK_SLIM */
4078 }
4079
4080 if ((IStatus & XM_IS_RXF_OV) != 0) {
4081 /* normal situation -> no effect */
4082#ifdef DEBUG
4083 pPrt->PRxOverCnt++;
4084#endif /* DEBUG */
4085 }
4086
4087 if ((IStatus & XM_IS_TXF_UR) != 0) {
4088 /* may NOT happen -> error log */
4089 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E020, SKERR_SIRQ_E020MSG);
4090 }
4091
4092 if ((IStatus & XM_IS_TX_COMP) != 0) {
4093 /* not served here */
4094 }
4095
4096 if ((IStatus & XM_IS_RX_COMP) != 0) {
4097 /* not served here */
4098 }
4099} /* SkXmIrq */
4100#endif /* GENESIS */
4101
4102
4103#ifdef YUKON
4104/******************************************************************************
4105 *
4106 * SkGmIrq() - Interrupt Service Routine
4107 *
4108 * Description: services an Interrupt Request of the GMAC
4109 *
4110 * Note:
4111 *
4112 * Returns:
4113 * nothing
4114 */
4115void SkGmIrq(
4116SK_AC *pAC, /* adapter context */
4117SK_IOC IoC, /* IO context */
4118int Port) /* Port Index (MAC_1 + n) */
4119{
4120 SK_GEPORT *pPrt;
4121 SK_U8 IStatus; /* Interrupt status */
4122#ifdef SK_SLIM
4123 SK_U64 OverflowStatus;
4124#else
4125 SK_EVPARA Para;
4126#endif
4127
4128 pPrt = &pAC->GIni.GP[Port];
4129
4130 SK_IN8(IoC, GMAC_IRQ_SRC, &IStatus);
4131
4132#ifdef XXX
4133 /* LinkPartner Auto-negable? */
4134 SkMacAutoNegLipaPhy(pAC, IoC, Port, IStatus);
4135#endif /* XXX */
4136
4137 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
4138 ("GmacIrq Port %d Isr 0x%04X\n", Port, IStatus));
4139
4140 /* Combined Tx & Rx Counter Overflow SIRQ Event */
4141 if (IStatus & (GM_IS_RX_CO_OV | GM_IS_TX_CO_OV)) {
4142 /* these IRQs will be cleared by reading GMACs register */
4143#ifdef SK_SLIM
4144 SkGmOverflowStatus(pAC, IoC, Port, IStatus, &OverflowStatus);
4145#else
4146 Para.Para32[0] = (SK_U32)Port;
4147 Para.Para32[1] = (SK_U32)IStatus;
4148 SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para);
4149#endif
4150 }
4151
4152 if (IStatus & GM_IS_RX_FF_OR) {
4153 /* clear GMAC Rx FIFO Overrun IRQ */
4154 SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_CLI_RX_FO);
4155#ifdef DEBUG
4156 pPrt->PRxOverCnt++;
4157#endif /* DEBUG */
4158 }
4159
4160 if (IStatus & GM_IS_TX_FF_UR) {
4161 /* clear GMAC Tx FIFO Underrun IRQ */
4162 SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_CLI_TX_FU);
4163 /* may NOT happen -> error log */
4164 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E020, SKERR_SIRQ_E020MSG);
4165 }
4166
4167 if (IStatus & GM_IS_TX_COMPL) {
4168 /* not served here */
4169 }
4170
4171 if (IStatus & GM_IS_RX_COMPL) {
4172 /* not served here */
4173 }
4174} /* SkGmIrq */
4175#endif /* YUKON */
4176
4177
4178/******************************************************************************
4179 *
4180 * SkMacIrq() - Interrupt Service Routine for MAC
4181 *
4182 * Description: calls the Interrupt Service Routine dep. on board type
4183 *
4184 * Returns:
4185 * nothing
4186 */
4187void SkMacIrq(
4188SK_AC *pAC, /* adapter context */
4189SK_IOC IoC, /* IO context */
4190int Port) /* Port Index (MAC_1 + n) */
4191{
4192#ifdef GENESIS
4193 if (pAC->GIni.GIGenesis) {
4194 /* IRQ from XMAC */
4195 SkXmIrq(pAC, IoC, Port);
4196 }
4197#endif /* GENESIS */
4198
4199#ifdef YUKON
4200 if (pAC->GIni.GIYukon) {
4201 /* IRQ from GMAC */
4202 SkGmIrq(pAC, IoC, Port);
4203 }
4204#endif /* YUKON */
4205
4206} /* SkMacIrq */
4207
4208#endif /* !SK_DIAG */
4209
4210#ifdef GENESIS
4211/******************************************************************************
4212 *
4213 * SkXmUpdateStats() - Force the XMAC to output the current statistic
4214 *
4215 * Description:
4216 * The XMAC holds its statistic internally. To obtain the current
4217 * values a command must be sent so that the statistic data will
4218 * be written to a predefined memory area on the adapter.
4219 *
4220 * Returns:
4221 * 0: success
4222 * 1: something went wrong
4223 */
4224int SkXmUpdateStats(
4225SK_AC *pAC, /* adapter context */
4226SK_IOC IoC, /* IO context */
4227unsigned int Port) /* Port Index (MAC_1 + n) */
4228{
4229 SK_GEPORT *pPrt;
4230 SK_U16 StatReg;
4231 int WaitIndex;
4232
4233 pPrt = &pAC->GIni.GP[Port];
4234 WaitIndex = 0;
4235
4236 /* Send an update command to XMAC specified */
4237 XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_SNP_TXC | XM_SC_SNP_RXC);
4238
4239 /*
4240 * It is an auto-clearing register. If the command bits
4241 * went to zero again, the statistics are transferred.
4242 * Normally the command should be executed immediately.
4243 * But just to be sure we execute a loop.
4244 */
4245 do {
4246
4247 XM_IN16(IoC, Port, XM_STAT_CMD, &StatReg);
4248
4249 if (++WaitIndex > 10) {
4250
4251 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E021, SKERR_HWI_E021MSG);
4252
4253 return(1);
4254 }
4255 } while ((StatReg & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) != 0);
4256
4257 return(0);
4258} /* SkXmUpdateStats */
4259
4260
4261/******************************************************************************
4262 *
4263 * SkXmMacStatistic() - Get XMAC counter value
4264 *
4265 * Description:
4266 * Gets the 32bit counter value. Except for the octet counters
4267 * the lower 32bit are counted in hardware and the upper 32bit
4268 * must be counted in software by monitoring counter overflow interrupts.
4269 *
4270 * Returns:
4271 * 0: success
4272 * 1: something went wrong
4273 */
4274int SkXmMacStatistic(
4275SK_AC *pAC, /* adapter context */
4276SK_IOC IoC, /* IO context */
4277unsigned int Port, /* Port Index (MAC_1 + n) */
4278SK_U16 StatAddr, /* MIB counter base address */
4279SK_U32 SK_FAR *pVal) /* ptr to return statistic value */
4280{
4281 if ((StatAddr < XM_TXF_OK) || (StatAddr > XM_RXF_MAX_SZ)) {
4282
4283 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG);
4284
4285 return(1);
4286 }
4287
4288 XM_IN32(IoC, Port, StatAddr, pVal);
4289
4290 return(0);
4291} /* SkXmMacStatistic */
4292
4293
4294/******************************************************************************
4295 *
4296 * SkXmResetCounter() - Clear MAC statistic counter
4297 *
4298 * Description:
4299 * Force the XMAC to clear its statistic counter.
4300 *
4301 * Returns:
4302 * 0: success
4303 * 1: something went wrong
4304 */
4305int SkXmResetCounter(
4306SK_AC *pAC, /* adapter context */
4307SK_IOC IoC, /* IO context */
4308unsigned int Port) /* Port Index (MAC_1 + n) */
4309{
4310 XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC);
4311 /* Clear two times according to Errata #3 */
4312 XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC);
4313
4314 return(0);
4315} /* SkXmResetCounter */
4316
4317
4318/******************************************************************************
4319 *
4320 * SkXmOverflowStatus() - Gets the status of counter overflow interrupt
4321 *
4322 * Description:
4323 * Checks the source causing an counter overflow interrupt. On success the
4324 * resulting counter overflow status is written to <pStatus>, whereas the
4325 * upper dword stores the XMAC ReceiveCounterEvent register and the lower
4326 * dword the XMAC TransmitCounterEvent register.
4327 *
4328 * Note:
4329 * For XMAC the interrupt source is a self-clearing register, so the source
4330 * must be checked only once. SIRQ module does another check to be sure
4331 * that no interrupt get lost during process time.
4332 *
4333 * Returns:
4334 * 0: success
4335 * 1: something went wrong
4336 */
4337int SkXmOverflowStatus(
4338SK_AC *pAC, /* adapter context */
4339SK_IOC IoC, /* IO context */
4340unsigned int Port, /* Port Index (MAC_1 + n) */
4341SK_U16 IStatus, /* Interupt Status from MAC */
4342SK_U64 SK_FAR *pStatus) /* ptr for return overflow status value */
4343{
4344 SK_U64 Status; /* Overflow status */
4345 SK_U32 RegVal;
4346
4347 Status = 0;
4348
4349 if ((IStatus & XM_IS_RXC_OV) != 0) {
4350
4351 XM_IN32(IoC, Port, XM_RX_CNT_EV, &RegVal);
4352 Status |= (SK_U64)RegVal << 32;
4353 }
4354
4355 if ((IStatus & XM_IS_TXC_OV) != 0) {
4356
4357 XM_IN32(IoC, Port, XM_TX_CNT_EV, &RegVal);
4358 Status |= (SK_U64)RegVal;
4359 }
4360
4361 *pStatus = Status;
4362
4363 return(0);
4364} /* SkXmOverflowStatus */
4365#endif /* GENESIS */
4366
4367
4368#ifdef YUKON
4369/******************************************************************************
4370 *
4371 * SkGmUpdateStats() - Force the GMAC to output the current statistic
4372 *
4373 * Description:
4374 * Empty function for GMAC. Statistic data is accessible in direct way.
4375 *
4376 * Returns:
4377 * 0: success
4378 * 1: something went wrong
4379 */
4380int SkGmUpdateStats(
4381SK_AC *pAC, /* adapter context */
4382SK_IOC IoC, /* IO context */
4383unsigned int Port) /* Port Index (MAC_1 + n) */
4384{
4385 return(0);
4386}
4387
4388
4389/******************************************************************************
4390 *
4391 * SkGmMacStatistic() - Get GMAC counter value
4392 *
4393 * Description:
4394 * Gets the 32bit counter value. Except for the octet counters
4395 * the lower 32bit are counted in hardware and the upper 32bit
4396 * must be counted in software by monitoring counter overflow interrupts.
4397 *
4398 * Returns:
4399 * 0: success
4400 * 1: something went wrong
4401 */
4402int SkGmMacStatistic(
4403SK_AC *pAC, /* adapter context */
4404SK_IOC IoC, /* IO context */
4405unsigned int Port, /* Port Index (MAC_1 + n) */
4406SK_U16 StatAddr, /* MIB counter base address */
4407SK_U32 SK_FAR *pVal) /* ptr to return statistic value */
4408{
4409
4410 if ((StatAddr < GM_RXF_UC_OK) || (StatAddr > GM_TXE_FIFO_UR)) {
4411
4412 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG);
4413
4414 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
4415 ("SkGmMacStat: wrong MIB counter 0x%04X\n", StatAddr));
4416 return(1);
4417 }
4418
4419 GM_IN32(IoC, Port, StatAddr, pVal);
4420
4421 return(0);
4422} /* SkGmMacStatistic */
4423
4424
4425/******************************************************************************
4426 *
4427 * SkGmResetCounter() - Clear MAC statistic counter
4428 *
4429 * Description:
4430 * Force GMAC to clear its statistic counter.
4431 *
4432 * Returns:
4433 * 0: success
4434 * 1: something went wrong
4435 */
4436int SkGmResetCounter(
4437SK_AC *pAC, /* adapter context */
4438SK_IOC IoC, /* IO context */
4439unsigned int Port) /* Port Index (MAC_1 + n) */
4440{
4441 SK_U16 Reg; /* Phy Address Register */
4442 SK_U16 Word;
4443 int i;
4444
4445 GM_IN16(IoC, Port, GM_PHY_ADDR, &Reg);
4446
4447 /* set MIB Clear Counter Mode */
4448 GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg | GM_PAR_MIB_CLR);
4449
4450 /* read all MIB Counters with Clear Mode set */
4451 for (i = 0; i < GM_MIB_CNT_SIZE; i++) {
4452 /* the reset is performed only when the lower 16 bits are read */
4453 GM_IN16(IoC, Port, GM_MIB_CNT_BASE + 8*i, &Word);
4454 }
4455
4456 /* clear MIB Clear Counter Mode */
4457 GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg);
4458
4459 return(0);
4460} /* SkGmResetCounter */
4461
4462
4463/******************************************************************************
4464 *
4465 * SkGmOverflowStatus() - Gets the status of counter overflow interrupt
4466 *
4467 * Description:
4468 * Checks the source causing an counter overflow interrupt. On success the
4469 * resulting counter overflow status is written to <pStatus>, whereas the
4470 * the following bit coding is used:
4471 * 63:56 - unused
4472 * 55:48 - TxRx interrupt register bit7:0
4473 * 32:47 - Rx interrupt register
4474 * 31:24 - unused
4475 * 23:16 - TxRx interrupt register bit15:8
4476 * 15:0 - Tx interrupt register
4477 *
4478 * Returns:
4479 * 0: success
4480 * 1: something went wrong
4481 */
4482int SkGmOverflowStatus(
4483SK_AC *pAC, /* adapter context */
4484SK_IOC IoC, /* IO context */
4485unsigned int Port, /* Port Index (MAC_1 + n) */
4486SK_U16 IStatus, /* Interupt Status from MAC */
4487SK_U64 SK_FAR *pStatus) /* ptr for return overflow status value */
4488{
4489 SK_U64 Status; /* Overflow status */
4490 SK_U16 RegVal;
4491
4492 Status = 0;
4493
4494 if ((IStatus & GM_IS_RX_CO_OV) != 0) {
4495 /* this register is self-clearing after read */
4496 GM_IN16(IoC, Port, GM_RX_IRQ_SRC, &RegVal);
4497 Status |= (SK_U64)RegVal << 32;
4498 }
4499
4500 if ((IStatus & GM_IS_TX_CO_OV) != 0) {
4501 /* this register is self-clearing after read */
4502 GM_IN16(IoC, Port, GM_TX_IRQ_SRC, &RegVal);
4503 Status |= (SK_U64)RegVal;
4504 }
4505
4506 /* this register is self-clearing after read */
4507 GM_IN16(IoC, Port, GM_TR_IRQ_SRC, &RegVal);
4508 /* Rx overflow interrupt register bits (LoByte)*/
4509 Status |= (SK_U64)((SK_U8)RegVal) << 48;
4510 /* Tx overflow interrupt register bits (HiByte)*/
4511 Status |= (SK_U64)(RegVal >> 8) << 16;
4512
4513 *pStatus = Status;
4514
4515 return(0);
4516} /* SkGmOverflowStatus */
4517
4518
4519#ifndef SK_SLIM
4520/******************************************************************************
4521 *
4522 * SkGmCableDiagStatus() - Starts / Gets status of cable diagnostic test
4523 *
4524 * Description:
4525 * starts the cable diagnostic test if 'StartTest' is true
4526 * gets the results if 'StartTest' is true
4527 *
4528 * NOTE: this test is meaningful only when link is down
4529 *
4530 * Returns:
4531 * 0: success
4532 * 1: no YUKON copper
4533 * 2: test in progress
4534 */
4535int SkGmCableDiagStatus(
4536SK_AC *pAC, /* adapter context */
4537SK_IOC IoC, /* IO context */
4538int Port, /* Port Index (MAC_1 + n) */
4539SK_BOOL StartTest) /* flag for start / get result */
4540{
4541 int i;
4542 SK_U16 RegVal;
4543 SK_GEPORT *pPrt;
4544
4545 pPrt = &pAC->GIni.GP[Port];
4546
4547 if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
4548
4549 return(1);
4550 }
4551
4552 if (StartTest) {
4553 /* only start the cable test */
4554 if ((pPrt->PhyId1 & PHY_I1_REV_MSK) < 4) {
4555 /* apply TDR workaround from Marvell */
4556 SkGmPhyWrite(pAC, IoC, Port, 29, 0x001e);
4557
4558 SkGmPhyWrite(pAC, IoC, Port, 30, 0xcc00);
4559 SkGmPhyWrite(pAC, IoC, Port, 30, 0xc800);
4560 SkGmPhyWrite(pAC, IoC, Port, 30, 0xc400);
4561 SkGmPhyWrite(pAC, IoC, Port, 30, 0xc000);
4562 SkGmPhyWrite(pAC, IoC, Port, 30, 0xc100);
4563 }
4564
4565 /* set address to 0 for MDI[0] */
4566 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0);
4567
4568 /* Read Cable Diagnostic Reg */
4569 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
4570
4571 /* start Cable Diagnostic Test */
4572 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CABLE_DIAG,
4573 (SK_U16)(RegVal | PHY_M_CABD_ENA_TEST));
4574
4575 return(0);
4576 }
4577
4578 /* Read Cable Diagnostic Reg */
4579 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
4580
4581 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
4582 ("PHY Cable Diag.=0x%04X\n", RegVal));
4583
4584 if ((RegVal & PHY_M_CABD_ENA_TEST) != 0) {
4585 /* test is running */
4586 return(2);
4587 }
4588
4589 /* get the test results */
4590 for (i = 0; i < 4; i++) {
4591 /* set address to i for MDI[i] */
4592 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, (SK_U16)i);
4593
4594 /* get Cable Diagnostic values */
4595 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
4596
4597 pPrt->PMdiPairLen[i] = (SK_U8)(RegVal & PHY_M_CABD_DIST_MSK);
4598
4599 pPrt->PMdiPairSts[i] = (SK_U8)((RegVal & PHY_M_CABD_STAT_MSK) >> 13);
4600 }
4601
4602 return(0);
4603} /* SkGmCableDiagStatus */
4604#endif /* !SK_SLIM */
4605#endif /* YUKON */
4606
4607/* End of file */