diff options
Diffstat (limited to 'drivers/net/sk98lin')
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 | |||
13 | obj-$(CONFIG_SK98LIN) += sk98lin.o | ||
14 | sk98lin-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 | |||
36 | ifdef DEBUG | ||
37 | DBGDEF += \ | ||
38 | -DSK_DEBUG_CHKMOD=0x00000000L \ | ||
39 | -DSK_DEBUG_CHKCAT=0x00000000L | ||
40 | endif | ||
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 | |||
80 | EXTRA_CFLAGS += -Idrivers/net/sk98lin -DSK_DIAG_SUPPORT -DSK_USE_CSUM -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM) | ||
81 | |||
82 | clean: | ||
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 | ||
30 | extern "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 | ||
48 | extern "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 | |||
155 | typedef 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. */ | ||
161 | typedef union s_InexactFilter { | ||
162 | SK_U8 Bytes[8]; | ||
163 | SK_U64 Val; /* Dummy entry for alignment only. */ | ||
164 | } SK_FILTER64; | ||
165 | |||
166 | |||
167 | typedef struct s_AddrNet SK_ADDR_NET; | ||
168 | |||
169 | |||
170 | typedef 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 | |||
195 | struct 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 | |||
210 | typedef 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 | |||
228 | extern int SkAddrInit( | ||
229 | SK_AC *pAC, | ||
230 | SK_IOC IoC, | ||
231 | int Level); | ||
232 | |||
233 | extern int SkAddrMcClear( | ||
234 | SK_AC *pAC, | ||
235 | SK_IOC IoC, | ||
236 | SK_U32 PortNumber, | ||
237 | int Flags); | ||
238 | |||
239 | extern int SkAddrXmacMcClear( | ||
240 | SK_AC *pAC, | ||
241 | SK_IOC IoC, | ||
242 | SK_U32 PortNumber, | ||
243 | int Flags); | ||
244 | |||
245 | extern int SkAddrGmacMcClear( | ||
246 | SK_AC *pAC, | ||
247 | SK_IOC IoC, | ||
248 | SK_U32 PortNumber, | ||
249 | int Flags); | ||
250 | |||
251 | extern int SkAddrMcAdd( | ||
252 | SK_AC *pAC, | ||
253 | SK_IOC IoC, | ||
254 | SK_U32 PortNumber, | ||
255 | SK_MAC_ADDR *pMc, | ||
256 | int Flags); | ||
257 | |||
258 | extern int SkAddrXmacMcAdd( | ||
259 | SK_AC *pAC, | ||
260 | SK_IOC IoC, | ||
261 | SK_U32 PortNumber, | ||
262 | SK_MAC_ADDR *pMc, | ||
263 | int Flags); | ||
264 | |||
265 | extern int SkAddrGmacMcAdd( | ||
266 | SK_AC *pAC, | ||
267 | SK_IOC IoC, | ||
268 | SK_U32 PortNumber, | ||
269 | SK_MAC_ADDR *pMc, | ||
270 | int Flags); | ||
271 | |||
272 | extern int SkAddrMcUpdate( | ||
273 | SK_AC *pAC, | ||
274 | SK_IOC IoC, | ||
275 | SK_U32 PortNumber); | ||
276 | |||
277 | extern int SkAddrXmacMcUpdate( | ||
278 | SK_AC *pAC, | ||
279 | SK_IOC IoC, | ||
280 | SK_U32 PortNumber); | ||
281 | |||
282 | extern int SkAddrGmacMcUpdate( | ||
283 | SK_AC *pAC, | ||
284 | SK_IOC IoC, | ||
285 | SK_U32 PortNumber); | ||
286 | |||
287 | extern 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 | |||
294 | extern int SkAddrPromiscuousChange( | ||
295 | SK_AC *pAC, | ||
296 | SK_IOC IoC, | ||
297 | SK_U32 PortNumber, | ||
298 | int NewPromMode); | ||
299 | |||
300 | extern int SkAddrXmacPromiscuousChange( | ||
301 | SK_AC *pAC, | ||
302 | SK_IOC IoC, | ||
303 | SK_U32 PortNumber, | ||
304 | int NewPromMode); | ||
305 | |||
306 | extern int SkAddrGmacPromiscuousChange( | ||
307 | SK_AC *pAC, | ||
308 | SK_IOC IoC, | ||
309 | SK_U32 PortNumber, | ||
310 | int NewPromMode); | ||
311 | |||
312 | #ifndef SK_SLIM | ||
313 | extern 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 | */ | ||
146 | typedef 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 | */ | ||
157 | typedef 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 | */ | ||
171 | typedef 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 | ||
188 | extern unsigned SkCsCalculateChecksum( | ||
189 | void *pData, | ||
190 | unsigned Length); | ||
191 | #endif /* SK_CS_CALCULATE_CHECKSUM */ | ||
192 | |||
193 | extern int SkCsEvent( | ||
194 | SK_AC *pAc, | ||
195 | SK_IOC Ioc, | ||
196 | SK_U32 Event, | ||
197 | SK_EVPARA Param); | ||
198 | |||
199 | extern SKCS_STATUS SkCsGetReceiveInfo( | ||
200 | SK_AC *pAc, | ||
201 | void *pIpHeader, | ||
202 | unsigned Checksum1, | ||
203 | unsigned Checksum2, | ||
204 | int NetNumber); | ||
205 | |||
206 | extern void SkCsGetSendInfo( | ||
207 | SK_AC *pAc, | ||
208 | void *pIpHeader, | ||
209 | SKCS_PACKET_INFO *pPacketInfo, | ||
210 | int NetNumber); | ||
211 | |||
212 | extern 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 | |||
45 | typedef 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 | |||
115 | typedef 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 | |||
166 | extern 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 | |||
188 | extern 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 | |||
57 | extern SK_MBUF *SkDrvAllocRlmtMbuf(SK_AC*, SK_IOC, unsigned); | ||
58 | extern void SkDrvFreeRlmtMbuf(SK_AC*, SK_IOC, SK_MBUF*); | ||
59 | extern SK_U64 SkOsGetTime(SK_AC*); | ||
60 | extern int SkPciReadCfgDWord(SK_AC*, int, SK_U32*); | ||
61 | extern int SkPciReadCfgWord(SK_AC*, int, SK_U16*); | ||
62 | extern int SkPciReadCfgByte(SK_AC*, int, SK_U8*); | ||
63 | extern int SkPciWriteCfgDWord(SK_AC*, int, SK_U32); | ||
64 | extern int SkPciWriteCfgWord(SK_AC*, int, SK_U16); | ||
65 | extern int SkPciWriteCfgByte(SK_AC*, int, SK_U8); | ||
66 | extern int SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA); | ||
67 | |||
68 | #ifdef SK_DIAG_SUPPORT | ||
69 | extern int SkDrvEnterDiagMode(SK_AC *pAc); | ||
70 | extern int SkDrvLeaveDiagMode(SK_AC *pAc); | ||
71 | #endif | ||
72 | |||
73 | struct 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 | |||
116 | typedef struct s_IOCTL SK_GE_IOCTL; | ||
117 | |||
118 | struct 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 | |||
203 | typedef struct s_RxD RXD; /* the receive descriptor */ | ||
204 | |||
205 | struct 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 | |||
218 | typedef struct s_TxD TXD; /* the transmit descriptor */ | ||
219 | |||
220 | struct 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 | |||
266 | typedef struct s_DevNet DEV_NET; | ||
267 | |||
268 | struct s_DevNet { | ||
269 | int PortNr; | ||
270 | int NetNr; | ||
271 | int Mtu; | ||
272 | int Up; | ||
273 | SK_AC *pAC; | ||
274 | }; | ||
275 | |||
276 | typedef struct s_TxPort TX_PORT; | ||
277 | |||
278 | struct 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 | |||
291 | typedef struct s_RxPort RX_PORT; | ||
292 | |||
293 | struct 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 | |||
333 | typedef struct s_DynIrqModInfo DIM_INFO; | ||
334 | struct 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 | |||
359 | typedef 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 | */ | ||
373 | struct 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 | ||
29 | extern "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 */ | ||
1603 | typedef 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 */ | ||
1624 | typedef 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 | */ | ||
37 | typedef 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 | |||
43 | extern void SkHwtInit(SK_AC *pAC, SK_IOC Ioc); | ||
44 | extern void SkHwtStart(SK_AC *pAC, SK_IOC Ioc, SK_U32 Time); | ||
45 | extern void SkHwtStop(SK_AC *pAC, SK_IOC Ioc); | ||
46 | extern SK_U32 SkHwtRead(SK_AC *pAC, SK_IOC Ioc); | ||
47 | extern 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 | |||
209 | extern 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 | ||
29 | extern "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 | */ | ||
298 | typedef 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 | */ | ||
310 | typedef 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 | */ | ||
378 | typedef 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 | */ | ||
467 | extern void SkGePollRxD( | ||
468 | SK_AC *pAC, | ||
469 | SK_IOC IoC, | ||
470 | int Port, | ||
471 | SK_BOOL PollRxD); | ||
472 | |||
473 | extern void SkGePollTxD( | ||
474 | SK_AC *pAC, | ||
475 | SK_IOC IoC, | ||
476 | int Port, | ||
477 | SK_BOOL PollTxD); | ||
478 | |||
479 | extern void SkGeYellowLED( | ||
480 | SK_AC *pAC, | ||
481 | SK_IOC IoC, | ||
482 | int State); | ||
483 | |||
484 | extern 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 | |||
492 | extern void SkGeLoadLnkSyncCnt( | ||
493 | SK_AC *pAC, | ||
494 | SK_IOC IoC, | ||
495 | int Port, | ||
496 | SK_U32 CntVal); | ||
497 | |||
498 | extern void SkGeStopPort( | ||
499 | SK_AC *pAC, | ||
500 | SK_IOC IoC, | ||
501 | int Port, | ||
502 | int Dir, | ||
503 | int RstMode); | ||
504 | |||
505 | extern int SkGeInit( | ||
506 | SK_AC *pAC, | ||
507 | SK_IOC IoC, | ||
508 | int Level); | ||
509 | |||
510 | extern void SkGeDeInit( | ||
511 | SK_AC *pAC, | ||
512 | SK_IOC IoC); | ||
513 | |||
514 | extern int SkGeInitPort( | ||
515 | SK_AC *pAC, | ||
516 | SK_IOC IoC, | ||
517 | int Port); | ||
518 | |||
519 | extern void SkGeXmitLED( | ||
520 | SK_AC *pAC, | ||
521 | SK_IOC IoC, | ||
522 | int Led, | ||
523 | int Mode); | ||
524 | |||
525 | extern void SkGeInitRamIface( | ||
526 | SK_AC *pAC, | ||
527 | SK_IOC IoC); | ||
528 | |||
529 | extern int SkGeInitAssignRamToQueues( | ||
530 | SK_AC *pAC, | ||
531 | int ActivePort, | ||
532 | SK_BOOL DualNet); | ||
533 | |||
534 | /* | ||
535 | * public functions in skxmac2.c | ||
536 | */ | ||
537 | extern void SkMacRxTxDisable( | ||
538 | SK_AC *pAC, | ||
539 | SK_IOC IoC, | ||
540 | int Port); | ||
541 | |||
542 | extern void SkMacSoftRst( | ||
543 | SK_AC *pAC, | ||
544 | SK_IOC IoC, | ||
545 | int Port); | ||
546 | |||
547 | extern void SkMacHardRst( | ||
548 | SK_AC *pAC, | ||
549 | SK_IOC IoC, | ||
550 | int Port); | ||
551 | |||
552 | extern void SkMacClearRst( | ||
553 | SK_AC *pAC, | ||
554 | SK_IOC IoC, | ||
555 | int Port); | ||
556 | |||
557 | extern void SkXmInitMac( | ||
558 | SK_AC *pAC, | ||
559 | SK_IOC IoC, | ||
560 | int Port); | ||
561 | |||
562 | extern void SkGmInitMac( | ||
563 | SK_AC *pAC, | ||
564 | SK_IOC IoC, | ||
565 | int Port); | ||
566 | |||
567 | extern void SkMacInitPhy( | ||
568 | SK_AC *pAC, | ||
569 | SK_IOC IoC, | ||
570 | int Port, | ||
571 | SK_BOOL DoLoop); | ||
572 | |||
573 | extern void SkMacIrqDisable( | ||
574 | SK_AC *pAC, | ||
575 | SK_IOC IoC, | ||
576 | int Port); | ||
577 | |||
578 | extern void SkMacFlushTxFifo( | ||
579 | SK_AC *pAC, | ||
580 | SK_IOC IoC, | ||
581 | int Port); | ||
582 | |||
583 | extern void SkMacFlushRxFifo( | ||
584 | SK_AC *pAC, | ||
585 | SK_IOC IoC, | ||
586 | int Port); | ||
587 | |||
588 | extern void SkMacIrq( | ||
589 | SK_AC *pAC, | ||
590 | SK_IOC IoC, | ||
591 | int Port); | ||
592 | |||
593 | extern int SkMacAutoNegDone( | ||
594 | SK_AC *pAC, | ||
595 | SK_IOC IoC, | ||
596 | int Port); | ||
597 | |||
598 | extern void SkMacAutoNegLipaPhy( | ||
599 | SK_AC *pAC, | ||
600 | SK_IOC IoC, | ||
601 | int Port, | ||
602 | SK_U16 IStatus); | ||
603 | |||
604 | extern void SkMacSetRxTxEn( | ||
605 | SK_AC *pAC, | ||
606 | SK_IOC IoC, | ||
607 | int Port, | ||
608 | int Para); | ||
609 | |||
610 | extern int SkMacRxTxEnable( | ||
611 | SK_AC *pAC, | ||
612 | SK_IOC IoC, | ||
613 | int Port); | ||
614 | |||
615 | extern void SkMacPromiscMode( | ||
616 | SK_AC *pAC, | ||
617 | SK_IOC IoC, | ||
618 | int Port, | ||
619 | SK_BOOL Enable); | ||
620 | |||
621 | extern void SkMacHashing( | ||
622 | SK_AC *pAC, | ||
623 | SK_IOC IoC, | ||
624 | int Port, | ||
625 | SK_BOOL Enable); | ||
626 | |||
627 | extern void SkXmPhyRead( | ||
628 | SK_AC *pAC, | ||
629 | SK_IOC IoC, | ||
630 | int Port, | ||
631 | int Addr, | ||
632 | SK_U16 SK_FAR *pVal); | ||
633 | |||
634 | extern void SkXmPhyWrite( | ||
635 | SK_AC *pAC, | ||
636 | SK_IOC IoC, | ||
637 | int Port, | ||
638 | int Addr, | ||
639 | SK_U16 Val); | ||
640 | |||
641 | extern void SkGmPhyRead( | ||
642 | SK_AC *pAC, | ||
643 | SK_IOC IoC, | ||
644 | int Port, | ||
645 | int Addr, | ||
646 | SK_U16 SK_FAR *pVal); | ||
647 | |||
648 | extern void SkGmPhyWrite( | ||
649 | SK_AC *pAC, | ||
650 | SK_IOC IoC, | ||
651 | int Port, | ||
652 | int Addr, | ||
653 | SK_U16 Val); | ||
654 | |||
655 | extern void SkXmClrExactAddr( | ||
656 | SK_AC *pAC, | ||
657 | SK_IOC IoC, | ||
658 | int Port, | ||
659 | int StartNum, | ||
660 | int StopNum); | ||
661 | |||
662 | extern void SkXmInitDupMd( | ||
663 | SK_AC *pAC, | ||
664 | SK_IOC IoC, | ||
665 | int Port); | ||
666 | |||
667 | extern void SkXmInitPauseMd( | ||
668 | SK_AC *pAC, | ||
669 | SK_IOC IoC, | ||
670 | int Port); | ||
671 | |||
672 | extern void SkXmAutoNegLipaXmac( | ||
673 | SK_AC *pAC, | ||
674 | SK_IOC IoC, | ||
675 | int Port, | ||
676 | SK_U16 IStatus); | ||
677 | |||
678 | extern int SkXmUpdateStats( | ||
679 | SK_AC *pAC, | ||
680 | SK_IOC IoC, | ||
681 | unsigned int Port); | ||
682 | |||
683 | extern int SkGmUpdateStats( | ||
684 | SK_AC *pAC, | ||
685 | SK_IOC IoC, | ||
686 | unsigned int Port); | ||
687 | |||
688 | extern 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 | |||
695 | extern 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 | |||
702 | extern int SkXmResetCounter( | ||
703 | SK_AC *pAC, | ||
704 | SK_IOC IoC, | ||
705 | unsigned int Port); | ||
706 | |||
707 | extern int SkGmResetCounter( | ||
708 | SK_AC *pAC, | ||
709 | SK_IOC IoC, | ||
710 | unsigned int Port); | ||
711 | |||
712 | extern 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 | |||
719 | extern 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 | |||
726 | extern int SkGmCableDiagStatus( | ||
727 | SK_AC *pAC, | ||
728 | SK_IOC IoC, | ||
729 | int Port, | ||
730 | SK_BOOL StartTest); | ||
731 | |||
732 | extern int SkGmEnterLowPowerMode( | ||
733 | SK_AC *pAC, | ||
734 | SK_IOC IoC, | ||
735 | int Port, | ||
736 | SK_U8 Mode); | ||
737 | |||
738 | extern int SkGmLeaveLowPowerMode( | ||
739 | SK_AC *pAC, | ||
740 | SK_IOC IoC, | ||
741 | int Port); | ||
742 | |||
743 | #ifdef SK_DIAG | ||
744 | extern void SkGePhyRead( | ||
745 | SK_AC *pAC, | ||
746 | SK_IOC IoC, | ||
747 | int Port, | ||
748 | int Addr, | ||
749 | SK_U16 *pVal); | ||
750 | |||
751 | extern void SkGePhyWrite( | ||
752 | SK_AC *pAC, | ||
753 | SK_IOC IoC, | ||
754 | int Port, | ||
755 | int Addr, | ||
756 | SK_U16 Val); | ||
757 | |||
758 | extern void SkMacSetRxCmd( | ||
759 | SK_AC *pAC, | ||
760 | SK_IOC IoC, | ||
761 | int Port, | ||
762 | int Mode); | ||
763 | extern void SkMacCrcGener( | ||
764 | SK_AC *pAC, | ||
765 | SK_IOC IoC, | ||
766 | int Port, | ||
767 | SK_BOOL Enable); | ||
768 | extern void SkMacTimeStamp( | ||
769 | SK_AC *pAC, | ||
770 | SK_IOC IoC, | ||
771 | int Port, | ||
772 | SK_BOOL Enable); | ||
773 | extern 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 | */ | ||
785 | extern void SkGePollRxD(); | ||
786 | extern void SkGePollTxD(); | ||
787 | extern void SkGeYellowLED(); | ||
788 | extern int SkGeCfgSync(); | ||
789 | extern void SkGeLoadLnkSyncCnt(); | ||
790 | extern void SkGeStopPort(); | ||
791 | extern int SkGeInit(); | ||
792 | extern void SkGeDeInit(); | ||
793 | extern int SkGeInitPort(); | ||
794 | extern void SkGeXmitLED(); | ||
795 | extern void SkGeInitRamIface(); | ||
796 | extern int SkGeInitAssignRamToQueues(); | ||
797 | |||
798 | /* | ||
799 | * public functions in skxmac2.c | ||
800 | */ | ||
801 | extern void SkMacRxTxDisable(); | ||
802 | extern void SkMacSoftRst(); | ||
803 | extern void SkMacHardRst(); | ||
804 | extern void SkMacClearRst(); | ||
805 | extern void SkMacInitPhy(); | ||
806 | extern int SkMacRxTxEnable(); | ||
807 | extern void SkMacPromiscMode(); | ||
808 | extern void SkMacHashing(); | ||
809 | extern void SkMacIrqDisable(); | ||
810 | extern void SkMacFlushTxFifo(); | ||
811 | extern void SkMacFlushRxFifo(); | ||
812 | extern void SkMacIrq(); | ||
813 | extern int SkMacAutoNegDone(); | ||
814 | extern void SkMacAutoNegLipaPhy(); | ||
815 | extern void SkMacSetRxTxEn(); | ||
816 | extern void SkXmInitMac(); | ||
817 | extern void SkXmPhyRead(); | ||
818 | extern void SkXmPhyWrite(); | ||
819 | extern void SkGmInitMac(); | ||
820 | extern void SkGmPhyRead(); | ||
821 | extern void SkGmPhyWrite(); | ||
822 | extern void SkXmClrExactAddr(); | ||
823 | extern void SkXmInitDupMd(); | ||
824 | extern void SkXmInitPauseMd(); | ||
825 | extern void SkXmAutoNegLipaXmac(); | ||
826 | extern int SkXmUpdateStats(); | ||
827 | extern int SkGmUpdateStats(); | ||
828 | extern int SkXmMacStatistic(); | ||
829 | extern int SkGmMacStatistic(); | ||
830 | extern int SkXmResetCounter(); | ||
831 | extern int SkGmResetCounter(); | ||
832 | extern int SkXmOverflowStatus(); | ||
833 | extern int SkGmOverflowStatus(); | ||
834 | extern int SkGmCableDiagStatus(); | ||
835 | extern int SkGmEnterLowPowerMode(); | ||
836 | extern int SkGmLeaveLowPowerMode(); | ||
837 | |||
838 | #ifdef SK_DIAG | ||
839 | extern void SkGePhyRead(); | ||
840 | extern void SkGePhyWrite(); | ||
841 | extern void SkMacSetRxCmd(); | ||
842 | extern void SkMacCrcGener(); | ||
843 | extern void SkMacTimeStamp(); | ||
844 | extern 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 | |||
88 | typedef 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 | */ | ||
118 | enum 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 | */ | ||
197 | typedef 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. */ | ||
371 | typedef 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 | |||
632 | typedef 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 | |||
639 | typedef 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 | |||
655 | typedef 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 | |||
663 | typedef 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 | |||
722 | typedef 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 | |||
744 | typedef 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 | |||
753 | typedef 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 | |||
761 | typedef struct s_PnmiRequestStatus { | ||
762 | SK_U32 ErrorStatus; | ||
763 | SK_U32 ErrorOffset; | ||
764 | } SK_PNMI_REQUEST_STATUS; | ||
765 | |||
766 | typedef 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 | */ | ||
850 | typedef 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 | */ | ||
861 | typedef struct s_VctTimer { | ||
862 | SK_TIMER VctTimer; | ||
863 | } SK_PNMI_VCT_TIMER; | ||
864 | |||
865 | |||
866 | /* | ||
867 | * PNMI specific adapter context structure | ||
868 | */ | ||
869 | typedef 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 | |||
898 | typedef 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 | */ | ||
948 | extern int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int Level); | ||
949 | extern int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf, | ||
950 | unsigned int* pLen, SK_U32 Instance, SK_U32 NetIndex); | ||
951 | extern int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, | ||
952 | void* pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); | ||
953 | extern int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf, | ||
954 | unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); | ||
955 | extern int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf, | ||
956 | unsigned int *pLen, SK_U32 NetIndex); | ||
957 | extern int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf, | ||
958 | unsigned int *pLen, SK_U32 NetIndex); | ||
959 | extern int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf, | ||
960 | unsigned int *pLen, SK_U32 NetIndex); | ||
961 | extern int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, | ||
962 | SK_EVPARA Param); | ||
963 | extern 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 | |||
106 | extern void SkGeSirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus); | ||
107 | extern int SkGeSirqEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para); | ||
108 | extern void SkHWLinkUp(SK_AC *pAC, SK_IOC IoC, int Port); | ||
109 | extern 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 | |||
32 | typedef 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 | */ | ||
127 | struct 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 | |||
152 | typedef 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 | |||
164 | extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level); | ||
165 | extern int SkI2cWrite(SK_AC *pAC, SK_IOC IoC, SK_U32 Data, int Dev, int Size, | ||
166 | int Reg, int Burst); | ||
167 | extern int SkI2cReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen); | ||
168 | #ifdef SK_DIAG | ||
169 | extern SK_U32 SkI2cRead(SK_AC *pAC, SK_IOC IoC, int Dev, int Size, int Reg, | ||
170 | int Burst); | ||
171 | #else /* !SK_DIAG */ | ||
172 | extern int SkI2cEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para); | ||
173 | extern void SkI2cWaitIrq(SK_AC *pAC, SK_IOC IoC); | ||
174 | extern 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 | */ | ||
57 | typedef 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 | */ | ||
70 | typedef 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 | |||
76 | typedef struct s_Queue { | ||
77 | SK_EVENTELEM EvQueue[SK_MAX_EVENT]; | ||
78 | SK_EVENTELEM *EvPut; | ||
79 | SK_EVENTELEM *EvGet; | ||
80 | } SK_QUEUE; | ||
81 | |||
82 | extern void SkEventInit(SK_AC *pAC, SK_IOC Ioc, int Level); | ||
83 | extern void SkEventQueue(SK_AC *pAC, SK_U32 Class, SK_U32 Event, | ||
84 | SK_EVPARA Para); | ||
85 | extern 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 | ||
48 | extern "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 | ||
155 | SK_AC *pAC /* adapter context */ | ||
156 | SK_U32 PortNum /* receiving port */ | ||
157 | unsigned PktLen /* received packet's length */ | ||
158 | SK_BOOL IsBc /* Flag: packet is broadcast */ | ||
159 | unsigned *pOffset /* offs. of bytes to present to SK_RLMT_LOOKAHEAD */ | ||
160 | unsigned *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 | ||
200 | SK_AC *pAC /* adapter context */ | ||
201 | SK_U32 PortNum /* receiving port */ | ||
202 | SK_U8 *pLaPacket, /* received packet's data (points to pOffset) */ | ||
203 | SK_BOOL IsBc /* Flag: packet is broadcast */ | ||
204 | SK_BOOL IsMc /* Flag: packet is multicast */ | ||
205 | unsigned *pForRlmt /* Result: bits SK_RLMT_RX_RLMT, SK_RLMT_RX_PROTOCOL */ | ||
206 | SK_RLMT_LOOKAHEAD() expects *pNumBytes from | ||
207 | packet offset *pOffset (s.a.) at *pLaPacket. | ||
208 | |||
209 | If you use SK_RLMT_LOOKAHEAD in a path where you already know if the packet is | ||
210 | BC, MC, or UC, you should use constants for IsBc and IsMc, so that your compiler | ||
211 | can 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 | ||
262 | Error: SK_RLMT_FAST_LOOKAHEAD no longer used. Use new macros for lookahead. | ||
263 | #endif /* SK_RLMT_FAST_LOOKAHEAD */ | ||
264 | #ifdef SK_RLMT_SLOW_LOOKAHEAD | ||
265 | Error: 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 | ||
271 | typedef struct s_RlmtMbuf { | ||
272 | some content | ||
273 | } SK_RLMT_MBUF; | ||
274 | #endif /* SK_RLMT_MBUF_PRIVATE */ | ||
275 | |||
276 | |||
277 | #ifdef SK_LA_INFO | ||
278 | typedef 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 | |||
285 | typedef struct s_RootId { | ||
286 | SK_U8 Id[8]; /* Root Bridge Id. */ | ||
287 | } SK_RLMT_ROOT_ID; | ||
288 | |||
289 | |||
290 | typedef struct s_port { | ||
291 | SK_MAC_ADDR CheckAddr; | ||
292 | SK_BOOL SuspectTx; | ||
293 | } SK_PORT_CHECK; | ||
294 | |||
295 | |||
296 | typedef struct s_RlmtNet SK_RLMT_NET; | ||
297 | |||
298 | |||
299 | typedef 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 | |||
348 | struct 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 | |||
383 | typedef 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 | |||
402 | extern SK_MAC_ADDR BridgeMcAddr; | ||
403 | extern 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 | |||
414 | extern void SkRlmtInit( | ||
415 | SK_AC *pAC, | ||
416 | SK_IOC IoC, | ||
417 | int Level); | ||
418 | |||
419 | extern 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 | */ | ||
39 | typedef struct s_Timer SK_TIMER; | ||
40 | |||
41 | struct 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 | */ | ||
54 | typedef struct s_TimCtrl { | ||
55 | SK_TIMER *StQueue; /* Head of Timer queue */ | ||
56 | } SK_TIMCTRL; | ||
57 | |||
58 | extern void SkTimerInit(SK_AC *pAC, SK_IOC Ioc, int Level); | ||
59 | extern void SkTimerStop(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer); | ||
60 | extern void SkTimerStart(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer, | ||
61 | SK_U32 Time, SK_U32 Class, SK_U32 Event, SK_EVPARA Para); | ||
62 | extern 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 | ||
26 | static const char SysKonnectFileId[] = "@(#) (C) SysKonnect GmbH."; | ||
27 | static 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 | */ | ||
91 | typedef 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 | |||
98 | typedef 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 | |||
105 | typedef 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 | */ | ||
119 | typedef 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 | ||
188 | extern SK_U32 VpdReadDWord( | ||
189 | SK_AC *pAC, | ||
190 | SK_IOC IoC, | ||
191 | int addr); | ||
192 | #endif /* SKDIAG */ | ||
193 | |||
194 | extern int VpdSetupPara( | ||
195 | SK_AC *pAC, | ||
196 | const char *key, | ||
197 | const char *buf, | ||
198 | int len, | ||
199 | int type, | ||
200 | int op); | ||
201 | |||
202 | extern SK_VPD_STATUS *VpdStat( | ||
203 | SK_AC *pAC, | ||
204 | SK_IOC IoC); | ||
205 | |||
206 | extern int VpdKeys( | ||
207 | SK_AC *pAC, | ||
208 | SK_IOC IoC, | ||
209 | char *buf, | ||
210 | int *len, | ||
211 | int *elements); | ||
212 | |||
213 | extern int VpdRead( | ||
214 | SK_AC *pAC, | ||
215 | SK_IOC IoC, | ||
216 | const char *key, | ||
217 | char *buf, | ||
218 | int *len); | ||
219 | |||
220 | extern SK_BOOL VpdMayWrite( | ||
221 | char *key); | ||
222 | |||
223 | extern int VpdWrite( | ||
224 | SK_AC *pAC, | ||
225 | SK_IOC IoC, | ||
226 | const char *key, | ||
227 | const char *buf); | ||
228 | |||
229 | extern int VpdDelete( | ||
230 | SK_AC *pAC, | ||
231 | SK_IOC IoC, | ||
232 | char *key); | ||
233 | |||
234 | extern int VpdUpdate( | ||
235 | SK_AC *pAC, | ||
236 | SK_IOC IoC); | ||
237 | |||
238 | extern void VpdErrLog( | ||
239 | SK_AC *pAC, | ||
240 | SK_IOC IoC, | ||
241 | char *msg); | ||
242 | |||
243 | #ifdef SKDIAG | ||
244 | extern int VpdReadBlock( | ||
245 | SK_AC *pAC, | ||
246 | SK_IOC IoC, | ||
247 | char *buf, | ||
248 | int addr, | ||
249 | int len); | ||
250 | |||
251 | extern 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 */ | ||
259 | extern SK_U32 VpdReadDWord(); | ||
260 | extern int VpdSetupPara(); | ||
261 | extern SK_VPD_STATUS *VpdStat(); | ||
262 | extern int VpdKeys(); | ||
263 | extern int VpdRead(); | ||
264 | extern SK_BOOL VpdMayWrite(); | ||
265 | extern int VpdWrite(); | ||
266 | extern int VpdDelete(); | ||
267 | extern int VpdUpdate(); | ||
268 | extern 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 | ||
29 | extern "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)))) | ||
46 | static 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 | ||
53 | extern "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 | |||
82 | static const SK_U16 OnesHash[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}; | ||
83 | |||
84 | /* local variables ************************************************************/ | ||
85 | |||
86 | #ifdef DEBUG | ||
87 | static 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 | */ | ||
126 | int SkAddrInit( | ||
127 | SK_AC *pAC, /* the adapter context */ | ||
128 | SK_IOC IoC, /* I/O context */ | ||
129 | int 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 | */ | ||
329 | int SkAddrMcClear( | ||
330 | SK_AC *pAC, /* adapter context */ | ||
331 | SK_IOC IoC, /* I/O context */ | ||
332 | SK_U32 PortNumber, /* Index of affected port */ | ||
333 | int 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 | */ | ||
375 | int SkAddrXmacMcClear( | ||
376 | SK_AC *pAC, /* adapter context */ | ||
377 | SK_IOC IoC, /* I/O context */ | ||
378 | SK_U32 PortNumber, /* Index of affected port */ | ||
379 | int 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 | */ | ||
432 | int SkAddrGmacMcClear( | ||
433 | SK_AC *pAC, /* adapter context */ | ||
434 | SK_IOC IoC, /* I/O context */ | ||
435 | SK_U32 PortNumber, /* Index of affected port */ | ||
436 | int 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 | */ | ||
522 | SK_U32 SkXmacMcHash( | ||
523 | unsigned 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 | */ | ||
560 | SK_U32 SkGmacMcHash( | ||
561 | unsigned 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 | */ | ||
627 | int SkAddrMcAdd( | ||
628 | SK_AC *pAC, /* adapter context */ | ||
629 | SK_IOC IoC, /* I/O context */ | ||
630 | SK_U32 PortNumber, /* Port Number */ | ||
631 | SK_MAC_ADDR *pMc, /* multicast address to be added */ | ||
632 | int 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 | */ | ||
675 | int SkAddrXmacMcAdd( | ||
676 | SK_AC *pAC, /* adapter context */ | ||
677 | SK_IOC IoC, /* I/O context */ | ||
678 | SK_U32 PortNumber, /* Port Number */ | ||
679 | SK_MAC_ADDR *pMc, /* multicast address to be added */ | ||
680 | int 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 | */ | ||
781 | int SkAddrGmacMcAdd( | ||
782 | SK_AC *pAC, /* adapter context */ | ||
783 | SK_IOC IoC, /* I/O context */ | ||
784 | SK_U32 PortNumber, /* Port Number */ | ||
785 | SK_MAC_ADDR *pMc, /* multicast address to be added */ | ||
786 | int 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 | */ | ||
890 | int SkAddrMcUpdate( | ||
891 | SK_AC *pAC, /* adapter context */ | ||
892 | SK_IOC IoC, /* I/O context */ | ||
893 | SK_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 | */ | ||
940 | int SkAddrXmacMcUpdate( | ||
941 | SK_AC *pAC, /* adapter context */ | ||
942 | SK_IOC IoC, /* I/O context */ | ||
943 | SK_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 | */ | ||
1085 | int SkAddrGmacMcUpdate( | ||
1086 | SK_AC *pAC, /* adapter context */ | ||
1087 | SK_IOC IoC, /* I/O context */ | ||
1088 | SK_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 | */ | ||
1207 | int SkAddrOverride( | ||
1208 | SK_AC *pAC, /* adapter context */ | ||
1209 | SK_IOC IoC, /* I/O context */ | ||
1210 | SK_U32 PortNumber, /* Port Number */ | ||
1211 | SK_MAC_ADDR SK_FAR *pNewAddr, /* new MAC address */ | ||
1212 | int 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 | */ | ||
1421 | int SkAddrPromiscuousChange( | ||
1422 | SK_AC *pAC, /* adapter context */ | ||
1423 | SK_IOC IoC, /* I/O context */ | ||
1424 | SK_U32 PortNumber, /* port whose promiscuous mode changes */ | ||
1425 | int 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 | */ | ||
1471 | int SkAddrXmacPromiscuousChange( | ||
1472 | SK_AC *pAC, /* adapter context */ | ||
1473 | SK_IOC IoC, /* I/O context */ | ||
1474 | SK_U32 PortNumber, /* port whose promiscuous mode changes */ | ||
1475 | int 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 | */ | ||
1588 | int SkAddrGmacPromiscuousChange( | ||
1589 | SK_AC *pAC, /* adapter context */ | ||
1590 | SK_IOC IoC, /* I/O context */ | ||
1591 | SK_U32 PortNumber, /* port whose promiscuous mode changes */ | ||
1592 | int 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 | */ | ||
1673 | int SkAddrSwap( | ||
1674 | SK_AC *pAC, /* adapter context */ | ||
1675 | SK_IOC IoC, /* I/O context */ | ||
1676 | SK_U32 FromPortNumber, /* Port1 Index */ | ||
1677 | SK_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 | ||
27 | static 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 | */ | ||
210 | void SkCsGetSendInfo( | ||
211 | SK_AC *pAc, /* Adapter context struct. */ | ||
212 | void *pIpHeader, /* IP header. */ | ||
213 | SKCS_PACKET_INFO *pPacketInfo, /* Packet information struct. */ | ||
214 | int 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 | */ | ||
437 | SKCS_STATUS SkCsGetReceiveInfo( | ||
438 | SK_AC *pAc, /* Adapter context struct. */ | ||
439 | void *pIpHeader, /* IP header. */ | ||
440 | unsigned Checksum1, /* Hardware checksum 1. */ | ||
441 | unsigned Checksum2, /* Hardware checksum 2. */ | ||
442 | int 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 | */ | ||
720 | void SkCsSetReceiveFlags( | ||
721 | SK_AC *pAc, /* Adapter context struct. */ | ||
722 | unsigned ReceiveFlags, /* New receive flags. */ | ||
723 | unsigned *pChecksum1Offset, /* Offset for hardware checksum 1. */ | ||
724 | unsigned *pChecksum2Offset, /* Offset for hardware checksum 2. */ | ||
725 | int 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 | */ | ||
767 | unsigned SkCsCalculateChecksum( | ||
768 | void *pData, /* Data to checksum. */ | ||
769 | unsigned 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 | */ | ||
834 | int SkCsEvent( | ||
835 | SK_AC *pAc, /* Pointer to adapter context. */ | ||
836 | SK_IOC Ioc, /* I/O context. */ | ||
837 | SK_U32 Event, /* Event id. */ | ||
838 | SK_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 | ||
40 | static 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. | ||
48 | extern "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 | |||
85 | static unsigned int GetCurrentSystemLoad(SK_AC *pAC); | ||
86 | static SK_U64 GetIsrCalls(SK_AC *pAC); | ||
87 | static SK_BOOL IsIntModEnabled(SK_AC *pAC); | ||
88 | static void SetCurrIntCtr(SK_AC *pAC); | ||
89 | static void EnableIntMod(SK_AC *pAC); | ||
90 | static void DisableIntMod(SK_AC *pAC); | ||
91 | static void ResizeDimTimerDuration(SK_AC *pAC); | ||
92 | static void DisplaySelectedModerationType(SK_AC *pAC); | ||
93 | static void DisplaySelectedModerationMask(SK_AC *pAC); | ||
94 | static 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 | |||
124 | void | ||
125 | SkDimModerate(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 | |||
214 | void | ||
215 | SkDimStartModerationTimer(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 | |||
236 | void | ||
237 | SkDimEnableModerationIfNeeded(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 | |||
262 | void | ||
263 | SkDimDisplayModerationSettings(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 | |||
287 | static unsigned int | ||
288 | GetCurrentSystemLoad(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 | |||
373 | static SK_U64 | ||
374 | GetIsrCalls(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 | |||
422 | static SK_U64 | ||
423 | GetRxCalls(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 | |||
448 | static void | ||
449 | SetCurrIntCtr(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 | |||
470 | static SK_BOOL | ||
471 | IsIntModEnabled(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 | |||
492 | static void | ||
493 | EnableIntMod(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 | |||
521 | static void | ||
522 | DisableIntMod(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 | |||
542 | static void | ||
543 | ResizeDimTimerDuration(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 | |||
652 | static void | ||
653 | DisplaySelectedModerationType(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 | |||
681 | static void | ||
682 | DisplaySelectedModerationMask(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 | |||
727 | static void | ||
728 | DisplayDescrRatio(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 | */ | ||
87 | static 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 | */ | ||
170 | static 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 | */ | ||
187 | static 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 | */ | ||
248 | static 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 | */ | ||
266 | static 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 | |||
283 | static int getStatsCount(struct net_device *dev) | ||
284 | { | ||
285 | return ARRAY_SIZE(StringsStats); | ||
286 | } | ||
287 | |||
288 | static 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 | |||
297 | static 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 | */ | ||
345 | static 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 | */ | ||
402 | void 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 | */ | ||
428 | static 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 | */ | ||
457 | static 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 | */ | ||
481 | static 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 | |||
542 | struct 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 | |||
192 | static void FreeResources(struct SK_NET_DEVICE *dev); | ||
193 | static int SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC); | ||
194 | static SK_BOOL BoardAllocMem(SK_AC *pAC); | ||
195 | static void BoardFreeMem(SK_AC *pAC); | ||
196 | static void BoardInitMem(SK_AC *pAC); | ||
197 | static void SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**, int*, SK_BOOL); | ||
198 | static SkIsrRetVar SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs); | ||
199 | static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs); | ||
200 | static int SkGeOpen(struct SK_NET_DEVICE *dev); | ||
201 | static int SkGeClose(struct SK_NET_DEVICE *dev); | ||
202 | static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev); | ||
203 | static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p); | ||
204 | static void SkGeSetRxMode(struct SK_NET_DEVICE *dev); | ||
205 | static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev); | ||
206 | static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd); | ||
207 | static void GetConfiguration(SK_AC*); | ||
208 | static void ProductStr(SK_AC*); | ||
209 | static int XmitFrame(SK_AC*, TX_PORT*, struct sk_buff*); | ||
210 | static void FreeTxDescriptors(SK_AC*pAC, TX_PORT*); | ||
211 | static void FillRxRing(SK_AC*, RX_PORT*); | ||
212 | static SK_BOOL FillRxDescriptor(SK_AC*, RX_PORT*); | ||
213 | static void ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL); | ||
214 | static void ClearAndStartRx(SK_AC*, int); | ||
215 | static void ClearTxIrq(SK_AC*, int, int); | ||
216 | static void ClearRxRing(SK_AC*, RX_PORT*); | ||
217 | static void ClearTxRing(SK_AC*, TX_PORT*); | ||
218 | static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int new_mtu); | ||
219 | static void PortReInitBmu(SK_AC*, int); | ||
220 | static int SkGeIocMib(DEV_NET*, unsigned int, int); | ||
221 | static int SkGeInitPCI(SK_AC *pAC); | ||
222 | static void StartDrvCleanupTimer(SK_AC *pAC); | ||
223 | static void StopDrvCleanupTimer(SK_AC *pAC); | ||
224 | static int XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*); | ||
225 | |||
226 | #ifdef SK_DIAG_SUPPORT | ||
227 | static SK_U32 ParseDeviceNbrFromSlotName(const char *SlotName); | ||
228 | static int SkDrvInitAdapter(SK_AC *pAC, int devNbr); | ||
229 | static int SkDrvDeInitAdapter(SK_AC *pAC, int devNbr); | ||
230 | #endif | ||
231 | |||
232 | /******************************************************************************* | ||
233 | * | ||
234 | * Extern Function Prototypes | ||
235 | * | ||
236 | ******************************************************************************/ | ||
237 | static const char SKRootName[] = "sk98lin"; | ||
238 | static struct proc_dir_entry *pSkRootDir; | ||
239 | extern struct file_operations sk_proc_fops; | ||
240 | |||
241 | static 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 | |||
253 | static inline void SkGeProcRemove(struct net_device *dev) | ||
254 | { | ||
255 | if (pSkRootDir) | ||
256 | remove_proc_entry(dev->name, pSkRootDir); | ||
257 | } | ||
258 | |||
259 | extern void SkDimEnableModerationIfNeeded(SK_AC *pAC); | ||
260 | extern void SkDimDisplayModerationSettings(SK_AC *pAC); | ||
261 | extern void SkDimStartModerationTimer(SK_AC *pAC); | ||
262 | extern void SkDimModerate(SK_AC *pAC); | ||
263 | extern void SkGeBlinkTimer(unsigned long data); | ||
264 | |||
265 | #ifdef DEBUG | ||
266 | static void DumpMsg(struct sk_buff*, char*); | ||
267 | static void DumpData(char*, int); | ||
268 | static void DumpLong(char*, int); | ||
269 | #endif | ||
270 | |||
271 | /* global variables *********************************************************/ | ||
272 | static SK_BOOL DoPrintInterfaceChange = SK_TRUE; | ||
273 | extern struct ethtool_ops SkGeEthtoolOps; | ||
274 | |||
275 | /* local variables **********************************************************/ | ||
276 | static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}}; | ||
277 | static 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 | */ | ||
289 | int 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 | */ | ||
351 | static void FreeResources(struct SK_NET_DEVICE *dev) | ||
352 | { | ||
353 | SK_U32 AllocFlag; | ||
354 | DEV_NET *pNet; | ||
355 | SK_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 | |||
375 | MODULE_AUTHOR("Mirko Lindner <mlindner@syskonnect.de>"); | ||
376 | MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver"); | ||
377 | MODULE_LICENSE("GPL"); | ||
378 | |||
379 | #ifdef LINK_SPEED_A | ||
380 | static char *Speed_A[SK_MAX_CARD_PARAM] = LINK_SPEED; | ||
381 | #else | ||
382 | static char *Speed_A[SK_MAX_CARD_PARAM] = {"", }; | ||
383 | #endif | ||
384 | |||
385 | #ifdef LINK_SPEED_B | ||
386 | static char *Speed_B[SK_MAX_CARD_PARAM] = LINK_SPEED; | ||
387 | #else | ||
388 | static char *Speed_B[SK_MAX_CARD_PARAM] = {"", }; | ||
389 | #endif | ||
390 | |||
391 | #ifdef AUTO_NEG_A | ||
392 | static char *AutoNeg_A[SK_MAX_CARD_PARAM] = AUTO_NEG_A; | ||
393 | #else | ||
394 | static char *AutoNeg_A[SK_MAX_CARD_PARAM] = {"", }; | ||
395 | #endif | ||
396 | |||
397 | #ifdef DUP_CAP_A | ||
398 | static char *DupCap_A[SK_MAX_CARD_PARAM] = DUP_CAP_A; | ||
399 | #else | ||
400 | static char *DupCap_A[SK_MAX_CARD_PARAM] = {"", }; | ||
401 | #endif | ||
402 | |||
403 | #ifdef FLOW_CTRL_A | ||
404 | static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = FLOW_CTRL_A; | ||
405 | #else | ||
406 | static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = {"", }; | ||
407 | #endif | ||
408 | |||
409 | #ifdef ROLE_A | ||
410 | static char *Role_A[SK_MAX_CARD_PARAM] = ROLE_A; | ||
411 | #else | ||
412 | static char *Role_A[SK_MAX_CARD_PARAM] = {"", }; | ||
413 | #endif | ||
414 | |||
415 | #ifdef AUTO_NEG_B | ||
416 | static char *AutoNeg_B[SK_MAX_CARD_PARAM] = AUTO_NEG_B; | ||
417 | #else | ||
418 | static char *AutoNeg_B[SK_MAX_CARD_PARAM] = {"", }; | ||
419 | #endif | ||
420 | |||
421 | #ifdef DUP_CAP_B | ||
422 | static char *DupCap_B[SK_MAX_CARD_PARAM] = DUP_CAP_B; | ||
423 | #else | ||
424 | static char *DupCap_B[SK_MAX_CARD_PARAM] = {"", }; | ||
425 | #endif | ||
426 | |||
427 | #ifdef FLOW_CTRL_B | ||
428 | static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = FLOW_CTRL_B; | ||
429 | #else | ||
430 | static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = {"", }; | ||
431 | #endif | ||
432 | |||
433 | #ifdef ROLE_B | ||
434 | static char *Role_B[SK_MAX_CARD_PARAM] = ROLE_B; | ||
435 | #else | ||
436 | static char *Role_B[SK_MAX_CARD_PARAM] = {"", }; | ||
437 | #endif | ||
438 | |||
439 | #ifdef CON_TYPE | ||
440 | static char *ConType[SK_MAX_CARD_PARAM] = CON_TYPE; | ||
441 | #else | ||
442 | static char *ConType[SK_MAX_CARD_PARAM] = {"", }; | ||
443 | #endif | ||
444 | |||
445 | #ifdef PREF_PORT | ||
446 | static char *PrefPort[SK_MAX_CARD_PARAM] = PREF_PORT; | ||
447 | #else | ||
448 | static char *PrefPort[SK_MAX_CARD_PARAM] = {"", }; | ||
449 | #endif | ||
450 | |||
451 | #ifdef RLMT_MODE | ||
452 | static char *RlmtMode[SK_MAX_CARD_PARAM] = RLMT_MODE; | ||
453 | #else | ||
454 | static char *RlmtMode[SK_MAX_CARD_PARAM] = {"", }; | ||
455 | #endif | ||
456 | |||
457 | static int IntsPerSec[SK_MAX_CARD_PARAM]; | ||
458 | static char *Moderation[SK_MAX_CARD_PARAM]; | ||
459 | static char *ModerationMask[SK_MAX_CARD_PARAM]; | ||
460 | static char *AutoSizing[SK_MAX_CARD_PARAM]; | ||
461 | static char *Stats[SK_MAX_CARD_PARAM]; | ||
462 | |||
463 | module_param_array(Speed_A, charp, NULL, 0); | ||
464 | module_param_array(Speed_B, charp, NULL, 0); | ||
465 | module_param_array(AutoNeg_A, charp, NULL, 0); | ||
466 | module_param_array(AutoNeg_B, charp, NULL, 0); | ||
467 | module_param_array(DupCap_A, charp, NULL, 0); | ||
468 | module_param_array(DupCap_B, charp, NULL, 0); | ||
469 | module_param_array(FlowCtrl_A, charp, NULL, 0); | ||
470 | module_param_array(FlowCtrl_B, charp, NULL, 0); | ||
471 | module_param_array(Role_A, charp, NULL, 0); | ||
472 | module_param_array(Role_B, charp, NULL, 0); | ||
473 | module_param_array(ConType, charp, NULL, 0); | ||
474 | module_param_array(PrefPort, charp, NULL, 0); | ||
475 | module_param_array(RlmtMode, charp, NULL, 0); | ||
476 | /* used for interrupt moderation */ | ||
477 | module_param_array(IntsPerSec, int, NULL, 0); | ||
478 | module_param_array(Moderation, charp, NULL, 0); | ||
479 | module_param_array(Stats, charp, NULL, 0); | ||
480 | module_param_array(ModerationMask, charp, NULL, 0); | ||
481 | module_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 | */ | ||
496 | static int __init SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC) | ||
497 | { | ||
498 | short i; | ||
499 | unsigned long Flags; | ||
500 | char *DescrString = "sk98lin: Driver for Linux"; /* this is given to PNMI */ | ||
501 | char *VerStr = VER_STRING; | ||
502 | int Ret; /* return code of request_irq */ | ||
503 | SK_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 | */ | ||
642 | static SK_BOOL BoardAllocMem( | ||
643 | SK_AC *pAC) | ||
644 | { | ||
645 | caddr_t pDescrMem; /* pointer to descriptor memory area */ | ||
646 | size_t AllocLength; /* length of complete descriptor area */ | ||
647 | int i; /* loop counter */ | ||
648 | unsigned 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 | */ | ||
706 | static void BoardFreeMem( | ||
707 | SK_AC *pAC) | ||
708 | { | ||
709 | size_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 | */ | ||
736 | static void BoardInitMem( | ||
737 | SK_AC *pAC) /* pointer to adapter context */ | ||
738 | { | ||
739 | int i; /* loop counter */ | ||
740 | int RxDescrSize; /* the size of a rx descriptor rounded up to alignment*/ | ||
741 | int 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 | */ | ||
785 | static void SetupRing( | ||
786 | SK_AC *pAC, | ||
787 | void *pMemArea, /* a pointer to the memory area for the ring */ | ||
788 | uintptr_t VMemArea, /* the virtual bus address of the memory area */ | ||
789 | RXD **ppRingHead, /* address where the head should be written */ | ||
790 | RXD **ppRingTail, /* address where the tail should be written */ | ||
791 | RXD **ppRingPrev, /* address where the tail should be written */ | ||
792 | int *pRingFree, /* address where the # of free descr. goes */ | ||
793 | SK_BOOL IsTx) /* flag: is this a tx ring */ | ||
794 | { | ||
795 | int i; /* loop counter */ | ||
796 | int DescrSize; /* the size of a descriptor rounded up to alignment*/ | ||
797 | int DescrNum; /* number of descriptors per ring */ | ||
798 | RXD *pDescr; /* pointer to a descriptor (receive or transmit) */ | ||
799 | RXD *pNextDescr; /* pointer to the next descriptor */ | ||
800 | RXD *pPrevDescr; /* pointer to the previous descriptor */ | ||
801 | uintptr_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 | */ | ||
855 | static void PortReInitBmu( | ||
856 | SK_AC *pAC, /* pointer to adapter context */ | ||
857 | int 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 | */ | ||
897 | static SkIsrRetVar SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs) | ||
898 | { | ||
899 | struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id; | ||
900 | DEV_NET *pNet; | ||
901 | SK_AC *pAC; | ||
902 | SK_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 | */ | ||
1046 | static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs) | ||
1047 | { | ||
1048 | struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id; | ||
1049 | DEV_NET *pNet; | ||
1050 | SK_AC *pAC; | ||
1051 | SK_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 | */ | ||
1154 | static 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 | */ | ||
1178 | static int SkGeOpen( | ||
1179 | struct 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 | */ | ||
1293 | static int SkGeClose( | ||
1294 | struct 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 | */ | ||
1423 | static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev) | ||
1424 | { | ||
1425 | DEV_NET *pNet; | ||
1426 | SK_AC *pAC; | ||
1427 | int 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 | */ | ||
1498 | static int XmitFrame( | ||
1499 | SK_AC *pAC, /* pointer to adapter context */ | ||
1500 | TX_PORT *pTxPort, /* pointer to struct of port to send to */ | ||
1501 | struct 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 | */ | ||
1649 | static int XmitFrameSG( | ||
1650 | SK_AC *pAC, /* pointer to adapter context */ | ||
1651 | TX_PORT *pTxPort, /* pointer to struct of port to send to */ | ||
1652 | struct 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 | */ | ||
1832 | static void FreeTxDescriptors( | ||
1833 | SK_AC *pAC, /* pointer to the adapter context */ | ||
1834 | TX_PORT *pTxPort) /* pointer to destination port structure */ | ||
1835 | { | ||
1836 | TXD *pTxd; /* pointer to the checked descriptor */ | ||
1837 | TXD *pNewTail; /* pointer to 'end' of the ring */ | ||
1838 | SK_U32 Control; /* TBControl field of descriptor */ | ||
1839 | SK_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 | */ | ||
1904 | static void FillRxRing( | ||
1905 | SK_AC *pAC, /* pointer to the adapter context */ | ||
1906 | RX_PORT *pRxPort) /* ptr to port struct for which the ring | ||
1907 | should be filled */ | ||
1908 | { | ||
1909 | unsigned 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 | */ | ||
1932 | static SK_BOOL FillRxDescriptor( | ||
1933 | SK_AC *pAC, /* pointer to the adapter context struct */ | ||
1934 | RX_PORT *pRxPort) /* ptr to port struct of ring to fill */ | ||
1935 | { | ||
1936 | struct sk_buff *pMsgBlock; /* pointer to a new message block */ | ||
1937 | RXD *pRxd; /* the rxd to fill */ | ||
1938 | SK_U16 Length; /* data fragment length */ | ||
1939 | SK_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 | */ | ||
1987 | static void ReQueueRxBuffer( | ||
1988 | SK_AC *pAC, /* pointer to the adapter context struct */ | ||
1989 | RX_PORT *pRxPort, /* ptr to port struct of ring to fill */ | ||
1990 | struct sk_buff *pMsg, /* pointer to the buffer */ | ||
1991 | SK_U32 PhysHigh, /* phys address high dword */ | ||
1992 | SK_U32 PhysLow) /* phys address low dword */ | ||
1993 | { | ||
1994 | RXD *pRxd; /* the rxd to fill */ | ||
1995 | SK_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 | */ | ||
2024 | static 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 | { | ||
2029 | RXD *pRxd; /* pointer to receive descriptors */ | ||
2030 | SK_U32 Control; /* control field of descriptor */ | ||
2031 | struct sk_buff *pMsg; /* pointer to message holding frame */ | ||
2032 | struct sk_buff *pNewMsg; /* pointer to a new message for copying frame */ | ||
2033 | int FrameLength; /* total length of received frame */ | ||
2034 | int IpFrameLength; | ||
2035 | SK_MBUF *pRlmtMbuf; /* ptr to a buffer for giving a frame to rlmt */ | ||
2036 | SK_EVPARA EvPara; /* an event parameter union */ | ||
2037 | unsigned long Flags; /* for spin lock */ | ||
2038 | int PortIndex = pRxPort->PortIndex; | ||
2039 | unsigned int Offset; | ||
2040 | unsigned int NumBytes; | ||
2041 | unsigned int ForRlmt; | ||
2042 | SK_BOOL IsBc; | ||
2043 | SK_BOOL IsMc; | ||
2044 | SK_BOOL IsBadFrame; /* Bad frame */ | ||
2045 | |||
2046 | SK_U32 FrameStat; | ||
2047 | unsigned short Csum1; | ||
2048 | unsigned short Csum2; | ||
2049 | unsigned short Type; | ||
2050 | int Result; | ||
2051 | SK_U64 PhysAddr; | ||
2052 | |||
2053 | rx_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 | |||
2373 | rx_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 | */ | ||
2406 | static void ClearAndStartRx( | ||
2407 | SK_AC *pAC, /* pointer to the adapter context */ | ||
2408 | int 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 | */ | ||
2426 | static void ClearTxIrq( | ||
2427 | SK_AC *pAC, /* pointer to the adapter context */ | ||
2428 | int PortIndex, /* index of the transmit port (XMAC) */ | ||
2429 | int 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 | */ | ||
2447 | static void ClearRxRing( | ||
2448 | SK_AC *pAC, /* pointer to adapter context */ | ||
2449 | RX_PORT *pRxPort) /* pointer to rx port struct */ | ||
2450 | { | ||
2451 | RXD *pRxd; /* pointer to the current descriptor */ | ||
2452 | unsigned long Flags; | ||
2453 | SK_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 | */ | ||
2493 | static void ClearTxRing( | ||
2494 | SK_AC *pAC, /* pointer to adapter context */ | ||
2495 | TX_PORT *pTxPort) /* pointer to tx prt struct */ | ||
2496 | { | ||
2497 | TXD *pTxd; /* pointer to the current descriptor */ | ||
2498 | int i; | ||
2499 | unsigned 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 | */ | ||
2522 | static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p) | ||
2523 | { | ||
2524 | |||
2525 | DEV_NET *pNet = netdev_priv(dev); | ||
2526 | SK_AC *pAC = pNet->pAC; | ||
2527 | |||
2528 | struct sockaddr *addr = p; | ||
2529 | unsigned 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 | */ | ||
2568 | static void SkGeSetRxMode(struct SK_NET_DEVICE *dev) | ||
2569 | { | ||
2570 | |||
2571 | DEV_NET *pNet; | ||
2572 | SK_AC *pAC; | ||
2573 | |||
2574 | struct dev_mc_list *pMcList; | ||
2575 | int i; | ||
2576 | int PortIdx; | ||
2577 | unsigned 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 | */ | ||
2642 | static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int NewMtu) | ||
2643 | { | ||
2644 | DEV_NET *pNet; | ||
2645 | DEV_NET *pOtherNet; | ||
2646 | SK_AC *pAC; | ||
2647 | unsigned long Flags; | ||
2648 | int i; | ||
2649 | SK_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 | */ | ||
2880 | static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev) | ||
2881 | { | ||
2882 | DEV_NET *pNet = netdev_priv(dev); | ||
2883 | SK_AC *pAC = pNet->pAC; | ||
2884 | SK_PNMI_STRUCT_DATA *pPnmiStruct; /* structure for all Pnmi-Data */ | ||
2885 | SK_PNMI_STAT *pPnmiStat; /* pointer to virtual XMAC stat. data */ | ||
2886 | SK_PNMI_CONF *pPnmiConf; /* pointer to virtual link config. */ | ||
2887 | unsigned int Size; /* size of pnmi struct */ | ||
2888 | unsigned 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 | */ | ||
2964 | static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd) | ||
2965 | { | ||
2966 | DEV_NET *pNet; | ||
2967 | SK_AC *pAC; | ||
2968 | void *pMemBuf; | ||
2969 | struct pci_dev *pdev = NULL; | ||
2970 | SK_GE_IOCTL Ioctl; | ||
2971 | unsigned int Err = 0; | ||
2972 | int Size = 0; | ||
2973 | int Ret = 0; | ||
2974 | unsigned int Length = 0; | ||
2975 | int 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 | } | ||
3033 | fault_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 | } | ||
3071 | fault_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 | */ | ||
3101 | static int SkGeIocMib( | ||
3102 | DEV_NET *pNet, /* pointer to the adapter context */ | ||
3103 | unsigned int Size, /* length of ioctl data */ | ||
3104 | int mode) /* flag for set/preset */ | ||
3105 | { | ||
3106 | unsigned long Flags; /* for spin lock */ | ||
3107 | SK_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 | */ | ||
3148 | static void GetConfiguration( | ||
3149 | SK_AC *pAC) /* pointer to the adapter context structure */ | ||
3150 | { | ||
3151 | SK_I32 Port; /* preferred port */ | ||
3152 | SK_BOOL AutoSet; | ||
3153 | SK_BOOL DupSet; | ||
3154 | int LinkSpeed = SK_LSPEED_AUTO; /* Link speed */ | ||
3155 | int AutoNeg = 1; /* autoneg off (0) or on (1) */ | ||
3156 | int DuplexCap = 0; /* 0=both,1=full,2=half */ | ||
3157 | int FlowCtrl = SK_FLOW_MODE_SYM_OR_REM; /* FlowControl */ | ||
3158 | int MSMode = SK_MS_MODE_AUTO; /* master/slave mode */ | ||
3159 | |||
3160 | SK_BOOL IsConTypeDefined = SK_TRUE; | ||
3161 | SK_BOOL IsLinkSpeedDefined = SK_TRUE; | ||
3162 | SK_BOOL IsFlowCtrlDefined = SK_TRUE; | ||
3163 | SK_BOOL IsRoleDefined = SK_TRUE; | ||
3164 | SK_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 | */ | ||
3177 | int 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 | */ | ||
3866 | static void ProductStr( | ||
3867 | SK_AC *pAC /* pointer to adapter context */ | ||
3868 | ) | ||
3869 | { | ||
3870 | int StrLen = 80; /* length of the string, defined in SK_AC */ | ||
3871 | char Keyword[] = VPD_NAME; /* vpd productname identifier */ | ||
3872 | int ReturnCode; /* return code from vpd_read */ | ||
3873 | unsigned 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 | */ | ||
3899 | static void | ||
3900 | StartDrvCleanupTimer(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 | */ | ||
3920 | static void | ||
3921 | StopDrvCleanupTimer(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 | */ | ||
3945 | SK_MBUF *SkDrvAllocRlmtMbuf( | ||
3946 | SK_AC *pAC, /* pointer to adapter context */ | ||
3947 | SK_IOC IoC, /* the IO-context */ | ||
3948 | unsigned BufferSize) /* size of the requested buffer */ | ||
3949 | { | ||
3950 | SK_MBUF *pRlmtMbuf; /* pointer to a new rlmt-mbuf structure */ | ||
3951 | struct 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 | */ | ||
3982 | void SkDrvFreeRlmtMbuf( | ||
3983 | SK_AC *pAC, /* pointer to adapter context */ | ||
3984 | SK_IOC IoC, /* the IO-context */ | ||
3985 | SK_MBUF *pMbuf) /* size of the requested buffer */ | ||
3986 | { | ||
3987 | SK_MBUF *pFreeMbuf; | ||
3988 | SK_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 | */ | ||
4011 | SK_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 | */ | ||
4031 | int SkPciReadCfgDWord( | ||
4032 | SK_AC *pAC, /* Adapter Control structure pointer */ | ||
4033 | int PciAddr, /* PCI register address */ | ||
4034 | SK_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 | */ | ||
4053 | int SkPciReadCfgWord( | ||
4054 | SK_AC *pAC, /* Adapter Control structure pointer */ | ||
4055 | int PciAddr, /* PCI register address */ | ||
4056 | SK_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 | */ | ||
4075 | int SkPciReadCfgByte( | ||
4076 | SK_AC *pAC, /* Adapter Control structure pointer */ | ||
4077 | int PciAddr, /* PCI register address */ | ||
4078 | SK_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 | */ | ||
4097 | int SkPciWriteCfgDWord( | ||
4098 | SK_AC *pAC, /* Adapter Control structure pointer */ | ||
4099 | int PciAddr, /* PCI register address */ | ||
4100 | SK_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 | */ | ||
4120 | int SkPciWriteCfgWord( | ||
4121 | SK_AC *pAC, /* Adapter Control structure pointer */ | ||
4122 | int PciAddr, /* PCI register address */ | ||
4123 | SK_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 | */ | ||
4143 | int SkPciWriteCfgByte( | ||
4144 | SK_AC *pAC, /* Adapter Control structure pointer */ | ||
4145 | int PciAddr, /* PCI register address */ | ||
4146 | SK_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 | */ | ||
4168 | int SkDrvEvent( | ||
4169 | SK_AC *pAC, /* pointer to adapter context */ | ||
4170 | SK_IOC IoC, /* io-context */ | ||
4171 | SK_U32 Event, /* event-id */ | ||
4172 | SK_EVPARA Param) /* event-parameter */ | ||
4173 | { | ||
4174 | SK_MBUF *pRlmtMbuf; /* pointer to a rlmt-mbuf structure */ | ||
4175 | struct sk_buff *pMsg; /* pointer to a message block */ | ||
4176 | int FromPort; /* the port from which we switch away */ | ||
4177 | int ToPort; /* the port we switch to */ | ||
4178 | SK_EVPARA NewPara; /* parameter for further events */ | ||
4179 | int Stat; | ||
4180 | unsigned long Flags; | ||
4181 | SK_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 | */ | ||
4513 | void SkErrorLog( | ||
4514 | SK_AC *pAC, | ||
4515 | int ErrClass, | ||
4516 | int ErrNum, | ||
4517 | char *pErrorMsg) | ||
4518 | { | ||
4519 | char 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 | */ | ||
4563 | int SkDrvEnterDiagMode( | ||
4564 | SK_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 | */ | ||
4609 | int SkDrvLeaveDiagMode( | ||
4610 | SK_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 | |||
4644 | static SK_U32 ParseDeviceNbrFromSlotName( | ||
4645 | const 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 | */ | ||
4697 | static int SkDrvDeInitAdapter( | ||
4698 | SK_AC *pAC, /* pointer to adapter context */ | ||
4699 | int 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 | */ | ||
4728 | static int SkDrvInitAdapter( | ||
4729 | SK_AC *pAC, /* pointer to adapter context */ | ||
4730 | int 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 | */ | ||
4768 | static 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 | */ | ||
4806 | static void DumpData(char *p, int size) | ||
4807 | { | ||
4808 | register int i; | ||
4809 | int haddr, addr; | ||
4810 | char hex_buffer[180]; | ||
4811 | char asc_buffer[180]; | ||
4812 | char 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 | */ | ||
4854 | static void DumpLong(char *pc, int size) | ||
4855 | { | ||
4856 | register int i; | ||
4857 | int haddr, addr; | ||
4858 | char hex_buffer[180]; | ||
4859 | char asc_buffer[180]; | ||
4860 | char HEXCHAR[] = "0123456789ABCDEF"; | ||
4861 | long *p; | ||
4862 | int 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 | |||
4902 | static 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 | |||
5089 | static 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 | |||
5137 | static 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 | |||
5155 | MODULE_DEVICE_TABLE(pci, skge_pci_tbl); | ||
5156 | |||
5157 | static 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 | |||
5164 | static 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 | |||
5178 | static void __exit skge_exit(void) | ||
5179 | { | ||
5180 | pci_unregister_driver(&skge_driver); | ||
5181 | proc_net_remove(SKRootName); | ||
5182 | |||
5183 | } | ||
5184 | |||
5185 | module_init(skge_init); | ||
5186 | module_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)))) | ||
29 | static 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 | */ | ||
40 | intro() | ||
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 | */ | ||
57 | void SkHwtInit( | ||
58 | SK_AC *pAC, /* Adapters context */ | ||
59 | SK_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 | */ | ||
73 | void SkHwtStart( | ||
74 | SK_AC *pAC, /* Adapters context */ | ||
75 | SK_IOC Ioc, /* IoContext */ | ||
76 | SK_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 | */ | ||
107 | void SkHwtStop( | ||
108 | SK_AC *pAC, /* Adapters context */ | ||
109 | SK_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 | */ | ||
126 | SK_U32 SkHwtRead( | ||
127 | SK_AC *pAC, /* Adapters context */ | ||
128 | SK_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 | */ | ||
160 | void SkHwtIsr( | ||
161 | SK_AC *pAC, /* Adapters context */ | ||
162 | SK_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)))) | ||
33 | static const char SysKonnectFileId[] = | ||
34 | "@(#) $Id: skgeinit.c,v 1.97 2003/10/02 16:45:31 rschmidt Exp $ (C) Marvell."; | ||
35 | #endif | ||
36 | |||
37 | struct 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 | }; | ||
42 | static struct s_QOffTab QOffTab[] = { | ||
43 | {Q_R1, Q_XS1, Q_XA1}, {Q_R2, Q_XS2, Q_XA2} | ||
44 | }; | ||
45 | |||
46 | struct s_Config { | ||
47 | char ScanString[8]; | ||
48 | SK_U32 Value; | ||
49 | }; | ||
50 | |||
51 | static 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 | */ | ||
73 | void SkGePollRxD( | ||
74 | SK_AC *pAC, /* adapter context */ | ||
75 | SK_IOC IoC, /* IO context */ | ||
76 | int Port, /* Port Index (MAC_1 + n) */ | ||
77 | SK_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 | */ | ||
101 | void SkGePollTxD( | ||
102 | SK_AC *pAC, /* adapter context */ | ||
103 | SK_IOC IoC, /* IO context */ | ||
104 | int Port, /* Port Index (MAC_1 + n) */ | ||
105 | SK_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 | */ | ||
137 | void SkGeYellowLED( | ||
138 | SK_AC *pAC, /* adapter context */ | ||
139 | SK_IOC IoC, /* IO context */ | ||
140 | int 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 | */ | ||
171 | void SkGeXmitLED( | ||
172 | SK_AC *pAC, /* adapter context */ | ||
173 | SK_IOC IoC, /* IO context */ | ||
174 | int Led, /* offset to the LED Init Value register */ | ||
175 | int 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 | */ | ||
229 | static int DoCalcAddr( | ||
230 | SK_AC *pAC, /* adapter context */ | ||
231 | SK_GEPORT SK_FAR *pPrt, /* port index */ | ||
232 | int QuSize, /* size of the queue to configure in kB */ | ||
233 | SK_U32 SK_FAR *StartVal, /* start value for address calculation */ | ||
234 | SK_U32 SK_FAR *QuStartAddr,/* start addr to calculate */ | ||
235 | SK_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 | |||
284 | int SkGeInitAssignRamToQueues( | ||
285 | SK_AC *pAC, /* Adapter context */ | ||
286 | int ActivePort, /* Active Port in RLMT mode */ | ||
287 | SK_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 | */ | ||
406 | static int SkGeCheckQSize( | ||
407 | SK_AC *pAC, /* adapter context */ | ||
408 | int 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 | */ | ||
504 | static void SkGeInitMacArb( | ||
505 | SK_AC *pAC, /* adapter context */ | ||
506 | SK_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 | */ | ||
544 | static void SkGeInitPktArb( | ||
545 | SK_AC *pAC, /* adapter context */ | ||
546 | SK_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 | */ | ||
584 | static void SkGeInitMacFifo( | ||
585 | SK_AC *pAC, /* adapter context */ | ||
586 | SK_IOC IoC, /* IO context */ | ||
587 | int 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 | */ | ||
676 | void SkGeLoadLnkSyncCnt( | ||
677 | SK_AC *pAC, /* adapter context */ | ||
678 | SK_IOC IoC, /* IO context */ | ||
679 | int Port, /* Port Index (MAC_1 + n) */ | ||
680 | SK_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 | */ | ||
760 | int SkGeCfgSync( | ||
761 | SK_AC *pAC, /* adapter context */ | ||
762 | SK_IOC IoC, /* IO context */ | ||
763 | int Port, /* Port Index (MAC_1 + n) */ | ||
764 | SK_U32 IntTime, /* Interval Timer Value in units of 8ns */ | ||
765 | SK_U32 LimCount, /* Number of bytes to transfer during IntTime */ | ||
766 | int 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 | */ | ||
834 | static void DoInitRamQueue( | ||
835 | SK_AC *pAC, /* adapter context */ | ||
836 | SK_IOC IoC, /* IO context */ | ||
837 | int QuIoOffs, /* Queue IO Address Offset */ | ||
838 | SK_U32 QuStartAddr, /* Queue Start Address */ | ||
839 | SK_U32 QuEndAddr, /* Queue End Address */ | ||
840 | int 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 | */ | ||
913 | static void SkGeInitRamBufs( | ||
914 | SK_AC *pAC, /* adapter context */ | ||
915 | SK_IOC IoC, /* IO context */ | ||
916 | int 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 | */ | ||
955 | void SkGeInitRamIface( | ||
956 | SK_AC *pAC, /* adapter context */ | ||
957 | SK_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 | */ | ||
989 | static void SkGeInitBmu( | ||
990 | SK_AC *pAC, /* adapter context */ | ||
991 | SK_IOC IoC, /* IO context */ | ||
992 | int 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 | */ | ||
1046 | static SK_U32 TestStopBit( | ||
1047 | SK_AC *pAC, /* Adapter Context */ | ||
1048 | SK_IOC IoC, /* IO Context */ | ||
1049 | int 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 | */ | ||
1144 | void SkGeStopPort( | ||
1145 | SK_AC *pAC, /* adapter context */ | ||
1146 | SK_IOC IoC, /* I/O context */ | ||
1147 | int Port, /* port to stop (MAC_1 + n) */ | ||
1148 | int Dir, /* Direction to Stop (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */ | ||
1149 | int 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 | */ | ||
1357 | static void SkGeInit0( | ||
1358 | SK_AC *pAC, /* adapter context */ | ||
1359 | SK_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 | */ | ||
1428 | static int SkGePciReset( | ||
1429 | SK_AC *pAC, /* adapter context */ | ||
1430 | SK_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 | */ | ||
1511 | static int SkGeInit1( | ||
1512 | SK_AC *pAC, /* adapter context */ | ||
1513 | SK_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 | */ | ||
1816 | static void SkGeInit2( | ||
1817 | SK_AC *pAC, /* adapter context */ | ||
1818 | SK_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 | */ | ||
1905 | int SkGeInit( | ||
1906 | SK_AC *pAC, /* adapter context */ | ||
1907 | SK_IOC IoC, /* IO context */ | ||
1908 | int 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 | */ | ||
1987 | void SkGeDeInit( | ||
1988 | SK_AC *pAC, /* adapter context */ | ||
1989 | SK_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 | */ | ||
2091 | int SkGeInitPort( | ||
2092 | SK_AC *pAC, /* adapter context */ | ||
2093 | SK_IOC IoC, /* IO context */ | ||
2094 | int 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 | */ | ||
28 | PNMI_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); | ||
31 | PNMI_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); | ||
34 | PNMI_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); | ||
37 | PNMI_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); | ||
40 | PNMI_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); | ||
43 | PNMI_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); | ||
46 | PNMI_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); | ||
49 | PNMI_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); | ||
52 | PNMI_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); | ||
55 | PNMI_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); | ||
58 | PNMI_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); | ||
61 | PNMI_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); | ||
64 | PNMI_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); | ||
67 | PNMI_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 | ||
72 | PNMI_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 | ||
78 | PNMI_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 | */ | ||
94 | PNMI_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 | ||
27 | static 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 | */ | ||
58 | int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level); | ||
59 | int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf, | ||
60 | unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); | ||
61 | int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf, | ||
62 | unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); | ||
63 | int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf, | ||
64 | unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); | ||
65 | int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, | ||
66 | unsigned int *pLen, SK_U32 NetIndex); | ||
67 | int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, | ||
68 | unsigned int *pLen, SK_U32 NetIndex); | ||
69 | int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, | ||
70 | unsigned int *pLen, SK_U32 NetIndex); | ||
71 | int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param); | ||
72 | int 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 | |||
80 | PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int | ||
81 | PhysPortIndex); | ||
82 | PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int | ||
83 | PhysPortIndex); | ||
84 | PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac); | ||
85 | PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf); | ||
86 | PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC, | ||
87 | unsigned int PhysPortIndex, unsigned int StatIndex); | ||
88 | PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex, | ||
89 | unsigned int StatIndex, SK_U32 NetIndex); | ||
90 | PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size); | ||
91 | PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen, | ||
92 | unsigned int *pEntries); | ||
93 | PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr, | ||
94 | unsigned int KeyArrLen, unsigned int *pKeyNo); | ||
95 | PNMI_STATIC int LookupId(SK_U32 Id); | ||
96 | PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac, | ||
97 | unsigned int LastMac); | ||
98 | PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf, | ||
99 | unsigned int *pLen, SK_U32 NetIndex); | ||
100 | PNMI_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); | ||
102 | PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac); | ||
103 | PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId, | ||
104 | unsigned int PortIndex); | ||
105 | PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId, | ||
106 | unsigned int SensorIndex); | ||
107 | PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId); | ||
108 | PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex); | ||
109 | PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex); | ||
110 | PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC); | ||
111 | PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf); | ||
112 | PNMI_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); | ||
114 | PNMI_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 | */ | ||
129 | PNMI_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 | */ | ||
199 | PNMI_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 | */ | ||
355 | int SkPnmiInit( | ||
356 | SK_AC *pAC, /* Pointer to adapter context */ | ||
357 | SK_IOC IoC, /* IO context handle */ | ||
358 | int 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 | */ | ||
590 | int SkPnmiGetVar( | ||
591 | SK_AC *pAC, /* Pointer to adapter context */ | ||
592 | SK_IOC IoC, /* IO context handle */ | ||
593 | SK_U32 Id, /* Object ID that is to be processed */ | ||
594 | void *pBuf, /* Buffer to which the management data will be copied */ | ||
595 | unsigned int *pLen, /* On call: buffer length. On return: used buffer */ | ||
596 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
597 | SK_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 | */ | ||
632 | int SkPnmiPreSetVar( | ||
633 | SK_AC *pAC, /* Pointer to adapter context */ | ||
634 | SK_IOC IoC, /* IO context handle */ | ||
635 | SK_U32 Id, /* Object ID that is to be processed */ | ||
636 | void *pBuf, /* Buffer to which the management data will be copied */ | ||
637 | unsigned int *pLen, /* Total length of management data */ | ||
638 | SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */ | ||
639 | SK_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 | */ | ||
675 | int SkPnmiSetVar( | ||
676 | SK_AC *pAC, /* Pointer to adapter context */ | ||
677 | SK_IOC IoC, /* IO context handle */ | ||
678 | SK_U32 Id, /* Object ID that is to be processed */ | ||
679 | void *pBuf, /* Buffer to which the management data will be copied */ | ||
680 | unsigned int *pLen, /* Total length of management data */ | ||
681 | SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */ | ||
682 | SK_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 | */ | ||
711 | int SkPnmiGetStruct( | ||
712 | SK_AC *pAC, /* Pointer to adapter context */ | ||
713 | SK_IOC IoC, /* IO context handle */ | ||
714 | void *pBuf, /* Buffer to which the management data will be copied. */ | ||
715 | unsigned int *pLen, /* Length of buffer */ | ||
716 | SK_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 | */ | ||
889 | int SkPnmiPreSetStruct( | ||
890 | SK_AC *pAC, /* Pointer to adapter context */ | ||
891 | SK_IOC IoC, /* IO context handle */ | ||
892 | void *pBuf, /* Buffer which contains the data to be set */ | ||
893 | unsigned int *pLen, /* Length of buffer */ | ||
894 | SK_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 | */ | ||
927 | int SkPnmiSetStruct( | ||
928 | SK_AC *pAC, /* Pointer to adapter context */ | ||
929 | SK_IOC IoC, /* IO context handle */ | ||
930 | void *pBuf, /* Buffer which contains the data to be set */ | ||
931 | unsigned int *pLen, /* Length of buffer */ | ||
932 | SK_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 | */ | ||
992 | int SkPnmiEvent( | ||
993 | SK_AC *pAC, /* Pointer to adapter context */ | ||
994 | SK_IOC IoC, /* IO context handle */ | ||
995 | SK_U32 Event, /* Event-Id */ | ||
996 | SK_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 | */ | ||
1700 | PNMI_STATIC int PnmiVar( | ||
1701 | SK_AC *pAC, /* Pointer to adapter context */ | ||
1702 | SK_IOC IoC, /* IO context handle */ | ||
1703 | int Action, /* GET/PRESET/SET action */ | ||
1704 | SK_U32 Id, /* Object ID that is to be processed */ | ||
1705 | char *pBuf, /* Buffer used for the management data transfer */ | ||
1706 | unsigned int *pLen, /* Total length of pBuf management data */ | ||
1707 | SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */ | ||
1708 | SK_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 | */ | ||
1753 | PNMI_STATIC int PnmiStruct( | ||
1754 | SK_AC *pAC, /* Pointer to adapter context */ | ||
1755 | SK_IOC IoC, /* IO context handle */ | ||
1756 | int Action, /* PRESET/SET action to be performed */ | ||
1757 | char *pBuf, /* Buffer used for the management data transfer */ | ||
1758 | unsigned int *pLen, /* Length of pBuf management data buffer */ | ||
1759 | SK_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 | */ | ||
1918 | PNMI_STATIC int LookupId( | ||
1919 | SK_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 | */ | ||
1955 | PNMI_STATIC int OidStruct( | ||
1956 | SK_AC *pAC, /* Pointer to adapter context */ | ||
1957 | SK_IOC IoC, /* IO context handle */ | ||
1958 | int Action, /* GET/PRESET/SET action */ | ||
1959 | SK_U32 Id, /* Object ID that is to be processed */ | ||
1960 | char *pBuf, /* Buffer used for the management data transfer */ | ||
1961 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
1962 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
1963 | unsigned int TableIndex, /* Index to the Id table */ | ||
1964 | SK_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 | */ | ||
2022 | PNMI_STATIC int Perform( | ||
2023 | SK_AC *pAC, /* Pointer to adapter context */ | ||
2024 | SK_IOC IoC, /* IO context handle */ | ||
2025 | int Action, /* GET/PRESET/SET action */ | ||
2026 | SK_U32 Id, /* Object ID that is to be processed */ | ||
2027 | char *pBuf, /* Buffer used for the management data transfer */ | ||
2028 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
2029 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
2030 | unsigned int TableIndex, /* Index to the Id table */ | ||
2031 | SK_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 | */ | ||
2153 | PNMI_STATIC int Mac8023Stat( | ||
2154 | SK_AC *pAC, /* Pointer to adapter context */ | ||
2155 | SK_IOC IoC, /* IO context handle */ | ||
2156 | int Action, /* GET/PRESET/SET action */ | ||
2157 | SK_U32 Id, /* Object ID that is to be processed */ | ||
2158 | char *pBuf, /* Buffer used for the management data transfer */ | ||
2159 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
2160 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
2161 | unsigned int TableIndex, /* Index to the Id table */ | ||
2162 | SK_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 | */ | ||
2289 | PNMI_STATIC int MacPrivateStat( | ||
2290 | SK_AC *pAC, /* Pointer to adapter context */ | ||
2291 | SK_IOC IoC, /* IO context handle */ | ||
2292 | int Action, /* GET/PRESET/SET action */ | ||
2293 | SK_U32 Id, /* Object ID that is to be processed */ | ||
2294 | char *pBuf, /* Buffer used for the management data transfer */ | ||
2295 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
2296 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
2297 | unsigned int TableIndex, /* Index to the Id table */ | ||
2298 | SK_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 | */ | ||
2451 | PNMI_STATIC int Addr( | ||
2452 | SK_AC *pAC, /* Pointer to adapter context */ | ||
2453 | SK_IOC IoC, /* IO context handle */ | ||
2454 | int Action, /* GET/PRESET/SET action */ | ||
2455 | SK_U32 Id, /* Object ID that is to be processed */ | ||
2456 | char *pBuf, /* Buffer used for the management data transfer */ | ||
2457 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
2458 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
2459 | unsigned int TableIndex, /* Index to the Id table */ | ||
2460 | SK_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 | */ | ||
2652 | PNMI_STATIC int CsumStat( | ||
2653 | SK_AC *pAC, /* Pointer to adapter context */ | ||
2654 | SK_IOC IoC, /* IO context handle */ | ||
2655 | int Action, /* GET/PRESET/SET action */ | ||
2656 | SK_U32 Id, /* Object ID that is to be processed */ | ||
2657 | char *pBuf, /* Buffer used for the management data transfer */ | ||
2658 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
2659 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
2660 | unsigned int TableIndex, /* Index to the Id table */ | ||
2661 | SK_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 | */ | ||
2768 | PNMI_STATIC int SensorStat( | ||
2769 | SK_AC *pAC, /* Pointer to adapter context */ | ||
2770 | SK_IOC IoC, /* IO context handle */ | ||
2771 | int Action, /* GET/PRESET/SET action */ | ||
2772 | SK_U32 Id, /* Object ID that is to be processed */ | ||
2773 | char *pBuf, /* Buffer used for the management data transfer */ | ||
2774 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
2775 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
2776 | unsigned int TableIndex, /* Index to the Id table */ | ||
2777 | SK_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 | */ | ||
3013 | PNMI_STATIC int Vpd( | ||
3014 | SK_AC *pAC, /* Pointer to adapter context */ | ||
3015 | SK_IOC IoC, /* IO context handle */ | ||
3016 | int Action, /* GET/PRESET/SET action */ | ||
3017 | SK_U32 Id, /* Object ID that is to be processed */ | ||
3018 | char *pBuf, /* Buffer used for the management data transfer */ | ||
3019 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
3020 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
3021 | unsigned int TableIndex, /* Index to the Id table */ | ||
3022 | SK_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 | */ | ||
3487 | PNMI_STATIC int General( | ||
3488 | SK_AC *pAC, /* Pointer to adapter context */ | ||
3489 | SK_IOC IoC, /* IO context handle */ | ||
3490 | int Action, /* GET/PRESET/SET action */ | ||
3491 | SK_U32 Id, /* Object ID that is to be processed */ | ||
3492 | char *pBuf, /* Buffer used for the management data transfer */ | ||
3493 | unsigned int *pLen, /* On call: buffer length. On return: used buffer */ | ||
3494 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
3495 | unsigned int TableIndex, /* Index to the Id table */ | ||
3496 | SK_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 | */ | ||
4485 | PNMI_STATIC int Rlmt( | ||
4486 | SK_AC *pAC, /* Pointer to adapter context */ | ||
4487 | SK_IOC IoC, /* IO context handle */ | ||
4488 | int Action, /* GET/PRESET/SET action */ | ||
4489 | SK_U32 Id, /* Object ID that is to be processed */ | ||
4490 | char *pBuf, /* Buffer used for the management data transfer */ | ||
4491 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
4492 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
4493 | unsigned int TableIndex, /* Index to the Id table */ | ||
4494 | SK_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 | */ | ||
4790 | PNMI_STATIC int RlmtStat( | ||
4791 | SK_AC *pAC, /* Pointer to adapter context */ | ||
4792 | SK_IOC IoC, /* IO context handle */ | ||
4793 | int Action, /* GET/PRESET/SET action */ | ||
4794 | SK_U32 Id, /* Object ID that is to be processed */ | ||
4795 | char *pBuf, /* Buffer used for the management data transfer */ | ||
4796 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
4797 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
4798 | unsigned int TableIndex, /* Index to the Id table */ | ||
4799 | SK_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 | */ | ||
4992 | PNMI_STATIC int MacPrivateConf( | ||
4993 | SK_AC *pAC, /* Pointer to adapter context */ | ||
4994 | SK_IOC IoC, /* IO context handle */ | ||
4995 | int Action, /* GET/PRESET/SET action */ | ||
4996 | SK_U32 Id, /* Object ID that is to be processed */ | ||
4997 | char *pBuf, /* Buffer used for the management data transfer */ | ||
4998 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
4999 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
5000 | unsigned int TableIndex, /* Index to the Id table */ | ||
5001 | SK_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 | */ | ||
5991 | PNMI_STATIC int Monitor( | ||
5992 | SK_AC *pAC, /* Pointer to adapter context */ | ||
5993 | SK_IOC IoC, /* IO context handle */ | ||
5994 | int Action, /* GET/PRESET/SET action */ | ||
5995 | SK_U32 Id, /* Object ID that is to be processed */ | ||
5996 | char *pBuf, /* Buffer used for the management data transfer */ | ||
5997 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
5998 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
5999 | unsigned int TableIndex, /* Index to the Id table */ | ||
6000 | SK_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 | */ | ||
6106 | PNMI_STATIC void VirtualConf( | ||
6107 | SK_AC *pAC, /* Pointer to adapter context */ | ||
6108 | SK_IOC IoC, /* IO context handle */ | ||
6109 | SK_U32 Id, /* Object ID that is to be processed */ | ||
6110 | char *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 | */ | ||
6444 | PNMI_STATIC SK_U8 CalculateLinkStatus( | ||
6445 | SK_AC *pAC, /* Pointer to adapter context */ | ||
6446 | SK_IOC IoC, /* IO context handle */ | ||
6447 | unsigned 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 | */ | ||
6483 | PNMI_STATIC SK_U8 CalculateLinkModeStatus( | ||
6484 | SK_AC *pAC, /* Pointer to adapter context */ | ||
6485 | SK_IOC IoC, /* IO context handle */ | ||
6486 | unsigned 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 | */ | ||
6530 | PNMI_STATIC int GetVpdKeyArr( | ||
6531 | SK_AC *pAC, /* Pointer to adapter context */ | ||
6532 | SK_IOC IoC, /* IO context handle */ | ||
6533 | char *pKeyArr, /* Ptr KeyArray */ | ||
6534 | unsigned int KeyArrLen, /* Length of array in bytes */ | ||
6535 | unsigned 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 | */ | ||
6626 | PNMI_STATIC int SirqUpdate( | ||
6627 | SK_AC *pAC, /* Pointer to adapter context */ | ||
6628 | SK_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 | */ | ||
6665 | PNMI_STATIC int RlmtUpdate( | ||
6666 | SK_AC *pAC, /* Pointer to adapter context */ | ||
6667 | SK_IOC IoC, /* IO context handle */ | ||
6668 | SK_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 | */ | ||
6707 | PNMI_STATIC int MacUpdate( | ||
6708 | SK_AC *pAC, /* Pointer to adapter context */ | ||
6709 | SK_IOC IoC, /* IO context handle */ | ||
6710 | unsigned int FirstMac, /* Index of the first Mac to be updated */ | ||
6711 | unsigned 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 | */ | ||
6763 | PNMI_STATIC SK_U64 GetStatVal( | ||
6764 | SK_AC *pAC, /* Pointer to adapter context */ | ||
6765 | SK_IOC IoC, /* IO context handle */ | ||
6766 | unsigned int LogPortIndex, /* Index of the logical Port to be processed */ | ||
6767 | unsigned int StatIndex, /* Index to statistic value */ | ||
6768 | SK_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 | */ | ||
6826 | PNMI_STATIC SK_U64 GetPhysStatVal( | ||
6827 | SK_AC *pAC, /* Pointer to adapter context */ | ||
6828 | SK_IOC IoC, /* IO context handle */ | ||
6829 | unsigned int PhysPortIndex, /* Index of the logical Port to be processed */ | ||
6830 | unsigned 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 | */ | ||
7160 | PNMI_STATIC void ResetCounter( | ||
7161 | SK_AC *pAC, /* Pointer to adapter context */ | ||
7162 | SK_IOC IoC, /* IO context handle */ | ||
7163 | SK_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 | */ | ||
7256 | PNMI_STATIC char* GetTrapEntry( | ||
7257 | SK_AC *pAC, /* Pointer to adapter context */ | ||
7258 | SK_U32 TrapId, /* SNMP ID of the trap */ | ||
7259 | unsigned 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 | */ | ||
7361 | PNMI_STATIC void CopyTrapQueue( | ||
7362 | SK_AC *pAC, /* Pointer to adapter context */ | ||
7363 | char *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 | */ | ||
7404 | PNMI_STATIC void GetTrapQueueLen( | ||
7405 | SK_AC *pAC, /* Pointer to adapter context */ | ||
7406 | unsigned int *pLen, /* Length in Bytes of all queued traps */ | ||
7407 | unsigned 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 | */ | ||
7446 | PNMI_STATIC void QueueSimpleTrap( | ||
7447 | SK_AC *pAC, /* Pointer to adapter context */ | ||
7448 | SK_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 | */ | ||
7464 | PNMI_STATIC void QueueSensorTrap( | ||
7465 | SK_AC *pAC, /* Pointer to adapter context */ | ||
7466 | SK_U32 TrapId, /* Type of sensor trap */ | ||
7467 | unsigned 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 | */ | ||
7519 | PNMI_STATIC void QueueRlmtNewMacTrap( | ||
7520 | SK_AC *pAC, /* Pointer to adapter context */ | ||
7521 | unsigned 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 | */ | ||
7546 | PNMI_STATIC void QueueRlmtPortTrap( | ||
7547 | SK_AC *pAC, /* Pointer to adapter context */ | ||
7548 | SK_U32 TrapId, /* Type of RLMT port trap */ | ||
7549 | unsigned 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 | */ | ||
7573 | PNMI_STATIC void CopyMac( | ||
7574 | char *pDst, /* Pointer to destination buffer */ | ||
7575 | SK_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 | |||
7605 | PNMI_STATIC int PowerManagement( | ||
7606 | SK_AC *pAC, /* Pointer to adapter context */ | ||
7607 | SK_IOC IoC, /* IO context handle */ | ||
7608 | int Action, /* Get/PreSet/Set action */ | ||
7609 | SK_U32 Id, /* Object ID that is to be processed */ | ||
7610 | char *pBuf, /* Buffer to which to mgmt data will be retrieved */ | ||
7611 | unsigned int *pLen, /* On call: buffer length. On return: used buffer */ | ||
7612 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
7613 | unsigned int TableIndex, /* Index to the Id table */ | ||
7614 | SK_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 | |||
7768 | PNMI_STATIC int DiagActions( | ||
7769 | SK_AC *pAC, /* Pointer to adapter context */ | ||
7770 | SK_IOC IoC, /* IO context handle */ | ||
7771 | int Action, /* GET/PRESET/SET action */ | ||
7772 | SK_U32 Id, /* Object ID that is to be processed */ | ||
7773 | char *pBuf, /* Buffer used for the management data transfer */ | ||
7774 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
7775 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
7776 | unsigned int TableIndex, /* Index to the Id table */ | ||
7777 | SK_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 | |||
7967 | PNMI_STATIC int Vct( | ||
7968 | SK_AC *pAC, /* Pointer to adapter context */ | ||
7969 | SK_IOC IoC, /* IO context handle */ | ||
7970 | int Action, /* GET/PRESET/SET action */ | ||
7971 | SK_U32 Id, /* Object ID that is to be processed */ | ||
7972 | char *pBuf, /* Buffer used for the management data transfer */ | ||
7973 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
7974 | SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */ | ||
7975 | unsigned int TableIndex, /* Index to the Id table */ | ||
7976 | SK_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 | |||
8218 | PNMI_STATIC void CheckVctStatus( | ||
8219 | SK_AC *pAC, | ||
8220 | SK_IOC IoC, | ||
8221 | char *pBuf, | ||
8222 | SK_U32 Offset, | ||
8223 | SK_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 | */ | ||
8302 | int SkPnmiGenIoctl( | ||
8303 | SK_AC *pAC, /* Pointer to adapter context struct */ | ||
8304 | SK_IOC IoC, /* I/O context */ | ||
8305 | void *pBuf, /* Buffer used for the management data transfer */ | ||
8306 | unsigned int *pLen, /* Length of buffer */ | ||
8307 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
8308 | { | ||
8309 | SK_I32 Mode; /* Store value of subcommand. */ | ||
8310 | SK_U32 Oid; /* Store value of OID. */ | ||
8311 | int ReturnCode; /* Store return value to show status of PNMI action. */ | ||
8312 | int 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)))) | ||
50 | static 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 | ||
63 | static int SkGePortCheckUpXmac(SK_AC*, SK_IOC, int, SK_BOOL); | ||
64 | static int SkGePortCheckUpBcom(SK_AC*, SK_IOC, int, SK_BOOL); | ||
65 | static void SkPhyIsrBcom(SK_AC*, SK_IOC, int, SK_U16); | ||
66 | #endif /* GENESIS */ | ||
67 | #ifdef YUKON | ||
68 | static int SkGePortCheckUpGmac(SK_AC*, SK_IOC, int, SK_BOOL); | ||
69 | static void SkPhyIsrGmac(SK_AC*, SK_IOC, int, SK_U16); | ||
70 | #endif /* YUKON */ | ||
71 | #ifdef OTHER_PHY | ||
72 | static int SkGePortCheckUpLone(SK_AC*, SK_IOC, int, SK_BOOL); | ||
73 | static int SkGePortCheckUpNat(SK_AC*, SK_IOC, int, SK_BOOL); | ||
74 | static 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 | */ | ||
82 | static 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 | */ | ||
99 | intro() | ||
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 | */ | ||
111 | static void SkHWInitDefSense( | ||
112 | SK_AC *pAC, /* adapter context */ | ||
113 | SK_IOC IoC, /* IO context */ | ||
114 | int 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 | */ | ||
147 | static SK_U8 SkHWSenseGetNext( | ||
148 | SK_AC *pAC, /* adapter context */ | ||
149 | SK_IOC IoC, /* IO context */ | ||
150 | int 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 | */ | ||
181 | static void SkHWSenseSetNext( | ||
182 | SK_AC *pAC, /* adapter context */ | ||
183 | SK_IOC IoC, /* IO context */ | ||
184 | int Port, /* Port Index (MAC_1 + n) */ | ||
185 | SK_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 | */ | ||
216 | void SkHWLinkDown( | ||
217 | SK_AC *pAC, /* adapter context */ | ||
218 | SK_IOC IoC, /* IO context */ | ||
219 | int 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 | */ | ||
268 | void SkHWLinkUp( | ||
269 | SK_AC *pAC, /* adapter context */ | ||
270 | SK_IOC IoC, /* IO context */ | ||
271 | int 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 | */ | ||
331 | static void SkMacParity( | ||
332 | SK_AC *pAC, /* adapter context */ | ||
333 | SK_IOC IoC, /* IO context */ | ||
334 | int 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 | */ | ||
408 | static void SkGeHwErr( | ||
409 | SK_AC *pAC, /* adapter context */ | ||
410 | SK_IOC IoC, /* IO context */ | ||
411 | SK_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 | */ | ||
542 | void SkGeSirqIsr( | ||
543 | SK_AC *pAC, /* adapter context */ | ||
544 | SK_IOC IoC, /* IO context */ | ||
545 | SK_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 | */ | ||
881 | static int SkGePortCheckShorts( | ||
882 | SK_AC *pAC, /* Adapter Context */ | ||
883 | SK_IOC IoC, /* IO Context */ | ||
884 | int 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 | */ | ||
996 | static int SkGePortCheckUp( | ||
997 | SK_AC *pAC, /* Adapter Context */ | ||
998 | SK_IOC IoC, /* IO Context */ | ||
999 | int 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 | */ | ||
1060 | static int SkGePortCheckUpXmac( | ||
1061 | SK_AC *pAC, /* Adapter Context */ | ||
1062 | SK_IOC IoC, /* IO Context */ | ||
1063 | int Port, /* Which port should be checked */ | ||
1064 | SK_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 | */ | ||
1315 | static int SkGePortCheckUpBcom( | ||
1316 | SK_AC *pAC, /* Adapter Context */ | ||
1317 | SK_IOC IoC, /* IO Context */ | ||
1318 | int Port, /* Which port should be checked */ | ||
1319 | SK_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 | */ | ||
1616 | static int SkGePortCheckUpGmac( | ||
1617 | SK_AC *pAC, /* Adapter Context */ | ||
1618 | SK_IOC IoC, /* IO Context */ | ||
1619 | int Port, /* Which port should be checked */ | ||
1620 | SK_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 | */ | ||
1759 | static int SkGePortCheckUpLone( | ||
1760 | SK_AC *pAC, /* Adapter Context */ | ||
1761 | SK_IOC IoC, /* IO Context */ | ||
1762 | int Port, /* Which port should be checked */ | ||
1763 | SK_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 | */ | ||
1890 | static int SkGePortCheckUpNat( | ||
1891 | SK_AC *pAC, /* Adapter Context */ | ||
1892 | SK_IOC IoC, /* IO Context */ | ||
1893 | int Port, /* Which port should be checked */ | ||
1894 | SK_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 | */ | ||
1910 | int SkGeSirqEvent( | ||
1911 | SK_AC *pAC, /* Adapter Context */ | ||
1912 | SK_IOC IoC, /* Io Context */ | ||
1913 | SK_U32 Event, /* Module specific Event */ | ||
1914 | SK_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 | */ | ||
2132 | static void SkPhyIsrBcom( | ||
2133 | SK_AC *pAC, /* Adapter Context */ | ||
2134 | SK_IOC IoC, /* Io Context */ | ||
2135 | int Port, /* Port Num = PHY Num */ | ||
2136 | SK_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 | */ | ||
2175 | static void SkPhyIsrGmac( | ||
2176 | SK_AC *pAC, /* Adapter Context */ | ||
2177 | SK_IOC IoC, /* Io Context */ | ||
2178 | int Port, /* Port Num = PHY Num */ | ||
2179 | SK_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 | */ | ||
2231 | static void SkPhyIsrLone( | ||
2232 | SK_AC *pAC, /* Adapter Context */ | ||
2233 | SK_IOC IoC, /* Io Context */ | ||
2234 | int Port, /* Port Num = PHY Num */ | ||
2235 | SK_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)))) | ||
29 | static 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 | */ | ||
107 | intro() | ||
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 | */ | ||
163 | void SkI2cSndBit( | ||
164 | SK_IOC IoC, /* I/O Context */ | ||
165 | SK_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 | */ | ||
190 | void SkI2cStart( | ||
191 | SK_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 | |||
214 | void SkI2cStop( | ||
215 | SK_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 | */ | ||
252 | int SkI2cRcvBit( | ||
253 | SK_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 | */ | ||
284 | int SkI2cRcvAck( | ||
285 | SK_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 | */ | ||
297 | void SkI2cSndNAck( | ||
298 | SK_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 | */ | ||
310 | void SkI2cSndAck( | ||
311 | SK_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 | */ | ||
325 | int SkI2cSndByte( | ||
326 | SK_IOC IoC, /* I/O Context */ | ||
327 | int 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 | */ | ||
349 | int SkI2cRcvByte( | ||
350 | SK_IOC IoC, /* I/O Context */ | ||
351 | int 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 | */ | ||
377 | int SkI2cSndDev( | ||
378 | SK_IOC IoC, /* I/O Context */ | ||
379 | int Addr, /* Device Address */ | ||
380 | int 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 | */ | ||
399 | int SkI2cWait( | ||
400 | SK_AC *pAC, /* Adapter Context */ | ||
401 | SK_IOC IoC, /* I/O Context */ | ||
402 | int 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 | */ | ||
444 | void SkI2cWaitIrq( | ||
445 | SK_AC *pAC, /* Adapter Context */ | ||
446 | SK_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 | */ | ||
484 | int SkI2cWrite( | ||
485 | SK_AC *pAC, /* Adapter Context */ | ||
486 | SK_IOC IoC, /* I/O Context */ | ||
487 | SK_U32 I2cData, /* I2C Data to write */ | ||
488 | int I2cDev, /* I2C Device Address */ | ||
489 | int I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */ | ||
490 | int I2cReg, /* I2C Device Register Address */ | ||
491 | int 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 | */ | ||
507 | SK_U32 SkI2cRead( | ||
508 | SK_AC *pAC, /* Adapter Context */ | ||
509 | SK_IOC IoC, /* I/O Context */ | ||
510 | int I2cDev, /* I2C Device Address */ | ||
511 | int I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */ | ||
512 | int I2cReg, /* I2C Device Register Address */ | ||
513 | int 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 | */ | ||
541 | int SkI2cReadSensor( | ||
542 | SK_AC *pAC, /* Adapter Context */ | ||
543 | SK_IOC IoC, /* I/O Context */ | ||
544 | SK_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 | */ | ||
557 | static int SkI2cInit0( | ||
558 | SK_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 | */ | ||
620 | static int SkI2cInit1( | ||
621 | SK_AC *pAC, /* Adapter Context */ | ||
622 | SK_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 | */ | ||
837 | static int SkI2cInit2( | ||
838 | SK_AC *pAC, /* Adapter Context */ | ||
839 | SK_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 | */ | ||
882 | int SkI2cInit( | ||
883 | SK_AC *pAC, /* Adapter Context */ | ||
884 | SK_IOC IoC, /* I/O Context needed in levels 1 and 2 */ | ||
885 | int 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 | */ | ||
914 | void SkI2cIsr( | ||
915 | SK_AC *pAC, /* Adapter Context */ | ||
916 | SK_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 | */ | ||
931 | static void SkI2cCheckSensor( | ||
932 | SK_AC *pAC, /* Adapter Context */ | ||
933 | SK_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 | */ | ||
1166 | int SkI2cEvent( | ||
1167 | SK_AC *pAC, /* Adapter Context */ | ||
1168 | SK_IOC IoC, /* I/O Context */ | ||
1169 | SK_U32 Event, /* Module specific Event */ | ||
1170 | SK_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)))) | ||
29 | static 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 | */ | ||
50 | int SkLm80RcvReg( | ||
51 | SK_IOC IoC, /* Adapter Context */ | ||
52 | int Dev, /* I2C device address */ | ||
53 | int 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 | */ | ||
121 | int SkLm80ReadSensor( | ||
122 | SK_AC *pAC, /* Adapter Context */ | ||
123 | SK_IOC IoC, /* I/O Context needed in level 1 and 2 */ | ||
124 | SK_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 | |||
34 | static int sk_seq_show(struct seq_file *seq, void *v); | ||
35 | static int sk_proc_open(struct inode *inode, struct file *file); | ||
36 | |||
37 | struct 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 | */ | ||
58 | static 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 | */ | ||
256 | static 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)))) | ||
30 | static 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 | */ | ||
45 | intro() | ||
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 | */ | ||
56 | void SkEventInit( | ||
57 | SK_AC *pAC, /* Adapter context */ | ||
58 | SK_IOC Ioc, /* IO context */ | ||
59 | int 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 | */ | ||
73 | void SkEventQueue( | ||
74 | SK_AC *pAC, /* Adapters context */ | ||
75 | SK_U32 Class, /* Event Class */ | ||
76 | SK_U32 Event, /* Event to be queued */ | ||
77 | SK_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 | */ | ||
100 | int SkEventDispatcher( | ||
101 | SK_AC *pAC, /* Adapters Context */ | ||
102 | SK_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 | ||
41 | static 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 | ||
48 | extern "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. */ | ||
245 | typedef 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 | |||
260 | typedef 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 | |||
283 | SK_MAC_ADDR SkRlmtMcAddr = {{0x01, 0x00, 0x5A, 0x52, 0x4C, 0x4D}}; | ||
284 | SK_MAC_ADDR BridgeMcAddr = {{0x01, 0x80, 0xC2, 0x00, 0x00, 0x00}}; | ||
285 | SK_MAC_ADDR BcAddr = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; | ||
286 | |||
287 | /* local variables ************************************************************/ | ||
288 | |||
289 | /* None. */ | ||
290 | |||
291 | /* functions ******************************************************************/ | ||
292 | |||
293 | RLMT_STATIC void SkRlmtCheckSwitch( | ||
294 | SK_AC *pAC, | ||
295 | SK_IOC IoC, | ||
296 | SK_U32 NetIdx); | ||
297 | RLMT_STATIC void SkRlmtCheckSeg( | ||
298 | SK_AC *pAC, | ||
299 | SK_IOC IoC, | ||
300 | SK_U32 NetIdx); | ||
301 | RLMT_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 | */ | ||
339 | void SkRlmtInit( | ||
340 | SK_AC *pAC, /* Adapter Context */ | ||
341 | SK_IOC IoC, /* I/O Context */ | ||
342 | int 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 | */ | ||
495 | RLMT_STATIC void SkRlmtBuildCheckChain( | ||
496 | SK_AC *pAC, /* Adapter Context */ | ||
497 | SK_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 | */ | ||
582 | RLMT_STATIC SK_MBUF *SkRlmtBuildPacket( | ||
583 | SK_AC *pAC, /* Adapter Context */ | ||
584 | SK_IOC IoC, /* I/O Context */ | ||
585 | SK_U32 PortNumber, /* Sending port */ | ||
586 | SK_U16 PacketType, /* RLMT packet type */ | ||
587 | SK_MAC_ADDR *SrcAddr, /* Source address */ | ||
588 | SK_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 | */ | ||
669 | RLMT_STATIC SK_MBUF *SkRlmtBuildSpanningTreePacket( | ||
670 | SK_AC *pAC, /* Adapter Context */ | ||
671 | SK_IOC IoC, /* I/O Context */ | ||
672 | SK_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 | */ | ||
752 | RLMT_STATIC void SkRlmtSend( | ||
753 | SK_AC *pAC, /* Adapter Context */ | ||
754 | SK_IOC IoC, /* I/O Context */ | ||
755 | SK_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 | */ | ||
820 | RLMT_STATIC void SkRlmtPortReceives( | ||
821 | SK_AC *pAC, /* Adapter Context */ | ||
822 | SK_IOC IoC, /* I/O Context */ | ||
823 | SK_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 | */ | ||
876 | RLMT_STATIC void SkRlmtPacketReceive( | ||
877 | SK_AC *pAC, /* Adapter Context */ | ||
878 | SK_IOC IoC, /* I/O Context */ | ||
879 | SK_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 | */ | ||
1220 | RLMT_STATIC SK_U32 SkRlmtCheckPort( | ||
1221 | SK_AC *pAC, /* Adapter Context */ | ||
1222 | SK_IOC IoC, /* I/O Context */ | ||
1223 | SK_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 | */ | ||
1326 | RLMT_STATIC SK_BOOL SkRlmtSelectBcRx( | ||
1327 | SK_AC *pAC, /* Adapter Context */ | ||
1328 | SK_IOC IoC, /* I/O Context */ | ||
1329 | SK_U32 Active, /* Active port */ | ||
1330 | SK_U32 PrefPort, /* Preferred port */ | ||
1331 | SK_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 | */ | ||
1409 | RLMT_STATIC SK_BOOL SkRlmtSelectNotSuspect( | ||
1410 | SK_AC *pAC, /* Adapter Context */ | ||
1411 | SK_IOC IoC, /* I/O Context */ | ||
1412 | SK_U32 Active, /* Active port */ | ||
1413 | SK_U32 PrefPort, /* Preferred port */ | ||
1414 | SK_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 | */ | ||
1458 | RLMT_STATIC SK_BOOL SkRlmtSelectUp( | ||
1459 | SK_AC *pAC, /* Adapter Context */ | ||
1460 | SK_IOC IoC, /* I/O Context */ | ||
1461 | SK_U32 Active, /* Active port */ | ||
1462 | SK_U32 PrefPort, /* Preferred port */ | ||
1463 | SK_U32 *pSelect, /* New active port */ | ||
1464 | SK_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 | */ | ||
1507 | RLMT_STATIC SK_BOOL SkRlmtSelectGoingUp( | ||
1508 | SK_AC *pAC, /* Adapter Context */ | ||
1509 | SK_IOC IoC, /* I/O Context */ | ||
1510 | SK_U32 Active, /* Active port */ | ||
1511 | SK_U32 PrefPort, /* Preferred port */ | ||
1512 | SK_U32 *pSelect, /* New active port */ | ||
1513 | SK_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 | */ | ||
1565 | RLMT_STATIC SK_BOOL SkRlmtSelectDown( | ||
1566 | SK_AC *pAC, /* Adapter Context */ | ||
1567 | SK_IOC IoC, /* I/O Context */ | ||
1568 | SK_U32 Active, /* Active port */ | ||
1569 | SK_U32 PrefPort, /* Preferred port */ | ||
1570 | SK_U32 *pSelect, /* New active port */ | ||
1571 | SK_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 | */ | ||
1615 | RLMT_STATIC void SkRlmtCheckSwitch( | ||
1616 | SK_AC *pAC, /* Adapter Context */ | ||
1617 | SK_IOC IoC, /* I/O Context */ | ||
1618 | SK_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 | */ | ||
1847 | RLMT_STATIC void SkRlmtCheckSeg( | ||
1848 | SK_AC *pAC, /* Adapter Context */ | ||
1849 | SK_IOC IoC, /* I/O Context */ | ||
1850 | SK_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 | */ | ||
1925 | RLMT_STATIC void SkRlmtPortStart( | ||
1926 | SK_AC *pAC, /* Adapter Context */ | ||
1927 | SK_IOC IoC, /* I/O Context */ | ||
1928 | SK_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 | */ | ||
1958 | RLMT_STATIC void SkRlmtEvtPortStartTim( | ||
1959 | SK_AC *pAC, /* Adapter Context */ | ||
1960 | SK_IOC IoC, /* I/O Context */ | ||
1961 | SK_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 | */ | ||
2011 | RLMT_STATIC void SkRlmtEvtLinkUp( | ||
2012 | SK_AC *pAC, /* Adapter Context */ | ||
2013 | SK_IOC IoC, /* I/O Context */ | ||
2014 | SK_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 | */ | ||
2131 | RLMT_STATIC void SkRlmtEvtPortUpTim( | ||
2132 | SK_AC *pAC, /* Adapter Context */ | ||
2133 | SK_IOC IoC, /* I/O Context */ | ||
2134 | SK_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 | */ | ||
2185 | RLMT_STATIC void SkRlmtEvtPortDownX( | ||
2186 | SK_AC *pAC, /* Adapter Context */ | ||
2187 | SK_IOC IoC, /* I/O Context */ | ||
2188 | SK_U32 Event, /* Event code */ | ||
2189 | SK_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 | */ | ||
2264 | RLMT_STATIC void SkRlmtEvtLinkDown( | ||
2265 | SK_AC *pAC, /* Adapter Context */ | ||
2266 | SK_IOC IoC, /* I/O Context */ | ||
2267 | SK_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 | */ | ||
2310 | RLMT_STATIC void SkRlmtEvtPortAddr( | ||
2311 | SK_AC *pAC, /* Adapter Context */ | ||
2312 | SK_IOC IoC, /* I/O Context */ | ||
2313 | SK_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 | */ | ||
2369 | RLMT_STATIC void SkRlmtEvtStart( | ||
2370 | SK_AC *pAC, /* Adapter Context */ | ||
2371 | SK_IOC IoC, /* I/O Context */ | ||
2372 | SK_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 | */ | ||
2459 | RLMT_STATIC void SkRlmtEvtStop( | ||
2460 | SK_AC *pAC, /* Adapter Context */ | ||
2461 | SK_IOC IoC, /* I/O Context */ | ||
2462 | SK_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 | */ | ||
2550 | RLMT_STATIC void SkRlmtEvtTim( | ||
2551 | SK_AC *pAC, /* Adapter Context */ | ||
2552 | SK_IOC IoC, /* I/O Context */ | ||
2553 | SK_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 | */ | ||
2658 | RLMT_STATIC void SkRlmtEvtSegTim( | ||
2659 | SK_AC *pAC, /* Adapter Context */ | ||
2660 | SK_IOC IoC, /* I/O Context */ | ||
2661 | SK_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 | */ | ||
2724 | RLMT_STATIC void SkRlmtEvtPacketRx( | ||
2725 | SK_AC *pAC, /* Adapter Context */ | ||
2726 | SK_IOC IoC, /* I/O Context */ | ||
2727 | SK_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 | */ | ||
2782 | RLMT_STATIC void SkRlmtEvtStatsClear( | ||
2783 | SK_AC *pAC, /* Adapter Context */ | ||
2784 | SK_IOC IoC, /* I/O Context */ | ||
2785 | SK_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 | */ | ||
2838 | RLMT_STATIC void SkRlmtEvtStatsUpdate( | ||
2839 | SK_AC *pAC, /* Adapter Context */ | ||
2840 | SK_IOC IoC, /* I/O Context */ | ||
2841 | SK_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 | */ | ||
2883 | RLMT_STATIC void SkRlmtEvtPrefportChange( | ||
2884 | SK_AC *pAC, /* Adapter Context */ | ||
2885 | SK_IOC IoC, /* I/O Context */ | ||
2886 | SK_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 | */ | ||
2940 | RLMT_STATIC void SkRlmtEvtSetNets( | ||
2941 | SK_AC *pAC, /* Adapter Context */ | ||
2942 | SK_IOC IoC, /* I/O Context */ | ||
2943 | SK_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 | */ | ||
3068 | RLMT_STATIC void SkRlmtEvtModeChange( | ||
3069 | SK_AC *pAC, /* Adapter Context */ | ||
3070 | SK_IOC IoC, /* I/O Context */ | ||
3071 | SK_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 | */ | ||
3180 | int SkRlmtEvent( | ||
3181 | SK_AC *pAC, /* Adapter Context */ | ||
3182 | SK_IOC IoC, /* I/O Context */ | ||
3183 | SK_U32 Event, /* Event code */ | ||
3184 | SK_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)))) | ||
30 | static 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 | */ | ||
44 | intro() | ||
45 | {} | ||
46 | #endif | ||
47 | |||
48 | |||
49 | /* Forward declaration */ | ||
50 | static 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 | */ | ||
58 | void SkTimerInit( | ||
59 | SK_AC *pAC, /* Adapters context */ | ||
60 | SK_IOC Ioc, /* IoContext */ | ||
61 | int 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 | */ | ||
80 | void SkTimerStop( | ||
81 | SK_AC *pAC, /* Adapters context */ | ||
82 | SK_IOC Ioc, /* IoContext */ | ||
83 | SK_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 | */ | ||
120 | void SkTimerStart( | ||
121 | SK_AC *pAC, /* Adapters context */ | ||
122 | SK_IOC Ioc, /* IoContext */ | ||
123 | SK_TIMER *pTimer, /* Timer Pointer to be started */ | ||
124 | SK_U32 Time, /* Time value */ | ||
125 | SK_U32 Class, /* Event Class for this timer */ | ||
126 | SK_U32 Event, /* Event Value for this timer */ | ||
127 | SK_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 | |||
193 | void SkTimerDone( | ||
194 | SK_AC *pAC, /* Adapters context */ | ||
195 | SK_IOC Ioc) /* IoContext */ | ||
196 | { | ||
197 | timer_done(pAC, Ioc, 1); | ||
198 | } | ||
199 | |||
200 | |||
201 | static void timer_done( | ||
202 | SK_AC *pAC, /* Adapters context */ | ||
203 | SK_IOC Ioc, /* IoContext */ | ||
204 | int 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 | */ | ||
27 | static 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 | ||
39 | static SK_VPD_PARA *vpd_find_para( | ||
40 | SK_AC *pAC, | ||
41 | const char *key, | ||
42 | SK_VPD_PARA *p); | ||
43 | #else /* SK_KR_PROTO */ | ||
44 | static 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 | */ | ||
54 | static int VpdWait( | ||
55 | SK_AC *pAC, /* Adapters context */ | ||
56 | SK_IOC IoC, /* IO Context */ | ||
57 | int 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 | */ | ||
106 | SK_U32 VpdReadDWord( | ||
107 | SK_AC *pAC, /* Adapters context */ | ||
108 | SK_IOC IoC, /* IO Context */ | ||
109 | int 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 | */ | ||
160 | static int VpdWriteDWord( | ||
161 | SK_AC *pAC, /* pAC pointer */ | ||
162 | SK_IOC IoC, /* IO Context */ | ||
163 | int addr, /* VPD address */ | ||
164 | SK_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 | */ | ||
200 | static int VpdWriteStream( | ||
201 | SK_AC *pAC, /* Adapters context */ | ||
202 | SK_IOC IoC, /* IO Context */ | ||
203 | char *buf, /* data buffer */ | ||
204 | int Addr, /* VPD start address */ | ||
205 | int 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 | */ | ||
295 | static int VpdReadStream( | ||
296 | SK_AC *pAC, /* Adapters context */ | ||
297 | SK_IOC IoC, /* IO Context */ | ||
298 | char *buf, /* data buffer */ | ||
299 | int Addr, /* VPD start address */ | ||
300 | int 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 | */ | ||
334 | static int VpdTransferBlock( | ||
335 | SK_AC *pAC, /* Adapters context */ | ||
336 | SK_IOC IoC, /* IO Context */ | ||
337 | char *buf, /* data buffer */ | ||
338 | int addr, /* VPD start address */ | ||
339 | int len, /* number of bytes to read / to write */ | ||
340 | int 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 | */ | ||
384 | int VpdReadBlock( | ||
385 | SK_AC *pAC, /* pAC pointer */ | ||
386 | SK_IOC IoC, /* IO Context */ | ||
387 | char *buf, /* buffer were the data should be stored */ | ||
388 | int addr, /* start reading at the VPD address */ | ||
389 | int 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 | */ | ||
399 | int VpdWriteBlock( | ||
400 | SK_AC *pAC, /* pAC pointer */ | ||
401 | SK_IOC IoC, /* IO Context */ | ||
402 | char *buf, /* buffer, holds the data to write */ | ||
403 | int addr, /* start writing at the VPD address */ | ||
404 | int 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 | */ | ||
419 | static int VpdInit( | ||
420 | SK_AC *pAC, /* Adapters context */ | ||
421 | SK_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 | */ | ||
541 | static SK_VPD_PARA *vpd_find_para( | ||
542 | SK_AC *pAC, /* common data base */ | ||
543 | const char *key, /* keyword to find (e.g. "MN") */ | ||
544 | SK_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 | */ | ||
612 | static void vpd_move_para( | ||
613 | char *start, /* start of memory block */ | ||
614 | char *end, /* end of memory block to move */ | ||
615 | int 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 | */ | ||
645 | static void vpd_insert_key( | ||
646 | const char *key, /* keyword to insert */ | ||
647 | const char *buf, /* buffer with the keyword value */ | ||
648 | int len, /* length of the value string */ | ||
649 | char *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 | */ | ||
667 | static int vpd_mod_endtag( | ||
668 | SK_AC *pAC, /* common data base */ | ||
669 | char *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 | */ | ||
731 | int VpdSetupPara( | ||
732 | SK_AC *pAC, /* common data base */ | ||
733 | const char *key, /* keyword to insert */ | ||
734 | const char *buf, /* buffer with the keyword value */ | ||
735 | int len, /* length of the keyword value */ | ||
736 | int type, /* VPD_RO_KEY or VPD_RW_KEY */ | ||
737 | int 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 | */ | ||
824 | SK_VPD_STATUS *VpdStat( | ||
825 | SK_AC *pAC, /* Adapters context */ | ||
826 | SK_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 | */ | ||
857 | int VpdKeys( | ||
858 | SK_AC *pAC, /* common data base */ | ||
859 | SK_IOC IoC, /* IO Context */ | ||
860 | char *buf, /* buffer where to copy the keywords */ | ||
861 | int *len, /* buffer length */ | ||
862 | int *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 | */ | ||
943 | int VpdRead( | ||
944 | SK_AC *pAC, /* common data base */ | ||
945 | SK_IOC IoC, /* IO Context */ | ||
946 | const char *key, /* keyword to read (e.g. "MN") */ | ||
947 | char *buf, /* buffer where to copy the keyword value */ | ||
948 | int *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 | */ | ||
989 | SK_BOOL VpdMayWrite( | ||
990 | char *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 | */ | ||
1014 | int VpdWrite( | ||
1015 | SK_AC *pAC, /* common data base */ | ||
1016 | SK_IOC IoC, /* IO Context */ | ||
1017 | const char *key, /* keyword to write (allowed values "Yx", "Vx") */ | ||
1018 | const 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 | */ | ||
1074 | int VpdDelete( | ||
1075 | SK_AC *pAC, /* common data base */ | ||
1076 | SK_IOC IoC, /* IO Context */ | ||
1077 | char *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 | */ | ||
1129 | int VpdUpdate( | ||
1130 | SK_AC *pAC, /* Adapters context */ | ||
1131 | SK_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 | */ | ||
1163 | void VpdErrLog( | ||
1164 | SK_AC *pAC, /* common data base */ | ||
1165 | SK_IOC IoC, /* IO Context */ | ||
1166 | char *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 */ | ||
31 | typedef 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)))) | ||
39 | static 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 | ||
44 | BCOM_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 | }; | ||
50 | BCOM_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 | ||
59 | static void SkXmInitPhyXmac(SK_AC*, SK_IOC, int, SK_BOOL); | ||
60 | static void SkXmInitPhyBcom(SK_AC*, SK_IOC, int, SK_BOOL); | ||
61 | static int SkXmAutoNegDoneXmac(SK_AC*, SK_IOC, int); | ||
62 | static int SkXmAutoNegDoneBcom(SK_AC*, SK_IOC, int); | ||
63 | #endif /* GENESIS */ | ||
64 | #ifdef YUKON | ||
65 | static void SkGmInitPhyMarv(SK_AC*, SK_IOC, int, SK_BOOL); | ||
66 | static int SkGmAutoNegDoneMarv(SK_AC*, SK_IOC, int); | ||
67 | #endif /* YUKON */ | ||
68 | #ifdef OTHER_PHY | ||
69 | static void SkXmInitPhyLone(SK_AC*, SK_IOC, int, SK_BOOL); | ||
70 | static void SkXmInitPhyNat (SK_AC*, SK_IOC, int, SK_BOOL); | ||
71 | static int SkXmAutoNegDoneLone(SK_AC*, SK_IOC, int); | ||
72 | static 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 | */ | ||
86 | void SkXmPhyRead( | ||
87 | SK_AC *pAC, /* Adapter Context */ | ||
88 | SK_IOC IoC, /* I/O Context */ | ||
89 | int Port, /* Port Index (MAC_1 + n) */ | ||
90 | int PhyReg, /* Register Address (Offset) */ | ||
91 | SK_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 | */ | ||
125 | void SkXmPhyWrite( | ||
126 | SK_AC *pAC, /* Adapter Context */ | ||
127 | SK_IOC IoC, /* I/O Context */ | ||
128 | int Port, /* Port Index (MAC_1 + n) */ | ||
129 | int PhyReg, /* Register Address (Offset) */ | ||
130 | SK_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 | */ | ||
170 | void SkGmPhyRead( | ||
171 | SK_AC *pAC, /* Adapter Context */ | ||
172 | SK_IOC IoC, /* I/O Context */ | ||
173 | int Port, /* Port Index (MAC_1 + n) */ | ||
174 | int PhyReg, /* Register Address (Offset) */ | ||
175 | SK_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 | */ | ||
237 | void SkGmPhyWrite( | ||
238 | SK_AC *pAC, /* Adapter Context */ | ||
239 | SK_IOC IoC, /* I/O Context */ | ||
240 | int Port, /* Port Index (MAC_1 + n) */ | ||
241 | int PhyReg, /* Register Address (Offset) */ | ||
242 | SK_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 | */ | ||
308 | void SkGePhyRead( | ||
309 | SK_AC *pAC, /* Adapter Context */ | ||
310 | SK_IOC IoC, /* I/O Context */ | ||
311 | int Port, /* Port Index (MAC_1 + n) */ | ||
312 | int PhyReg, /* Register Address (Offset) */ | ||
313 | SK_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 | */ | ||
337 | void SkGePhyWrite( | ||
338 | SK_AC *pAC, /* Adapter Context */ | ||
339 | SK_IOC IoC, /* I/O Context */ | ||
340 | int Port, /* Port Index (MAC_1 + n) */ | ||
341 | int PhyReg, /* Register Address (Offset) */ | ||
342 | SK_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 | */ | ||
369 | void SkMacPromiscMode( | ||
370 | SK_AC *pAC, /* adapter context */ | ||
371 | SK_IOC IoC, /* IO context */ | ||
372 | int Port, /* Port Index (MAC_1 + n) */ | ||
373 | SK_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 | */ | ||
429 | void SkMacHashing( | ||
430 | SK_AC *pAC, /* adapter context */ | ||
431 | SK_IOC IoC, /* IO context */ | ||
432 | int Port, /* Port Index (MAC_1 + n) */ | ||
433 | SK_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 | */ | ||
501 | static void SkXmSetRxCmd( | ||
502 | SK_AC *pAC, /* adapter context */ | ||
503 | SK_IOC IoC, /* IO context */ | ||
504 | int Port, /* Port Index (MAC_1 + n) */ | ||
505 | int 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 | */ | ||
586 | static void SkGmSetRxCmd( | ||
587 | SK_AC *pAC, /* adapter context */ | ||
588 | SK_IOC IoC, /* IO context */ | ||
589 | int Port, /* Port Index (MAC_1 + n) */ | ||
590 | int 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 | */ | ||
643 | void SkMacSetRxCmd( | ||
644 | SK_AC *pAC, /* adapter context */ | ||
645 | SK_IOC IoC, /* IO context */ | ||
646 | int Port, /* Port Index (MAC_1 + n) */ | ||
647 | int 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 | */ | ||
670 | void SkMacCrcGener( | ||
671 | SK_AC *pAC, /* adapter context */ | ||
672 | SK_IOC IoC, /* IO context */ | ||
673 | int Port, /* Port Index (MAC_1 + n) */ | ||
674 | SK_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 | */ | ||
723 | void SkXmClrExactAddr( | ||
724 | SK_AC *pAC, /* adapter context */ | ||
725 | SK_IOC IoC, /* IO context */ | ||
726 | int Port, /* Port Index (MAC_1 + n) */ | ||
727 | int StartNum, /* Begin with this Address Register Index (0..15) */ | ||
728 | int 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 | */ | ||
757 | void SkMacFlushTxFifo( | ||
758 | SK_AC *pAC, /* adapter context */ | ||
759 | SK_IOC IoC, /* IO context */ | ||
760 | int 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 | */ | ||
793 | void SkMacFlushRxFifo( | ||
794 | SK_AC *pAC, /* adapter context */ | ||
795 | SK_IOC IoC, /* IO context */ | ||
796 | int 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 | */ | ||
855 | static void SkXmSoftRst( | ||
856 | SK_AC *pAC, /* adapter context */ | ||
857 | SK_IOC IoC, /* IO context */ | ||
858 | int 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 | */ | ||
918 | static void SkXmHardRst( | ||
919 | SK_AC *pAC, /* adapter context */ | ||
920 | SK_IOC IoC, /* IO context */ | ||
921 | int 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 | */ | ||
980 | static void SkXmClearRst( | ||
981 | SK_AC *pAC, /* adapter context */ | ||
982 | SK_IOC IoC, /* IO context */ | ||
983 | int 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 | */ | ||
1022 | static void SkGmSoftRst( | ||
1023 | SK_AC *pAC, /* adapter context */ | ||
1024 | SK_IOC IoC, /* IO context */ | ||
1025 | int 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 | */ | ||
1059 | static void SkGmHardRst( | ||
1060 | SK_AC *pAC, /* adapter context */ | ||
1061 | SK_IOC IoC, /* IO context */ | ||
1062 | int 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 | */ | ||
1096 | static void SkGmClearRst( | ||
1097 | SK_AC *pAC, /* adapter context */ | ||
1098 | SK_IOC IoC, /* IO context */ | ||
1099 | int 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 | */ | ||
1164 | void SkMacSoftRst( | ||
1165 | SK_AC *pAC, /* adapter context */ | ||
1166 | SK_IOC IoC, /* IO context */ | ||
1167 | int 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 | */ | ||
1209 | void SkMacHardRst( | ||
1210 | SK_AC *pAC, /* adapter context */ | ||
1211 | SK_IOC IoC, /* IO context */ | ||
1212 | int 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 | */ | ||
1243 | void SkMacClearRst( | ||
1244 | SK_AC *pAC, /* adapter context */ | ||
1245 | SK_IOC IoC, /* IO context */ | ||
1246 | int 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 | */ | ||
1281 | void SkXmInitMac( | ||
1282 | SK_AC *pAC, /* adapter context */ | ||
1283 | SK_IOC IoC, /* IO context */ | ||
1284 | int 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 | */ | ||
1495 | void SkGmInitMac( | ||
1496 | SK_AC *pAC, /* adapter context */ | ||
1497 | SK_IOC IoC, /* IO context */ | ||
1498 | int 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 | */ | ||
1716 | void SkXmInitDupMd( | ||
1717 | SK_AC *pAC, /* adapter context */ | ||
1718 | SK_IOC IoC, /* IO context */ | ||
1719 | int 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 | */ | ||
1764 | void SkXmInitPauseMd( | ||
1765 | SK_AC *pAC, /* adapter context */ | ||
1766 | SK_IOC IoC, /* IO context */ | ||
1767 | int 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 | */ | ||
1847 | static void SkXmInitPhyXmac( | ||
1848 | SK_AC *pAC, /* adapter context */ | ||
1849 | SK_IOC IoC, /* IO context */ | ||
1850 | int Port, /* Port Index (MAC_1 + n) */ | ||
1851 | SK_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 | */ | ||
1941 | static void SkXmInitPhyBcom( | ||
1942 | SK_AC *pAC, /* adapter context */ | ||
1943 | SK_IOC IoC, /* IO context */ | ||
1944 | int Port, /* Port Index (MAC_1 + n) */ | ||
1945 | SK_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 | */ | ||
2117 | int SkGmEnterLowPowerMode( | ||
2118 | SK_AC *pAC, /* adapter context */ | ||
2119 | SK_IOC IoC, /* IO context */ | ||
2120 | int Port, /* Port Index (e.g. MAC_1) */ | ||
2121 | SK_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 | */ | ||
2245 | int SkGmLeaveLowPowerMode( | ||
2246 | SK_AC *pAC, /* adapter context */ | ||
2247 | SK_IOC IoC, /* IO context */ | ||
2248 | int 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 | */ | ||
2367 | static void SkGmInitPhyMarv( | ||
2368 | SK_AC *pAC, /* adapter context */ | ||
2369 | SK_IOC IoC, /* IO context */ | ||
2370 | int Port, /* Port Index (MAC_1 + n) */ | ||
2371 | SK_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 | */ | ||
2739 | static void SkXmInitPhyLone( | ||
2740 | SK_AC *pAC, /* adapter context */ | ||
2741 | SK_IOC IoC, /* IO context */ | ||
2742 | int Port, /* Port Index (MAC_1 + n) */ | ||
2743 | SK_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 | */ | ||
2864 | static void SkXmInitPhyNat( | ||
2865 | SK_AC *pAC, /* adapter context */ | ||
2866 | SK_IOC IoC, /* IO context */ | ||
2867 | int Port, /* Port Index (MAC_1 + n) */ | ||
2868 | SK_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 | */ | ||
2886 | void SkMacInitPhy( | ||
2887 | SK_AC *pAC, /* adapter context */ | ||
2888 | SK_IOC IoC, /* IO context */ | ||
2889 | int Port, /* Port Index (MAC_1 + n) */ | ||
2890 | SK_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 | */ | ||
2941 | static int SkXmAutoNegDoneXmac( | ||
2942 | SK_AC *pAC, /* adapter context */ | ||
2943 | SK_IOC IoC, /* IO context */ | ||
2944 | int 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 | */ | ||
3024 | static int SkXmAutoNegDoneBcom( | ||
3025 | SK_AC *pAC, /* adapter context */ | ||
3026 | SK_IOC IoC, /* IO context */ | ||
3027 | int 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 | ||
3034 | 01-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 | ||
3045 | 01-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 | ||
3075 | 01-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 | */ | ||
3127 | static int SkGmAutoNegDoneMarv( | ||
3128 | SK_AC *pAC, /* adapter context */ | ||
3129 | SK_IOC IoC, /* IO context */ | ||
3130 | int 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 | */ | ||
3235 | static int SkXmAutoNegDoneLone( | ||
3236 | SK_AC *pAC, /* adapter context */ | ||
3237 | SK_IOC IoC, /* IO context */ | ||
3238 | int 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 | */ | ||
3341 | static int SkXmAutoNegDoneNat( | ||
3342 | SK_AC *pAC, /* adapter context */ | ||
3343 | SK_IOC IoC, /* IO context */ | ||
3344 | int 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 | */ | ||
3363 | int SkMacAutoNegDone( | ||
3364 | SK_AC *pAC, /* adapter context */ | ||
3365 | SK_IOC IoC, /* IO context */ | ||
3366 | int 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 | */ | ||
3434 | static void SkXmSetRxTxEn( | ||
3435 | SK_AC *pAC, /* Adapter Context */ | ||
3436 | SK_IOC IoC, /* IO context */ | ||
3437 | int Port, /* Port Index (MAC_1 + n) */ | ||
3438 | int 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 | */ | ||
3491 | static void SkGmSetRxTxEn( | ||
3492 | SK_AC *pAC, /* Adapter Context */ | ||
3493 | SK_IOC IoC, /* IO context */ | ||
3494 | int Port, /* Port Index (MAC_1 + n) */ | ||
3495 | int 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 | */ | ||
3538 | void SkMacSetRxTxEn( | ||
3539 | SK_AC *pAC, /* Adapter Context */ | ||
3540 | SK_IOC IoC, /* IO context */ | ||
3541 | int Port, /* Port Index (MAC_1 + n) */ | ||
3542 | int 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 | */ | ||
3572 | int SkMacRxTxEnable( | ||
3573 | SK_AC *pAC, /* adapter context */ | ||
3574 | SK_IOC IoC, /* IO context */ | ||
3575 | int 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 | */ | ||
3718 | void SkMacRxTxDisable( | ||
3719 | SK_AC *pAC, /* Adapter Context */ | ||
3720 | SK_IOC IoC, /* IO context */ | ||
3721 | int 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 | */ | ||
3761 | void SkMacIrqDisable( | ||
3762 | SK_AC *pAC, /* Adapter Context */ | ||
3763 | SK_IOC IoC, /* IO context */ | ||
3764 | int 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 | */ | ||
3831 | void SkXmSendCont( | ||
3832 | SK_AC *pAC, /* adapter context */ | ||
3833 | SK_IOC IoC, /* IO context */ | ||
3834 | int Port, /* Port Index (MAC_1 + n) */ | ||
3835 | SK_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 | */ | ||
3862 | void SkMacTimeStamp( | ||
3863 | SK_AC *pAC, /* adapter context */ | ||
3864 | SK_IOC IoC, /* IO context */ | ||
3865 | int Port, /* Port Index (MAC_1 + n) */ | ||
3866 | SK_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 | */ | ||
3908 | void SkXmAutoNegLipaXmac( | ||
3909 | SK_AC *pAC, /* adapter context */ | ||
3910 | SK_IOC IoC, /* IO context */ | ||
3911 | int Port, /* Port Index (MAC_1 + n) */ | ||
3912 | SK_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 | */ | ||
3938 | void SkMacAutoNegLipaPhy( | ||
3939 | SK_AC *pAC, /* adapter context */ | ||
3940 | SK_IOC IoC, /* IO context */ | ||
3941 | int Port, /* Port Index (MAC_1 + n) */ | ||
3942 | SK_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 | */ | ||
3979 | void SkXmIrq( | ||
3980 | SK_AC *pAC, /* adapter context */ | ||
3981 | SK_IOC IoC, /* IO context */ | ||
3982 | int 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 | */ | ||
4115 | void SkGmIrq( | ||
4116 | SK_AC *pAC, /* adapter context */ | ||
4117 | SK_IOC IoC, /* IO context */ | ||
4118 | int 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 | */ | ||
4187 | void SkMacIrq( | ||
4188 | SK_AC *pAC, /* adapter context */ | ||
4189 | SK_IOC IoC, /* IO context */ | ||
4190 | int 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 | */ | ||
4224 | int SkXmUpdateStats( | ||
4225 | SK_AC *pAC, /* adapter context */ | ||
4226 | SK_IOC IoC, /* IO context */ | ||
4227 | unsigned 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 | */ | ||
4274 | int SkXmMacStatistic( | ||
4275 | SK_AC *pAC, /* adapter context */ | ||
4276 | SK_IOC IoC, /* IO context */ | ||
4277 | unsigned int Port, /* Port Index (MAC_1 + n) */ | ||
4278 | SK_U16 StatAddr, /* MIB counter base address */ | ||
4279 | SK_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 | */ | ||
4305 | int SkXmResetCounter( | ||
4306 | SK_AC *pAC, /* adapter context */ | ||
4307 | SK_IOC IoC, /* IO context */ | ||
4308 | unsigned 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 | */ | ||
4337 | int SkXmOverflowStatus( | ||
4338 | SK_AC *pAC, /* adapter context */ | ||
4339 | SK_IOC IoC, /* IO context */ | ||
4340 | unsigned int Port, /* Port Index (MAC_1 + n) */ | ||
4341 | SK_U16 IStatus, /* Interupt Status from MAC */ | ||
4342 | SK_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 | */ | ||
4380 | int SkGmUpdateStats( | ||
4381 | SK_AC *pAC, /* adapter context */ | ||
4382 | SK_IOC IoC, /* IO context */ | ||
4383 | unsigned 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 | */ | ||
4402 | int SkGmMacStatistic( | ||
4403 | SK_AC *pAC, /* adapter context */ | ||
4404 | SK_IOC IoC, /* IO context */ | ||
4405 | unsigned int Port, /* Port Index (MAC_1 + n) */ | ||
4406 | SK_U16 StatAddr, /* MIB counter base address */ | ||
4407 | SK_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 | */ | ||
4436 | int SkGmResetCounter( | ||
4437 | SK_AC *pAC, /* adapter context */ | ||
4438 | SK_IOC IoC, /* IO context */ | ||
4439 | unsigned 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 | */ | ||
4482 | int SkGmOverflowStatus( | ||
4483 | SK_AC *pAC, /* adapter context */ | ||
4484 | SK_IOC IoC, /* IO context */ | ||
4485 | unsigned int Port, /* Port Index (MAC_1 + n) */ | ||
4486 | SK_U16 IStatus, /* Interupt Status from MAC */ | ||
4487 | SK_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 | */ | ||
4535 | int SkGmCableDiagStatus( | ||
4536 | SK_AC *pAC, /* adapter context */ | ||
4537 | SK_IOC IoC, /* IO context */ | ||
4538 | int Port, /* Port Index (MAC_1 + n) */ | ||
4539 | SK_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 */ | ||