diff options
author | Stephen Hemminger <shemminger@linux-foundation.org> | 2007-09-15 19:35:14 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-09-15 19:35:14 -0400 |
commit | 5ad887fa8e875231d72a27c474b10241a5818bf1 (patch) | |
tree | 492292dada18b2db42dc99218345885b1ec43978 /drivers | |
parent | 62270336e8fdfbea36cb455c27744c23780dbf07 (diff) |
sk98lin: resurrect driver
This reverts commit e1abecc48938fbe1966ea6e78267fc673fa59295.
The driver works on some hardware that skge doesn't handle yet.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
42 files changed, 41398 insertions, 1 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 5b9e17bf1749..c5519250efd9 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -2177,7 +2177,7 @@ config SKGE | |||
2177 | with better performance and more complete ethtool support. | 2177 | with better performance and more complete ethtool support. |
2178 | 2178 | ||
2179 | It does not support the link failover and network management | 2179 | It does not support the link failover and network management |
2180 | features available in the hardware. | 2180 | features that "portable" vendor supplied sk98lin driver does. |
2181 | 2181 | ||
2182 | This driver supports adapters based on the original Yukon chipset: | 2182 | This driver supports adapters based on the original Yukon chipset: |
2183 | Marvell 88E8001, Belkin F5D5005, CNet GigaCard, DLink DGE-530T, | 2183 | Marvell 88E8001, Belkin F5D5005, CNet GigaCard, DLink DGE-530T, |
@@ -2215,6 +2215,93 @@ config SKY2_DEBUG | |||
2215 | 2215 | ||
2216 | If unsure, say N. | 2216 | If unsure, say N. |
2217 | 2217 | ||
2218 | config SK98LIN | ||
2219 | tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support (DEPRECATED)" | ||
2220 | depends on PCI | ||
2221 | ---help--- | ||
2222 | Say Y here if you have a Marvell Yukon or SysKonnect SK-98xx/SK-95xx | ||
2223 | compliant Gigabit Ethernet Adapter. | ||
2224 | |||
2225 | This driver supports the original Yukon chipset. This driver is | ||
2226 | deprecated and will be removed from the kernel in the near future, | ||
2227 | it has been replaced by the skge driver. skge is cleaner and | ||
2228 | seems to work better. | ||
2229 | |||
2230 | This driver does not support the newer Yukon2 chipset. A separate | ||
2231 | driver, sky2, is provided to support Yukon2-based adapters. | ||
2232 | |||
2233 | The following adapters are supported by this driver: | ||
2234 | - 3Com 3C940 Gigabit LOM Ethernet Adapter | ||
2235 | - 3Com 3C941 Gigabit LOM Ethernet Adapter | ||
2236 | - Allied Telesyn AT-2970LX Gigabit Ethernet Adapter | ||
2237 | - Allied Telesyn AT-2970LX/2SC Gigabit Ethernet Adapter | ||
2238 | - Allied Telesyn AT-2970SX Gigabit Ethernet Adapter | ||
2239 | - Allied Telesyn AT-2970SX/2SC Gigabit Ethernet Adapter | ||
2240 | - Allied Telesyn AT-2970TX Gigabit Ethernet Adapter | ||
2241 | - Allied Telesyn AT-2970TX/2TX Gigabit Ethernet Adapter | ||
2242 | - Allied Telesyn AT-2971SX Gigabit Ethernet Adapter | ||
2243 | - Allied Telesyn AT-2971T Gigabit Ethernet Adapter | ||
2244 | - Belkin Gigabit Desktop Card 10/100/1000Base-T Adapter, Copper RJ-45 | ||
2245 | - EG1032 v2 Instant Gigabit Network Adapter | ||
2246 | - EG1064 v2 Instant Gigabit Network Adapter | ||
2247 | - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit) | ||
2248 | - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Albatron) | ||
2249 | - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus) | ||
2250 | - Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS) | ||
2251 | - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox) | ||
2252 | - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn) | ||
2253 | - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte) | ||
2254 | - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill) | ||
2255 | - Marvell 88E8050 Gigabit LOM Ethernet Adapter (Intel) | ||
2256 | - Marvell RDK-8001 Adapter | ||
2257 | - Marvell RDK-8002 Adapter | ||
2258 | - Marvell RDK-8003 Adapter | ||
2259 | - Marvell RDK-8004 Adapter | ||
2260 | - Marvell RDK-8006 Adapter | ||
2261 | - Marvell RDK-8007 Adapter | ||
2262 | - Marvell RDK-8008 Adapter | ||
2263 | - Marvell RDK-8009 Adapter | ||
2264 | - Marvell RDK-8010 Adapter | ||
2265 | - Marvell RDK-8011 Adapter | ||
2266 | - Marvell RDK-8012 Adapter | ||
2267 | - Marvell RDK-8052 Adapter | ||
2268 | - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit) | ||
2269 | - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit) | ||
2270 | - N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L) | ||
2271 | - SK-9521 10/100/1000Base-T Adapter | ||
2272 | - SK-9521 V2.0 10/100/1000Base-T Adapter | ||
2273 | - SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T) | ||
2274 | - SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter | ||
2275 | - SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link) | ||
2276 | - SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX) | ||
2277 | - SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter | ||
2278 | - SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link) | ||
2279 | - SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX) | ||
2280 | - SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter | ||
2281 | - SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link) | ||
2282 | - SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter | ||
2283 | - SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition) | ||
2284 | - SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter | ||
2285 | - SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link) | ||
2286 | - SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX) | ||
2287 | - SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter | ||
2288 | - SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) | ||
2289 | - SMC EZ Card 1000 (SMC9452TXV.2) | ||
2290 | |||
2291 | The adapters support Jumbo Frames. | ||
2292 | The dual link adapters support link-failover and dual port features. | ||
2293 | Both Marvell Yukon and SysKonnect SK-98xx/SK-95xx adapters support | ||
2294 | the scatter-gather functionality with sendfile(). Please refer to | ||
2295 | <file:Documentation/networking/sk98lin.txt> for more information about | ||
2296 | optional driver parameters. | ||
2297 | Questions concerning this driver may be addressed to: | ||
2298 | <linux@syskonnect.de> | ||
2299 | |||
2300 | If you want to compile this driver as a module ( = code which can be | ||
2301 | inserted in and removed from the running kernel whenever you want), | ||
2302 | say M here and read <file:Documentation/kbuild/modules.txt>. The module will | ||
2303 | be called sk98lin. This is recommended. | ||
2304 | |||
2218 | config VIA_VELOCITY | 2305 | config VIA_VELOCITY |
2219 | tristate "VIA Velocity support" | 2306 | tristate "VIA Velocity support" |
2220 | depends on PCI | 2307 | depends on PCI |
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index e684212fd8e2..9c928a845841 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile | |||
@@ -66,6 +66,7 @@ ps3_gelic-objs += ps3_gelic_net.o | |||
66 | obj-$(CONFIG_TC35815) += tc35815.o | 66 | obj-$(CONFIG_TC35815) += tc35815.o |
67 | obj-$(CONFIG_SKGE) += skge.o | 67 | obj-$(CONFIG_SKGE) += skge.o |
68 | obj-$(CONFIG_SKY2) += sky2.o | 68 | obj-$(CONFIG_SKY2) += sky2.o |
69 | obj-$(CONFIG_SK98LIN) += sk98lin/ | ||
69 | obj-$(CONFIG_SKFP) += skfp/ | 70 | obj-$(CONFIG_SKFP) += skfp/ |
70 | obj-$(CONFIG_VIA_RHINE) += via-rhine.o | 71 | obj-$(CONFIG_VIA_RHINE) += via-rhine.o |
71 | obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o | 72 | obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o |
diff --git a/drivers/net/sk98lin/Makefile b/drivers/net/sk98lin/Makefile new file mode 100644 index 000000000000..afd900d5d730 --- /dev/null +++ b/drivers/net/sk98lin/Makefile | |||
@@ -0,0 +1,87 @@ | |||
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 | |||
31 | # DBGDEF = \ | ||
32 | # -DDEBUG | ||
33 | |||
34 | ifdef DEBUG | ||
35 | DBGDEF += \ | ||
36 | -DSK_DEBUG_CHKMOD=0x00000000L \ | ||
37 | -DSK_DEBUG_CHKCAT=0x00000000L | ||
38 | endif | ||
39 | |||
40 | |||
41 | # **** possible debug modules for SK_DEBUG_CHKMOD ***************** | ||
42 | # SK_DBGMOD_MERR 0x00000001L /* general module error indication */ | ||
43 | # SK_DBGMOD_HWM 0x00000002L /* Hardware init module */ | ||
44 | # SK_DBGMOD_RLMT 0x00000004L /* RLMT module */ | ||
45 | # SK_DBGMOD_VPD 0x00000008L /* VPD module */ | ||
46 | # SK_DBGMOD_I2C 0x00000010L /* I2C module */ | ||
47 | # SK_DBGMOD_PNMI 0x00000020L /* PNMI module */ | ||
48 | # SK_DBGMOD_CSUM 0x00000040L /* CSUM module */ | ||
49 | # SK_DBGMOD_ADDR 0x00000080L /* ADDR module */ | ||
50 | # SK_DBGMOD_DRV 0x00010000L /* DRV module */ | ||
51 | |||
52 | # **** possible debug categories for SK_DEBUG_CHKCAT ************** | ||
53 | # *** common modules *** | ||
54 | # SK_DBGCAT_INIT 0x00000001L module/driver initialization | ||
55 | # SK_DBGCAT_CTRL 0x00000002L controlling: add/rmv MCA/MAC and other controls (IOCTL) | ||
56 | # SK_DBGCAT_ERR 0x00000004L error handling paths | ||
57 | # SK_DBGCAT_TX 0x00000008L transmit path | ||
58 | # SK_DBGCAT_RX 0x00000010L receive path | ||
59 | # SK_DBGCAT_IRQ 0x00000020L general IRQ handling | ||
60 | # SK_DBGCAT_QUEUE 0x00000040L any queue management | ||
61 | # SK_DBGCAT_DUMP 0x00000080L large data output e.g. hex dump | ||
62 | # SK_DBGCAT_FATAL 0x00000100L large data output e.g. hex dump | ||
63 | |||
64 | # *** driver (file skge.c) *** | ||
65 | # SK_DBGCAT_DRV_ENTRY 0x00010000 entry points | ||
66 | # SK_DBGCAT_DRV_??? 0x00020000 not used | ||
67 | # SK_DBGCAT_DRV_MCA 0x00040000 multicast | ||
68 | # SK_DBGCAT_DRV_TX_PROGRESS 0x00080000 tx path | ||
69 | # SK_DBGCAT_DRV_RX_PROGRESS 0x00100000 rx path | ||
70 | # SK_DBGCAT_DRV_PROGRESS 0x00200000 general runtime | ||
71 | # SK_DBGCAT_DRV_??? 0x00400000 not used | ||
72 | # SK_DBGCAT_DRV_PROM 0x00800000 promiscuous mode | ||
73 | # SK_DBGCAT_DRV_TX_FRAME 0x01000000 display tx frames | ||
74 | # SK_DBGCAT_DRV_ERROR 0x02000000 error conditions | ||
75 | # SK_DBGCAT_DRV_INT_SRC 0x04000000 interrupts sources | ||
76 | # SK_DBGCAT_DRV_EVENT 0x08000000 driver events | ||
77 | |||
78 | EXTRA_CFLAGS += -Idrivers/net/sk98lin -DSK_DIAG_SUPPORT -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM) | ||
79 | |||
80 | clean: | ||
81 | rm -f core *.o *.a *.s | ||
82 | |||
83 | |||
84 | |||
85 | |||
86 | |||
87 | |||
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..423ad063d09b --- /dev/null +++ b/drivers/net/sk98lin/h/skaddr.h | |||
@@ -0,0 +1,285 @@ | |||
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 SkAddrMcAdd( | ||
240 | SK_AC *pAC, | ||
241 | SK_IOC IoC, | ||
242 | SK_U32 PortNumber, | ||
243 | SK_MAC_ADDR *pMc, | ||
244 | int Flags); | ||
245 | |||
246 | extern int SkAddrMcUpdate( | ||
247 | SK_AC *pAC, | ||
248 | SK_IOC IoC, | ||
249 | SK_U32 PortNumber); | ||
250 | |||
251 | extern int SkAddrOverride( | ||
252 | SK_AC *pAC, | ||
253 | SK_IOC IoC, | ||
254 | SK_U32 PortNumber, | ||
255 | SK_MAC_ADDR SK_FAR *pNewAddr, | ||
256 | int Flags); | ||
257 | |||
258 | extern int SkAddrPromiscuousChange( | ||
259 | SK_AC *pAC, | ||
260 | SK_IOC IoC, | ||
261 | SK_U32 PortNumber, | ||
262 | int NewPromMode); | ||
263 | |||
264 | #ifndef SK_SLIM | ||
265 | extern int SkAddrSwap( | ||
266 | SK_AC *pAC, | ||
267 | SK_IOC IoC, | ||
268 | SK_U32 FromPortNumber, | ||
269 | SK_U32 ToPortNumber); | ||
270 | #endif | ||
271 | |||
272 | #else /* defined(SK_KR_PROTO)) */ | ||
273 | |||
274 | /* Non-ANSI/C++ compliant function prototypes */ | ||
275 | |||
276 | #error KR-style prototypes are not yet provided. | ||
277 | |||
278 | #endif /* defined(SK_KR_PROTO)) */ | ||
279 | |||
280 | |||
281 | #ifdef __cplusplus | ||
282 | } | ||
283 | #endif /* __cplusplus */ | ||
284 | |||
285 | #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..6e256bd9a28c --- /dev/null +++ b/drivers/net/sk98lin/h/skcsum.h | |||
@@ -0,0 +1,213 @@ | |||
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 SkCsSetReceiveFlags( | ||
207 | SK_AC *pAc, | ||
208 | unsigned ReceiveFlags, | ||
209 | unsigned *pChecksum1Offset, | ||
210 | unsigned *pChecksum2Offset, | ||
211 | int NetNumber); | ||
212 | |||
213 | #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..91b8d4f45904 --- /dev/null +++ b/drivers/net/sk98lin/h/skdrv1st.h | |||
@@ -0,0 +1,188 @@ | |||
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 | typedef struct s_AC SK_AC; | ||
43 | |||
44 | /* Set card versions */ | ||
45 | #define SK_FAR | ||
46 | |||
47 | /* override some default functions with optimized linux functions */ | ||
48 | |||
49 | #define SK_PNMI_STORE_U16(p,v) memcpy((char*)(p),(char*)&(v),2) | ||
50 | #define SK_PNMI_STORE_U32(p,v) memcpy((char*)(p),(char*)&(v),4) | ||
51 | #define SK_PNMI_STORE_U64(p,v) memcpy((char*)(p),(char*)&(v),8) | ||
52 | #define SK_PNMI_READ_U16(p,v) memcpy((char*)&(v),(char*)(p),2) | ||
53 | #define SK_PNMI_READ_U32(p,v) memcpy((char*)&(v),(char*)(p),4) | ||
54 | #define SK_PNMI_READ_U64(p,v) memcpy((char*)&(v),(char*)(p),8) | ||
55 | |||
56 | #define SK_ADDR_EQUAL(a1,a2) (!memcmp(a1,a2,6)) | ||
57 | |||
58 | #include <linux/types.h> | ||
59 | #include <linux/kernel.h> | ||
60 | #include <linux/string.h> | ||
61 | #include <linux/errno.h> | ||
62 | #include <linux/ioport.h> | ||
63 | #include <linux/slab.h> | ||
64 | #include <linux/interrupt.h> | ||
65 | #include <linux/pci.h> | ||
66 | #include <linux/bitops.h> | ||
67 | #include <asm/byteorder.h> | ||
68 | #include <asm/io.h> | ||
69 | #include <asm/irq.h> | ||
70 | #include <linux/netdevice.h> | ||
71 | #include <linux/etherdevice.h> | ||
72 | #include <linux/skbuff.h> | ||
73 | |||
74 | #include <linux/init.h> | ||
75 | #include <asm/uaccess.h> | ||
76 | #include <net/checksum.h> | ||
77 | |||
78 | #define SK_CS_CALCULATE_CHECKSUM | ||
79 | #ifndef CONFIG_X86_64 | ||
80 | #define SkCsCalculateChecksum(p,l) ((~ip_compute_csum(p, l)) & 0xffff) | ||
81 | #else | ||
82 | #define SkCsCalculateChecksum(p,l) ((~ip_fast_csum(p, l)) & 0xffff) | ||
83 | #endif | ||
84 | |||
85 | #include "h/sktypes.h" | ||
86 | #include "h/skerror.h" | ||
87 | #include "h/skdebug.h" | ||
88 | #include "h/lm80.h" | ||
89 | #include "h/xmac_ii.h" | ||
90 | |||
91 | #ifdef __LITTLE_ENDIAN | ||
92 | #define SK_LITTLE_ENDIAN | ||
93 | #else | ||
94 | #define SK_BIG_ENDIAN | ||
95 | #endif | ||
96 | |||
97 | #define SK_NET_DEVICE net_device | ||
98 | |||
99 | |||
100 | /* we use gethrtime(), return unit: nanoseconds */ | ||
101 | #define SK_TICKS_PER_SEC 100 | ||
102 | |||
103 | #define SK_MEM_MAPPED_IO | ||
104 | |||
105 | // #define SK_RLMT_SLOW_LOOKAHEAD | ||
106 | |||
107 | #define SK_MAX_MACS 2 | ||
108 | #define SK_MAX_NETS 2 | ||
109 | |||
110 | #define SK_IOC char __iomem * | ||
111 | |||
112 | typedef struct s_DrvRlmtMbuf SK_MBUF; | ||
113 | |||
114 | #define SK_CONST64 INT64_C | ||
115 | #define SK_CONSTU64 UINT64_C | ||
116 | |||
117 | #define SK_MEMCPY(dest,src,size) memcpy(dest,src,size) | ||
118 | #define SK_MEMCMP(s1,s2,size) memcmp(s1,s2,size) | ||
119 | #define SK_MEMSET(dest,val,size) memset(dest,val,size) | ||
120 | #define SK_STRLEN(pStr) strlen((char*)(pStr)) | ||
121 | #define SK_STRNCPY(pDest,pSrc,size) strncpy((char*)(pDest),(char*)(pSrc),size) | ||
122 | #define SK_STRCMP(pStr1,pStr2) strcmp((char*)(pStr1),(char*)(pStr2)) | ||
123 | |||
124 | /* macros to access the adapter */ | ||
125 | #define SK_OUT8(b,a,v) writeb((v), ((b)+(a))) | ||
126 | #define SK_OUT16(b,a,v) writew((v), ((b)+(a))) | ||
127 | #define SK_OUT32(b,a,v) writel((v), ((b)+(a))) | ||
128 | #define SK_IN8(b,a,pv) (*(pv) = readb((b)+(a))) | ||
129 | #define SK_IN16(b,a,pv) (*(pv) = readw((b)+(a))) | ||
130 | #define SK_IN32(b,a,pv) (*(pv) = readl((b)+(a))) | ||
131 | |||
132 | #define int8_t char | ||
133 | #define int16_t short | ||
134 | #define int32_t long | ||
135 | #define int64_t long long | ||
136 | #define uint8_t u_char | ||
137 | #define uint16_t u_short | ||
138 | #define uint32_t u_long | ||
139 | #define uint64_t unsigned long long | ||
140 | #define t_scalar_t int | ||
141 | #define t_uscalar_t unsigned int | ||
142 | #define uintptr_t unsigned long | ||
143 | |||
144 | #define __CONCAT__(A,B) A##B | ||
145 | |||
146 | #define INT32_C(a) __CONCAT__(a,L) | ||
147 | #define INT64_C(a) __CONCAT__(a,LL) | ||
148 | #define UINT32_C(a) __CONCAT__(a,UL) | ||
149 | #define UINT64_C(a) __CONCAT__(a,ULL) | ||
150 | |||
151 | #ifdef DEBUG | ||
152 | #define SK_DBG_PRINTF printk | ||
153 | #ifndef SK_DEBUG_CHKMOD | ||
154 | #define SK_DEBUG_CHKMOD 0 | ||
155 | #endif | ||
156 | #ifndef SK_DEBUG_CHKCAT | ||
157 | #define SK_DEBUG_CHKCAT 0 | ||
158 | #endif | ||
159 | /* those come from the makefile */ | ||
160 | #define SK_DBG_CHKMOD(pAC) (SK_DEBUG_CHKMOD) | ||
161 | #define SK_DBG_CHKCAT(pAC) (SK_DEBUG_CHKCAT) | ||
162 | |||
163 | extern void SkDbgPrintf(const char *format,...); | ||
164 | |||
165 | #define SK_DBGMOD_DRV 0x00010000 | ||
166 | |||
167 | /**** possible driver debug categories ********************************/ | ||
168 | #define SK_DBGCAT_DRV_ENTRY 0x00010000 | ||
169 | #define SK_DBGCAT_DRV_SAP 0x00020000 | ||
170 | #define SK_DBGCAT_DRV_MCA 0x00040000 | ||
171 | #define SK_DBGCAT_DRV_TX_PROGRESS 0x00080000 | ||
172 | #define SK_DBGCAT_DRV_RX_PROGRESS 0x00100000 | ||
173 | #define SK_DBGCAT_DRV_PROGRESS 0x00200000 | ||
174 | #define SK_DBGCAT_DRV_MSG 0x00400000 | ||
175 | #define SK_DBGCAT_DRV_PROM 0x00800000 | ||
176 | #define SK_DBGCAT_DRV_TX_FRAME 0x01000000 | ||
177 | #define SK_DBGCAT_DRV_ERROR 0x02000000 | ||
178 | #define SK_DBGCAT_DRV_INT_SRC 0x04000000 | ||
179 | #define SK_DBGCAT_DRV_EVENT 0x08000000 | ||
180 | |||
181 | #endif | ||
182 | |||
183 | #define SK_ERR_LOG SkErrorLog | ||
184 | |||
185 | extern void SkErrorLog(SK_AC*, int, int, char*); | ||
186 | |||
187 | #endif | ||
188 | |||
diff --git a/drivers/net/sk98lin/h/skdrv2nd.h b/drivers/net/sk98lin/h/skdrv2nd.h new file mode 100644 index 000000000000..3fa67171e832 --- /dev/null +++ b/drivers/net/sk98lin/h/skdrv2nd.h | |||
@@ -0,0 +1,447 @@ | |||
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 SkPciWriteCfgWord(SK_AC*, int, SK_U16); | ||
64 | extern int SkPciWriteCfgByte(SK_AC*, int, SK_U8); | ||
65 | extern int SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA); | ||
66 | |||
67 | #ifdef SK_DIAG_SUPPORT | ||
68 | extern int SkDrvEnterDiagMode(SK_AC *pAc); | ||
69 | extern int SkDrvLeaveDiagMode(SK_AC *pAc); | ||
70 | #endif | ||
71 | |||
72 | struct s_DrvRlmtMbuf { | ||
73 | SK_MBUF *pNext; /* Pointer to next RLMT Mbuf. */ | ||
74 | SK_U8 *pData; /* Data buffer (virtually contig.). */ | ||
75 | unsigned Size; /* Data buffer size. */ | ||
76 | unsigned Length; /* Length of packet (<= Size). */ | ||
77 | SK_U32 PortIdx; /* Receiving/transmitting port. */ | ||
78 | #ifdef SK_RLMT_MBUF_PRIVATE | ||
79 | SK_RLMT_MBUF Rlmt; /* Private part for RLMT. */ | ||
80 | #endif /* SK_RLMT_MBUF_PRIVATE */ | ||
81 | struct sk_buff *pOs; /* Pointer to message block */ | ||
82 | }; | ||
83 | |||
84 | |||
85 | /* | ||
86 | * Time macros | ||
87 | */ | ||
88 | #if SK_TICKS_PER_SEC == 100 | ||
89 | #define SK_PNMI_HUNDREDS_SEC(t) (t) | ||
90 | #else | ||
91 | #define SK_PNMI_HUNDREDS_SEC(t) ((((unsigned long)t) * 100) / \ | ||
92 | (SK_TICKS_PER_SEC)) | ||
93 | #endif | ||
94 | |||
95 | /* | ||
96 | * New SkOsGetTime | ||
97 | */ | ||
98 | #define SkOsGetTimeCurrent(pAC, pUsec) {\ | ||
99 | struct timeval t;\ | ||
100 | do_gettimeofday(&t);\ | ||
101 | *pUsec = ((((t.tv_sec) * 1000000L)+t.tv_usec)/10000);\ | ||
102 | } | ||
103 | |||
104 | |||
105 | /* | ||
106 | * ioctl definitions | ||
107 | */ | ||
108 | #define SK_IOCTL_BASE (SIOCDEVPRIVATE) | ||
109 | #define SK_IOCTL_GETMIB (SK_IOCTL_BASE + 0) | ||
110 | #define SK_IOCTL_SETMIB (SK_IOCTL_BASE + 1) | ||
111 | #define SK_IOCTL_PRESETMIB (SK_IOCTL_BASE + 2) | ||
112 | #define SK_IOCTL_GEN (SK_IOCTL_BASE + 3) | ||
113 | #define SK_IOCTL_DIAG (SK_IOCTL_BASE + 4) | ||
114 | |||
115 | typedef struct s_IOCTL SK_GE_IOCTL; | ||
116 | |||
117 | struct s_IOCTL { | ||
118 | char __user * pData; | ||
119 | unsigned int Len; | ||
120 | }; | ||
121 | |||
122 | |||
123 | /* | ||
124 | * define sizes of descriptor rings in bytes | ||
125 | */ | ||
126 | |||
127 | #define TX_RING_SIZE (8*1024) | ||
128 | #define RX_RING_SIZE (24*1024) | ||
129 | |||
130 | /* | ||
131 | * Buffer size for ethernet packets | ||
132 | */ | ||
133 | #define ETH_BUF_SIZE 1540 | ||
134 | #define ETH_MAX_MTU 1514 | ||
135 | #define ETH_MIN_MTU 60 | ||
136 | #define ETH_MULTICAST_BIT 0x01 | ||
137 | #define SK_JUMBO_MTU 9000 | ||
138 | |||
139 | /* | ||
140 | * transmit priority selects the queue: LOW=asynchron, HIGH=synchron | ||
141 | */ | ||
142 | #define TX_PRIO_LOW 0 | ||
143 | #define TX_PRIO_HIGH 1 | ||
144 | |||
145 | /* | ||
146 | * alignment of rx/tx descriptors | ||
147 | */ | ||
148 | #define DESCR_ALIGN 64 | ||
149 | |||
150 | /* | ||
151 | * definitions for pnmi. TODO | ||
152 | */ | ||
153 | #define SK_DRIVER_RESET(pAC, IoC) 0 | ||
154 | #define SK_DRIVER_SENDEVENT(pAC, IoC) 0 | ||
155 | #define SK_DRIVER_SELFTEST(pAC, IoC) 0 | ||
156 | /* For get mtu you must add an own function */ | ||
157 | #define SK_DRIVER_GET_MTU(pAc,IoC,i) 0 | ||
158 | #define SK_DRIVER_SET_MTU(pAc,IoC,i,v) 0 | ||
159 | #define SK_DRIVER_PRESET_MTU(pAc,IoC,i,v) 0 | ||
160 | |||
161 | /* | ||
162 | ** Interim definition of SK_DRV_TIMER placed in this file until | ||
163 | ** common modules have been finalized | ||
164 | */ | ||
165 | #define SK_DRV_TIMER 11 | ||
166 | #define SK_DRV_MODERATION_TIMER 1 | ||
167 | #define SK_DRV_MODERATION_TIMER_LENGTH 1000000 /* 1 second */ | ||
168 | #define SK_DRV_RX_CLEANUP_TIMER 2 | ||
169 | #define SK_DRV_RX_CLEANUP_TIMER_LENGTH 1000000 /* 100 millisecs */ | ||
170 | |||
171 | /* | ||
172 | ** Definitions regarding transmitting frames | ||
173 | ** any calculating any checksum. | ||
174 | */ | ||
175 | #define C_LEN_ETHERMAC_HEADER_DEST_ADDR 6 | ||
176 | #define C_LEN_ETHERMAC_HEADER_SRC_ADDR 6 | ||
177 | #define C_LEN_ETHERMAC_HEADER_LENTYPE 2 | ||
178 | #define C_LEN_ETHERMAC_HEADER ( (C_LEN_ETHERMAC_HEADER_DEST_ADDR) + \ | ||
179 | (C_LEN_ETHERMAC_HEADER_SRC_ADDR) + \ | ||
180 | (C_LEN_ETHERMAC_HEADER_LENTYPE) ) | ||
181 | |||
182 | #define C_LEN_ETHERMTU_MINSIZE 46 | ||
183 | #define C_LEN_ETHERMTU_MAXSIZE_STD 1500 | ||
184 | #define C_LEN_ETHERMTU_MAXSIZE_JUMBO 9000 | ||
185 | |||
186 | #define C_LEN_ETHERNET_MINSIZE ( (C_LEN_ETHERMAC_HEADER) + \ | ||
187 | (C_LEN_ETHERMTU_MINSIZE) ) | ||
188 | |||
189 | #define C_OFFSET_IPHEADER C_LEN_ETHERMAC_HEADER | ||
190 | #define C_OFFSET_IPHEADER_IPPROTO 9 | ||
191 | #define C_OFFSET_TCPHEADER_TCPCS 16 | ||
192 | #define C_OFFSET_UDPHEADER_UDPCS 6 | ||
193 | |||
194 | #define C_OFFSET_IPPROTO ( (C_LEN_ETHERMAC_HEADER) + \ | ||
195 | (C_OFFSET_IPHEADER_IPPROTO) ) | ||
196 | |||
197 | #define C_PROTO_ID_UDP 17 /* refer to RFC 790 or Stevens' */ | ||
198 | #define C_PROTO_ID_TCP 6 /* TCP/IP illustrated for details */ | ||
199 | |||
200 | /* TX and RX descriptors *****************************************************/ | ||
201 | |||
202 | typedef struct s_RxD RXD; /* the receive descriptor */ | ||
203 | |||
204 | struct s_RxD { | ||
205 | volatile SK_U32 RBControl; /* Receive Buffer Control */ | ||
206 | SK_U32 VNextRxd; /* Next receive descriptor,low dword */ | ||
207 | SK_U32 VDataLow; /* Receive buffer Addr, low dword */ | ||
208 | SK_U32 VDataHigh; /* Receive buffer Addr, high dword */ | ||
209 | SK_U32 FrameStat; /* Receive Frame Status word */ | ||
210 | SK_U32 TimeStamp; /* Time stamp from XMAC */ | ||
211 | SK_U32 TcpSums; /* TCP Sum 2 / TCP Sum 1 */ | ||
212 | SK_U32 TcpSumStarts; /* TCP Sum Start 2 / TCP Sum Start 1 */ | ||
213 | RXD *pNextRxd; /* Pointer to next Rxd */ | ||
214 | struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */ | ||
215 | }; | ||
216 | |||
217 | typedef struct s_TxD TXD; /* the transmit descriptor */ | ||
218 | |||
219 | struct s_TxD { | ||
220 | volatile SK_U32 TBControl; /* Transmit Buffer Control */ | ||
221 | SK_U32 VNextTxd; /* Next transmit descriptor,low dword */ | ||
222 | SK_U32 VDataLow; /* Transmit Buffer Addr, low dword */ | ||
223 | SK_U32 VDataHigh; /* Transmit Buffer Addr, high dword */ | ||
224 | SK_U32 FrameStat; /* Transmit Frame Status Word */ | ||
225 | SK_U32 TcpSumOfs; /* Reserved / TCP Sum Offset */ | ||
226 | SK_U16 TcpSumSt; /* TCP Sum Start */ | ||
227 | SK_U16 TcpSumWr; /* TCP Sum Write */ | ||
228 | SK_U32 TcpReserved; /* not used */ | ||
229 | TXD *pNextTxd; /* Pointer to next Txd */ | ||
230 | struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */ | ||
231 | }; | ||
232 | |||
233 | /* Used interrupt bits in the interrupts source register *********************/ | ||
234 | |||
235 | #define DRIVER_IRQS ((IS_IRQ_SW) | \ | ||
236 | (IS_R1_F) |(IS_R2_F) | \ | ||
237 | (IS_XS1_F) |(IS_XA1_F) | \ | ||
238 | (IS_XS2_F) |(IS_XA2_F)) | ||
239 | |||
240 | #define SPECIAL_IRQS ((IS_HW_ERR) |(IS_I2C_READY) | \ | ||
241 | (IS_EXT_REG) |(IS_TIMINT) | \ | ||
242 | (IS_PA_TO_RX1) |(IS_PA_TO_RX2) | \ | ||
243 | (IS_PA_TO_TX1) |(IS_PA_TO_TX2) | \ | ||
244 | (IS_MAC1) |(IS_LNK_SYNC_M1)| \ | ||
245 | (IS_MAC2) |(IS_LNK_SYNC_M2)| \ | ||
246 | (IS_R1_C) |(IS_R2_C) | \ | ||
247 | (IS_XS1_C) |(IS_XA1_C) | \ | ||
248 | (IS_XS2_C) |(IS_XA2_C)) | ||
249 | |||
250 | #define IRQ_MASK ((IS_IRQ_SW) | \ | ||
251 | (IS_R1_B) |(IS_R1_F) |(IS_R2_B) |(IS_R2_F) | \ | ||
252 | (IS_XS1_B) |(IS_XS1_F) |(IS_XA1_B)|(IS_XA1_F)| \ | ||
253 | (IS_XS2_B) |(IS_XS2_F) |(IS_XA2_B)|(IS_XA2_F)| \ | ||
254 | (IS_HW_ERR) |(IS_I2C_READY)| \ | ||
255 | (IS_EXT_REG) |(IS_TIMINT) | \ | ||
256 | (IS_PA_TO_RX1) |(IS_PA_TO_RX2)| \ | ||
257 | (IS_PA_TO_TX1) |(IS_PA_TO_TX2)| \ | ||
258 | (IS_MAC1) |(IS_MAC2) | \ | ||
259 | (IS_R1_C) |(IS_R2_C) | \ | ||
260 | (IS_XS1_C) |(IS_XA1_C) | \ | ||
261 | (IS_XS2_C) |(IS_XA2_C)) | ||
262 | |||
263 | #define IRQ_HWE_MASK (IS_ERR_MSK) /* enable all HW irqs */ | ||
264 | |||
265 | typedef struct s_DevNet DEV_NET; | ||
266 | |||
267 | struct s_DevNet { | ||
268 | int PortNr; | ||
269 | int NetNr; | ||
270 | SK_AC *pAC; | ||
271 | }; | ||
272 | |||
273 | typedef struct s_TxPort TX_PORT; | ||
274 | |||
275 | struct s_TxPort { | ||
276 | /* the transmit descriptor rings */ | ||
277 | caddr_t pTxDescrRing; /* descriptor area memory */ | ||
278 | SK_U64 VTxDescrRing; /* descr. area bus virt. addr. */ | ||
279 | TXD *pTxdRingHead; /* Head of Tx rings */ | ||
280 | TXD *pTxdRingTail; /* Tail of Tx rings */ | ||
281 | TXD *pTxdRingPrev; /* descriptor sent previously */ | ||
282 | int TxdRingFree; /* # of free entrys */ | ||
283 | spinlock_t TxDesRingLock; /* serialize descriptor accesses */ | ||
284 | SK_IOC HwAddr; /* bmu registers address */ | ||
285 | int PortIndex; /* index number of port (0 or 1) */ | ||
286 | }; | ||
287 | |||
288 | typedef struct s_RxPort RX_PORT; | ||
289 | |||
290 | struct s_RxPort { | ||
291 | /* the receive descriptor rings */ | ||
292 | caddr_t pRxDescrRing; /* descriptor area memory */ | ||
293 | SK_U64 VRxDescrRing; /* descr. area bus virt. addr. */ | ||
294 | RXD *pRxdRingHead; /* Head of Rx rings */ | ||
295 | RXD *pRxdRingTail; /* Tail of Rx rings */ | ||
296 | RXD *pRxdRingPrev; /* descriptor given to BMU previously */ | ||
297 | int RxdRingFree; /* # of free entrys */ | ||
298 | int RxCsum; /* use receive checksum hardware */ | ||
299 | spinlock_t RxDesRingLock; /* serialize descriptor accesses */ | ||
300 | int RxFillLimit; /* limit for buffers in ring */ | ||
301 | SK_IOC HwAddr; /* bmu registers address */ | ||
302 | int PortIndex; /* index number of port (0 or 1) */ | ||
303 | }; | ||
304 | |||
305 | /* Definitions needed for interrupt moderation *******************************/ | ||
306 | |||
307 | #define IRQ_EOF_AS_TX ((IS_XA1_F) | (IS_XA2_F)) | ||
308 | #define IRQ_EOF_SY_TX ((IS_XS1_F) | (IS_XS2_F)) | ||
309 | #define IRQ_MASK_TX_ONLY ((IRQ_EOF_AS_TX)| (IRQ_EOF_SY_TX)) | ||
310 | #define IRQ_MASK_RX_ONLY ((IS_R1_F) | (IS_R2_F)) | ||
311 | #define IRQ_MASK_SP_ONLY (SPECIAL_IRQS) | ||
312 | #define IRQ_MASK_TX_RX ((IRQ_MASK_TX_ONLY)| (IRQ_MASK_RX_ONLY)) | ||
313 | #define IRQ_MASK_SP_RX ((SPECIAL_IRQS) | (IRQ_MASK_RX_ONLY)) | ||
314 | #define IRQ_MASK_SP_TX ((SPECIAL_IRQS) | (IRQ_MASK_TX_ONLY)) | ||
315 | #define IRQ_MASK_RX_TX_SP ((SPECIAL_IRQS) | (IRQ_MASK_TX_RX)) | ||
316 | |||
317 | #define C_INT_MOD_NONE 1 | ||
318 | #define C_INT_MOD_STATIC 2 | ||
319 | #define C_INT_MOD_DYNAMIC 4 | ||
320 | |||
321 | #define C_CLK_FREQ_GENESIS 53215000 /* shorter: 53.125 MHz */ | ||
322 | #define C_CLK_FREQ_YUKON 78215000 /* shorter: 78.125 MHz */ | ||
323 | |||
324 | #define C_INTS_PER_SEC_DEFAULT 2000 | ||
325 | #define C_INT_MOD_ENABLE_PERCENTAGE 50 /* if higher 50% enable */ | ||
326 | #define C_INT_MOD_DISABLE_PERCENTAGE 50 /* if lower 50% disable */ | ||
327 | #define C_INT_MOD_IPS_LOWER_RANGE 30 | ||
328 | #define C_INT_MOD_IPS_UPPER_RANGE 40000 | ||
329 | |||
330 | |||
331 | typedef struct s_DynIrqModInfo DIM_INFO; | ||
332 | struct s_DynIrqModInfo { | ||
333 | unsigned long PrevTimeVal; | ||
334 | unsigned int PrevSysLoad; | ||
335 | unsigned int PrevUsedTime; | ||
336 | unsigned int PrevTotalTime; | ||
337 | int PrevUsedDescrRatio; | ||
338 | int NbrProcessedDescr; | ||
339 | SK_U64 PrevPort0RxIntrCts; | ||
340 | SK_U64 PrevPort1RxIntrCts; | ||
341 | SK_U64 PrevPort0TxIntrCts; | ||
342 | SK_U64 PrevPort1TxIntrCts; | ||
343 | SK_BOOL ModJustEnabled; /* Moderation just enabled yes/no */ | ||
344 | |||
345 | int MaxModIntsPerSec; /* Moderation Threshold */ | ||
346 | int MaxModIntsPerSecUpperLimit; /* Upper limit for DIM */ | ||
347 | int MaxModIntsPerSecLowerLimit; /* Lower limit for DIM */ | ||
348 | |||
349 | long MaskIrqModeration; /* ModIrqType (eg. 'TxRx') */ | ||
350 | SK_BOOL DisplayStats; /* Stats yes/no */ | ||
351 | SK_BOOL AutoSizing; /* Resize DIM-timer on/off */ | ||
352 | int IntModTypeSelect; /* EnableIntMod (eg. 'dynamic') */ | ||
353 | |||
354 | SK_TIMER ModTimer; /* just some timer */ | ||
355 | }; | ||
356 | |||
357 | typedef struct s_PerStrm PER_STRM; | ||
358 | |||
359 | #define SK_ALLOC_IRQ 0x00000001 | ||
360 | |||
361 | #ifdef SK_DIAG_SUPPORT | ||
362 | #define DIAG_ACTIVE 1 | ||
363 | #define DIAG_NOTACTIVE 0 | ||
364 | #endif | ||
365 | |||
366 | /**************************************************************************** | ||
367 | * Per board structure / Adapter Context structure: | ||
368 | * Allocated within attach(9e) and freed within detach(9e). | ||
369 | * Contains all 'per device' necessary handles, flags, locks etc.: | ||
370 | */ | ||
371 | struct s_AC { | ||
372 | SK_GEINIT GIni; /* GE init struct */ | ||
373 | SK_PNMI Pnmi; /* PNMI data struct */ | ||
374 | SK_VPD vpd; /* vpd data struct */ | ||
375 | SK_QUEUE Event; /* Event queue */ | ||
376 | SK_HWT Hwt; /* Hardware Timer control struct */ | ||
377 | SK_TIMCTRL Tim; /* Software Timer control struct */ | ||
378 | SK_I2C I2c; /* I2C relevant data structure */ | ||
379 | SK_ADDR Addr; /* for Address module */ | ||
380 | SK_CSUM Csum; /* for checksum module */ | ||
381 | SK_RLMT Rlmt; /* for rlmt module */ | ||
382 | spinlock_t SlowPathLock; /* Normal IRQ lock */ | ||
383 | struct timer_list BlinkTimer; /* for LED blinking */ | ||
384 | int LedsOn; | ||
385 | SK_PNMI_STRUCT_DATA PnmiStruct; /* structure to get all Pnmi-Data */ | ||
386 | int RlmtMode; /* link check mode to set */ | ||
387 | int RlmtNets; /* Number of nets */ | ||
388 | |||
389 | SK_IOC IoBase; /* register set of adapter */ | ||
390 | int BoardLevel; /* level of active hw init (0-2) */ | ||
391 | |||
392 | SK_U32 AllocFlag; /* flag allocation of resources */ | ||
393 | struct pci_dev *PciDev; /* for access to pci config space */ | ||
394 | struct SK_NET_DEVICE *dev[2]; /* pointer to device struct */ | ||
395 | |||
396 | int RxBufSize; /* length of receive buffers */ | ||
397 | struct net_device_stats stats; /* linux 'netstat -i' statistics */ | ||
398 | int Index; /* internal board index number */ | ||
399 | |||
400 | /* adapter RAM sizes for queues of active port */ | ||
401 | int RxQueueSize; /* memory used for receive queue */ | ||
402 | int TxSQueueSize; /* memory used for sync. tx queue */ | ||
403 | int TxAQueueSize; /* memory used for async. tx queue */ | ||
404 | |||
405 | int PromiscCount; /* promiscuous mode counter */ | ||
406 | int AllMultiCount; /* allmulticast mode counter */ | ||
407 | int MulticCount; /* number of different MC */ | ||
408 | /* addresses for this board */ | ||
409 | /* (may be more than HW can)*/ | ||
410 | |||
411 | int HWRevision; /* Hardware revision */ | ||
412 | int ActivePort; /* the active XMAC port */ | ||
413 | int MaxPorts; /* number of activated ports */ | ||
414 | int TxDescrPerRing; /* # of descriptors per tx ring */ | ||
415 | int RxDescrPerRing; /* # of descriptors per rx ring */ | ||
416 | |||
417 | caddr_t pDescrMem; /* Pointer to the descriptor area */ | ||
418 | dma_addr_t pDescrMemDMA; /* PCI DMA address of area */ | ||
419 | |||
420 | /* the port structures with descriptor rings */ | ||
421 | TX_PORT TxPort[SK_MAX_MACS][2]; | ||
422 | RX_PORT RxPort[SK_MAX_MACS]; | ||
423 | |||
424 | SK_BOOL CheckQueue; /* check event queue soon */ | ||
425 | SK_TIMER DrvCleanupTimer;/* to check for pending descriptors */ | ||
426 | DIM_INFO DynIrqModInfo; /* all data related to DIM */ | ||
427 | |||
428 | /* Only for tests */ | ||
429 | int PortDown; | ||
430 | int ChipsetType; /* Chipset family type | ||
431 | * 0 == Genesis family support | ||
432 | * 1 == Yukon family support | ||
433 | */ | ||
434 | #ifdef SK_DIAG_SUPPORT | ||
435 | SK_U32 DiagModeActive; /* is diag active? */ | ||
436 | SK_BOOL DiagFlowCtrl; /* for control purposes */ | ||
437 | SK_PNMI_STRUCT_DATA PnmiBackup; /* backup structure for all Pnmi-Data */ | ||
438 | SK_BOOL WasIfUp[SK_MAX_MACS]; /* for OpenClose while | ||
439 | * DIAG is busy with NIC | ||
440 | */ | ||
441 | #endif | ||
442 | |||
443 | }; | ||
444 | |||
445 | |||
446 | #endif /* __INC_SKDRV2ND_H */ | ||
447 | |||
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..143e635ec24d --- /dev/null +++ b/drivers/net/sk98lin/h/skgeinit.h | |||
@@ -0,0 +1,797 @@ | |||
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 SkGePollTxD( | ||
468 | SK_AC *pAC, | ||
469 | SK_IOC IoC, | ||
470 | int Port, | ||
471 | SK_BOOL PollTxD); | ||
472 | |||
473 | extern void SkGeYellowLED( | ||
474 | SK_AC *pAC, | ||
475 | SK_IOC IoC, | ||
476 | int State); | ||
477 | |||
478 | extern int SkGeCfgSync( | ||
479 | SK_AC *pAC, | ||
480 | SK_IOC IoC, | ||
481 | int Port, | ||
482 | SK_U32 IntTime, | ||
483 | SK_U32 LimCount, | ||
484 | int SyncMode); | ||
485 | |||
486 | extern void SkGeLoadLnkSyncCnt( | ||
487 | SK_AC *pAC, | ||
488 | SK_IOC IoC, | ||
489 | int Port, | ||
490 | SK_U32 CntVal); | ||
491 | |||
492 | extern void SkGeStopPort( | ||
493 | SK_AC *pAC, | ||
494 | SK_IOC IoC, | ||
495 | int Port, | ||
496 | int Dir, | ||
497 | int RstMode); | ||
498 | |||
499 | extern int SkGeInit( | ||
500 | SK_AC *pAC, | ||
501 | SK_IOC IoC, | ||
502 | int Level); | ||
503 | |||
504 | extern void SkGeDeInit( | ||
505 | SK_AC *pAC, | ||
506 | SK_IOC IoC); | ||
507 | |||
508 | extern int SkGeInitPort( | ||
509 | SK_AC *pAC, | ||
510 | SK_IOC IoC, | ||
511 | int Port); | ||
512 | |||
513 | extern void SkGeXmitLED( | ||
514 | SK_AC *pAC, | ||
515 | SK_IOC IoC, | ||
516 | int Led, | ||
517 | int Mode); | ||
518 | |||
519 | extern int SkGeInitAssignRamToQueues( | ||
520 | SK_AC *pAC, | ||
521 | int ActivePort, | ||
522 | SK_BOOL DualNet); | ||
523 | |||
524 | /* | ||
525 | * public functions in skxmac2.c | ||
526 | */ | ||
527 | extern void SkMacRxTxDisable( | ||
528 | SK_AC *pAC, | ||
529 | SK_IOC IoC, | ||
530 | int Port); | ||
531 | |||
532 | extern void SkMacSoftRst( | ||
533 | SK_AC *pAC, | ||
534 | SK_IOC IoC, | ||
535 | int Port); | ||
536 | |||
537 | extern void SkMacHardRst( | ||
538 | SK_AC *pAC, | ||
539 | SK_IOC IoC, | ||
540 | int Port); | ||
541 | |||
542 | extern void SkXmInitMac( | ||
543 | SK_AC *pAC, | ||
544 | SK_IOC IoC, | ||
545 | int Port); | ||
546 | |||
547 | extern void SkGmInitMac( | ||
548 | SK_AC *pAC, | ||
549 | SK_IOC IoC, | ||
550 | int Port); | ||
551 | |||
552 | extern void SkMacInitPhy( | ||
553 | SK_AC *pAC, | ||
554 | SK_IOC IoC, | ||
555 | int Port, | ||
556 | SK_BOOL DoLoop); | ||
557 | |||
558 | extern void SkMacIrqDisable( | ||
559 | SK_AC *pAC, | ||
560 | SK_IOC IoC, | ||
561 | int Port); | ||
562 | |||
563 | extern void SkMacFlushTxFifo( | ||
564 | SK_AC *pAC, | ||
565 | SK_IOC IoC, | ||
566 | int Port); | ||
567 | |||
568 | extern void SkMacIrq( | ||
569 | SK_AC *pAC, | ||
570 | SK_IOC IoC, | ||
571 | int Port); | ||
572 | |||
573 | extern int SkMacAutoNegDone( | ||
574 | SK_AC *pAC, | ||
575 | SK_IOC IoC, | ||
576 | int Port); | ||
577 | |||
578 | extern void SkMacAutoNegLipaPhy( | ||
579 | SK_AC *pAC, | ||
580 | SK_IOC IoC, | ||
581 | int Port, | ||
582 | SK_U16 IStatus); | ||
583 | |||
584 | extern int SkMacRxTxEnable( | ||
585 | SK_AC *pAC, | ||
586 | SK_IOC IoC, | ||
587 | int Port); | ||
588 | |||
589 | extern void SkMacPromiscMode( | ||
590 | SK_AC *pAC, | ||
591 | SK_IOC IoC, | ||
592 | int Port, | ||
593 | SK_BOOL Enable); | ||
594 | |||
595 | extern void SkMacHashing( | ||
596 | SK_AC *pAC, | ||
597 | SK_IOC IoC, | ||
598 | int Port, | ||
599 | SK_BOOL Enable); | ||
600 | |||
601 | extern void SkXmPhyRead( | ||
602 | SK_AC *pAC, | ||
603 | SK_IOC IoC, | ||
604 | int Port, | ||
605 | int Addr, | ||
606 | SK_U16 SK_FAR *pVal); | ||
607 | |||
608 | extern void SkXmPhyWrite( | ||
609 | SK_AC *pAC, | ||
610 | SK_IOC IoC, | ||
611 | int Port, | ||
612 | int Addr, | ||
613 | SK_U16 Val); | ||
614 | |||
615 | extern void SkGmPhyRead( | ||
616 | SK_AC *pAC, | ||
617 | SK_IOC IoC, | ||
618 | int Port, | ||
619 | int Addr, | ||
620 | SK_U16 SK_FAR *pVal); | ||
621 | |||
622 | extern void SkGmPhyWrite( | ||
623 | SK_AC *pAC, | ||
624 | SK_IOC IoC, | ||
625 | int Port, | ||
626 | int Addr, | ||
627 | SK_U16 Val); | ||
628 | |||
629 | extern void SkXmClrExactAddr( | ||
630 | SK_AC *pAC, | ||
631 | SK_IOC IoC, | ||
632 | int Port, | ||
633 | int StartNum, | ||
634 | int StopNum); | ||
635 | |||
636 | extern void SkXmAutoNegLipaXmac( | ||
637 | SK_AC *pAC, | ||
638 | SK_IOC IoC, | ||
639 | int Port, | ||
640 | SK_U16 IStatus); | ||
641 | |||
642 | extern int SkXmUpdateStats( | ||
643 | SK_AC *pAC, | ||
644 | SK_IOC IoC, | ||
645 | unsigned int Port); | ||
646 | |||
647 | extern int SkGmUpdateStats( | ||
648 | SK_AC *pAC, | ||
649 | SK_IOC IoC, | ||
650 | unsigned int Port); | ||
651 | |||
652 | extern int SkXmMacStatistic( | ||
653 | SK_AC *pAC, | ||
654 | SK_IOC IoC, | ||
655 | unsigned int Port, | ||
656 | SK_U16 StatAddr, | ||
657 | SK_U32 SK_FAR *pVal); | ||
658 | |||
659 | extern int SkGmMacStatistic( | ||
660 | SK_AC *pAC, | ||
661 | SK_IOC IoC, | ||
662 | unsigned int Port, | ||
663 | SK_U16 StatAddr, | ||
664 | SK_U32 SK_FAR *pVal); | ||
665 | |||
666 | extern int SkXmResetCounter( | ||
667 | SK_AC *pAC, | ||
668 | SK_IOC IoC, | ||
669 | unsigned int Port); | ||
670 | |||
671 | extern int SkGmResetCounter( | ||
672 | SK_AC *pAC, | ||
673 | SK_IOC IoC, | ||
674 | unsigned int Port); | ||
675 | |||
676 | extern int SkXmOverflowStatus( | ||
677 | SK_AC *pAC, | ||
678 | SK_IOC IoC, | ||
679 | unsigned int Port, | ||
680 | SK_U16 IStatus, | ||
681 | SK_U64 SK_FAR *pStatus); | ||
682 | |||
683 | extern int SkGmOverflowStatus( | ||
684 | SK_AC *pAC, | ||
685 | SK_IOC IoC, | ||
686 | unsigned int Port, | ||
687 | SK_U16 MacStatus, | ||
688 | SK_U64 SK_FAR *pStatus); | ||
689 | |||
690 | extern int SkGmCableDiagStatus( | ||
691 | SK_AC *pAC, | ||
692 | SK_IOC IoC, | ||
693 | int Port, | ||
694 | SK_BOOL StartTest); | ||
695 | |||
696 | #ifdef SK_DIAG | ||
697 | extern void SkGePhyRead( | ||
698 | SK_AC *pAC, | ||
699 | SK_IOC IoC, | ||
700 | int Port, | ||
701 | int Addr, | ||
702 | SK_U16 *pVal); | ||
703 | |||
704 | extern void SkGePhyWrite( | ||
705 | SK_AC *pAC, | ||
706 | SK_IOC IoC, | ||
707 | int Port, | ||
708 | int Addr, | ||
709 | SK_U16 Val); | ||
710 | |||
711 | extern void SkMacSetRxCmd( | ||
712 | SK_AC *pAC, | ||
713 | SK_IOC IoC, | ||
714 | int Port, | ||
715 | int Mode); | ||
716 | extern void SkMacCrcGener( | ||
717 | SK_AC *pAC, | ||
718 | SK_IOC IoC, | ||
719 | int Port, | ||
720 | SK_BOOL Enable); | ||
721 | extern void SkMacTimeStamp( | ||
722 | SK_AC *pAC, | ||
723 | SK_IOC IoC, | ||
724 | int Port, | ||
725 | SK_BOOL Enable); | ||
726 | extern void SkXmSendCont( | ||
727 | SK_AC *pAC, | ||
728 | SK_IOC IoC, | ||
729 | int Port, | ||
730 | SK_BOOL Enable); | ||
731 | #endif /* SK_DIAG */ | ||
732 | |||
733 | #else /* SK_KR_PROTO */ | ||
734 | |||
735 | /* | ||
736 | * public functions in skgeinit.c | ||
737 | */ | ||
738 | extern void SkGePollTxD(); | ||
739 | extern void SkGeYellowLED(); | ||
740 | extern int SkGeCfgSync(); | ||
741 | extern void SkGeLoadLnkSyncCnt(); | ||
742 | extern void SkGeStopPort(); | ||
743 | extern int SkGeInit(); | ||
744 | extern void SkGeDeInit(); | ||
745 | extern int SkGeInitPort(); | ||
746 | extern void SkGeXmitLED(); | ||
747 | extern int SkGeInitAssignRamToQueues(); | ||
748 | |||
749 | /* | ||
750 | * public functions in skxmac2.c | ||
751 | */ | ||
752 | extern void SkMacRxTxDisable(); | ||
753 | extern void SkMacSoftRst(); | ||
754 | extern void SkMacHardRst(); | ||
755 | extern void SkMacInitPhy(); | ||
756 | extern int SkMacRxTxEnable(); | ||
757 | extern void SkMacPromiscMode(); | ||
758 | extern void SkMacHashing(); | ||
759 | extern void SkMacIrqDisable(); | ||
760 | extern void SkMacFlushTxFifo(); | ||
761 | extern void SkMacIrq(); | ||
762 | extern int SkMacAutoNegDone(); | ||
763 | extern void SkMacAutoNegLipaPhy(); | ||
764 | extern void SkXmInitMac(); | ||
765 | extern void SkXmPhyRead(); | ||
766 | extern void SkXmPhyWrite(); | ||
767 | extern void SkGmInitMac(); | ||
768 | extern void SkGmPhyRead(); | ||
769 | extern void SkGmPhyWrite(); | ||
770 | extern void SkXmClrExactAddr(); | ||
771 | extern void SkXmAutoNegLipaXmac(); | ||
772 | extern int SkXmUpdateStats(); | ||
773 | extern int SkGmUpdateStats(); | ||
774 | extern int SkXmMacStatistic(); | ||
775 | extern int SkGmMacStatistic(); | ||
776 | extern int SkXmResetCounter(); | ||
777 | extern int SkGmResetCounter(); | ||
778 | extern int SkXmOverflowStatus(); | ||
779 | extern int SkGmOverflowStatus(); | ||
780 | extern int SkGmCableDiagStatus(); | ||
781 | |||
782 | #ifdef SK_DIAG | ||
783 | extern void SkGePhyRead(); | ||
784 | extern void SkGePhyWrite(); | ||
785 | extern void SkMacSetRxCmd(); | ||
786 | extern void SkMacCrcGener(); | ||
787 | extern void SkMacTimeStamp(); | ||
788 | extern void SkXmSendCont(); | ||
789 | #endif /* SK_DIAG */ | ||
790 | |||
791 | #endif /* SK_KR_PROTO */ | ||
792 | |||
793 | #ifdef __cplusplus | ||
794 | } | ||
795 | #endif /* __cplusplus */ | ||
796 | |||
797 | #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..1ed214ccb253 --- /dev/null +++ b/drivers/net/sk98lin/h/skgepnmi.h | |||
@@ -0,0 +1,962 @@ | |||
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 SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf, | ||
950 | unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); | ||
951 | extern int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf, | ||
952 | unsigned int *pLen, SK_U32 NetIndex); | ||
953 | extern int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf, | ||
954 | unsigned int *pLen, SK_U32 NetIndex); | ||
955 | extern int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf, | ||
956 | unsigned int *pLen, SK_U32 NetIndex); | ||
957 | extern int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, | ||
958 | SK_EVPARA Param); | ||
959 | extern int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf, | ||
960 | unsigned int * pLen, SK_U32 NetIndex); | ||
961 | |||
962 | #endif | ||
diff --git a/drivers/net/sk98lin/h/skgesirq.h b/drivers/net/sk98lin/h/skgesirq.h new file mode 100644 index 000000000000..3eec6274e413 --- /dev/null +++ b/drivers/net/sk98lin/h/skgesirq.h | |||
@@ -0,0 +1,110 @@ | |||
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 SkHWLinkDown(SK_AC *pAC, SK_IOC IoC, int Port); | ||
109 | |||
110 | #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..6a63f4a15de6 --- /dev/null +++ b/drivers/net/sk98lin/h/ski2c.h | |||
@@ -0,0 +1,174 @@ | |||
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 | #ifdef SK_DIAG | ||
166 | extern SK_U32 SkI2cRead(SK_AC *pAC, SK_IOC IoC, int Dev, int Size, int Reg, | ||
167 | int Burst); | ||
168 | #else /* !SK_DIAG */ | ||
169 | extern int SkI2cEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para); | ||
170 | extern void SkI2cWaitIrq(SK_AC *pAC, SK_IOC IoC); | ||
171 | extern void SkI2cIsr(SK_AC *pAC, SK_IOC IoC); | ||
172 | #endif /* !SK_DIAG */ | ||
173 | #endif /* n_SKI2C_H */ | ||
174 | |||
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..fdd9e48e8040 --- /dev/null +++ b/drivers/net/sk98lin/h/skvpd.h | |||
@@ -0,0 +1,248 @@ | |||
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_IN8(pAC,IoC,Addr,pVal) (void)SkPciReadCfgByte(pAC,Addr,pVal) | ||
134 | #define VPD_IN16(pAC,IoC,Addr,pVal) (void)SkPciReadCfgWord(pAC,Addr,pVal) | ||
135 | #define VPD_IN32(pAC,IoC,Addr,pVal) (void)SkPciReadCfgDWord(pAC,Addr,pVal) | ||
136 | #else /* VPD_DO_IO */ | ||
137 | #define VPD_OUT8(pAC,IoC,Addr,Val) SK_OUT8(IoC,PCI_C(Addr),Val) | ||
138 | #define VPD_OUT16(pAC,IoC,Addr,Val) SK_OUT16(IoC,PCI_C(Addr),Val) | ||
139 | #define VPD_IN8(pAC,IoC,Addr,pVal) SK_IN8(IoC,PCI_C(Addr),pVal) | ||
140 | #define VPD_IN16(pAC,IoC,Addr,pVal) SK_IN16(IoC,PCI_C(Addr),pVal) | ||
141 | #define VPD_IN32(pAC,IoC,Addr,pVal) SK_IN32(IoC,PCI_C(Addr),pVal) | ||
142 | #endif /* VPD_DO_IO */ | ||
143 | #else /* SKDIAG */ | ||
144 | #define VPD_OUT8(pAC,Ioc,Addr,Val) { \ | ||
145 | if ((pAC)->DgT.DgUseCfgCycle) \ | ||
146 | SkPciWriteCfgByte(pAC,Addr,Val); \ | ||
147 | else \ | ||
148 | SK_OUT8(pAC,PCI_C(Addr),Val); \ | ||
149 | } | ||
150 | #define VPD_OUT16(pAC,Ioc,Addr,Val) { \ | ||
151 | if ((pAC)->DgT.DgUseCfgCycle) \ | ||
152 | SkPciWriteCfgWord(pAC,Addr,Val); \ | ||
153 | else \ | ||
154 | SK_OUT16(pAC,PCI_C(Addr),Val); \ | ||
155 | } | ||
156 | #define VPD_IN8(pAC,Ioc,Addr,pVal) { \ | ||
157 | if ((pAC)->DgT.DgUseCfgCycle) \ | ||
158 | SkPciReadCfgByte(pAC,Addr,pVal); \ | ||
159 | else \ | ||
160 | SK_IN8(pAC,PCI_C(Addr),pVal); \ | ||
161 | } | ||
162 | #define VPD_IN16(pAC,Ioc,Addr,pVal) { \ | ||
163 | if ((pAC)->DgT.DgUseCfgCycle) \ | ||
164 | SkPciReadCfgWord(pAC,Addr,pVal); \ | ||
165 | else \ | ||
166 | SK_IN16(pAC,PCI_C(Addr),pVal); \ | ||
167 | } | ||
168 | #define VPD_IN32(pAC,Ioc,Addr,pVal) { \ | ||
169 | if ((pAC)->DgT.DgUseCfgCycle) \ | ||
170 | SkPciReadCfgDWord(pAC,Addr,pVal); \ | ||
171 | else \ | ||
172 | SK_IN32(pAC,PCI_C(Addr),pVal); \ | ||
173 | } | ||
174 | #endif /* nSKDIAG */ | ||
175 | |||
176 | /* function prototypes ********************************************************/ | ||
177 | |||
178 | #ifndef SK_KR_PROTO | ||
179 | #ifdef SKDIAG | ||
180 | extern SK_U32 VpdReadDWord( | ||
181 | SK_AC *pAC, | ||
182 | SK_IOC IoC, | ||
183 | int addr); | ||
184 | #endif /* SKDIAG */ | ||
185 | |||
186 | extern SK_VPD_STATUS *VpdStat( | ||
187 | SK_AC *pAC, | ||
188 | SK_IOC IoC); | ||
189 | |||
190 | extern int VpdKeys( | ||
191 | SK_AC *pAC, | ||
192 | SK_IOC IoC, | ||
193 | char *buf, | ||
194 | int *len, | ||
195 | int *elements); | ||
196 | |||
197 | extern int VpdRead( | ||
198 | SK_AC *pAC, | ||
199 | SK_IOC IoC, | ||
200 | const char *key, | ||
201 | char *buf, | ||
202 | int *len); | ||
203 | |||
204 | extern SK_BOOL VpdMayWrite( | ||
205 | char *key); | ||
206 | |||
207 | extern int VpdWrite( | ||
208 | SK_AC *pAC, | ||
209 | SK_IOC IoC, | ||
210 | const char *key, | ||
211 | const char *buf); | ||
212 | |||
213 | extern int VpdDelete( | ||
214 | SK_AC *pAC, | ||
215 | SK_IOC IoC, | ||
216 | char *key); | ||
217 | |||
218 | extern int VpdUpdate( | ||
219 | SK_AC *pAC, | ||
220 | SK_IOC IoC); | ||
221 | |||
222 | #ifdef SKDIAG | ||
223 | extern int VpdReadBlock( | ||
224 | SK_AC *pAC, | ||
225 | SK_IOC IoC, | ||
226 | char *buf, | ||
227 | int addr, | ||
228 | int len); | ||
229 | |||
230 | extern int VpdWriteBlock( | ||
231 | SK_AC *pAC, | ||
232 | SK_IOC IoC, | ||
233 | char *buf, | ||
234 | int addr, | ||
235 | int len); | ||
236 | #endif /* SKDIAG */ | ||
237 | #else /* SK_KR_PROTO */ | ||
238 | extern SK_U32 VpdReadDWord(); | ||
239 | extern SK_VPD_STATUS *VpdStat(); | ||
240 | extern int VpdKeys(); | ||
241 | extern int VpdRead(); | ||
242 | extern SK_BOOL VpdMayWrite(); | ||
243 | extern int VpdWrite(); | ||
244 | extern int VpdDelete(); | ||
245 | extern int VpdUpdate(); | ||
246 | #endif /* SK_KR_PROTO */ | ||
247 | |||
248 | #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..7f8e6d0084c7 --- /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 (7<<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..6e6c56aa6d6f --- /dev/null +++ b/drivers/net/sk98lin/skaddr.c | |||
@@ -0,0 +1,1788 @@ | |||
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 | static int SkAddrGmacMcAdd(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, | ||
91 | SK_MAC_ADDR *pMc, int Flags); | ||
92 | static int SkAddrGmacMcClear(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, | ||
93 | int Flags); | ||
94 | static int SkAddrGmacMcUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber); | ||
95 | static int SkAddrGmacPromiscuousChange(SK_AC *pAC, SK_IOC IoC, | ||
96 | SK_U32 PortNumber, int NewPromMode); | ||
97 | static int SkAddrXmacMcAdd(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, | ||
98 | SK_MAC_ADDR *pMc, int Flags); | ||
99 | static int SkAddrXmacMcClear(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, | ||
100 | int Flags); | ||
101 | static int SkAddrXmacMcUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber); | ||
102 | static int SkAddrXmacPromiscuousChange(SK_AC *pAC, SK_IOC IoC, | ||
103 | SK_U32 PortNumber, int NewPromMode); | ||
104 | |||
105 | /* functions ******************************************************************/ | ||
106 | |||
107 | /****************************************************************************** | ||
108 | * | ||
109 | * SkAddrInit - initialize data, set state to init | ||
110 | * | ||
111 | * Description: | ||
112 | * | ||
113 | * SK_INIT_DATA | ||
114 | * ============ | ||
115 | * | ||
116 | * This routine clears the multicast tables and resets promiscuous mode. | ||
117 | * Some entries are reserved for the "logical MAC address", the | ||
118 | * SK-RLMT multicast address, and the BPDU multicast address. | ||
119 | * | ||
120 | * | ||
121 | * SK_INIT_IO | ||
122 | * ========== | ||
123 | * | ||
124 | * All permanent MAC addresses are read from EPROM. | ||
125 | * If the current MAC addresses are not already set in software, | ||
126 | * they are set to the values of the permanent addresses. | ||
127 | * The current addresses are written to the corresponding MAC. | ||
128 | * | ||
129 | * | ||
130 | * SK_INIT_RUN | ||
131 | * =========== | ||
132 | * | ||
133 | * Nothing. | ||
134 | * | ||
135 | * Context: | ||
136 | * init, pageable | ||
137 | * | ||
138 | * Returns: | ||
139 | * SK_ADDR_SUCCESS | ||
140 | */ | ||
141 | int SkAddrInit( | ||
142 | SK_AC *pAC, /* the adapter context */ | ||
143 | SK_IOC IoC, /* I/O context */ | ||
144 | int Level) /* initialization level */ | ||
145 | { | ||
146 | int j; | ||
147 | SK_U32 i; | ||
148 | SK_U8 *InAddr; | ||
149 | SK_U16 *OutAddr; | ||
150 | SK_ADDR_PORT *pAPort; | ||
151 | |||
152 | switch (Level) { | ||
153 | case SK_INIT_DATA: | ||
154 | SK_MEMSET((char *) &pAC->Addr, (SK_U8) 0, | ||
155 | (SK_U16) sizeof(SK_ADDR)); | ||
156 | |||
157 | for (i = 0; i < SK_MAX_MACS; i++) { | ||
158 | pAPort = &pAC->Addr.Port[i]; | ||
159 | pAPort->PromMode = SK_PROM_MODE_NONE; | ||
160 | |||
161 | pAPort->FirstExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT; | ||
162 | pAPort->FirstExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV; | ||
163 | pAPort->NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT; | ||
164 | pAPort->NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV; | ||
165 | } | ||
166 | #ifdef xDEBUG | ||
167 | for (i = 0; i < SK_MAX_MACS; i++) { | ||
168 | if (pAC->Addr.Port[i].NextExactMatchRlmt < | ||
169 | SK_ADDR_FIRST_MATCH_RLMT) { | ||
170 | Next0[i] |= 4; | ||
171 | } | ||
172 | } | ||
173 | #endif /* DEBUG */ | ||
174 | /* pAC->Addr.InitDone = SK_INIT_DATA; */ | ||
175 | break; | ||
176 | |||
177 | case SK_INIT_IO: | ||
178 | #ifndef SK_NO_RLMT | ||
179 | for (i = 0; i < SK_MAX_NETS; i++) { | ||
180 | pAC->Addr.Net[i].ActivePort = pAC->Rlmt.Net[i].ActivePort; | ||
181 | } | ||
182 | #endif /* !SK_NO_RLMT */ | ||
183 | #ifdef xDEBUG | ||
184 | for (i = 0; i < SK_MAX_MACS; i++) { | ||
185 | if (pAC->Addr.Port[i].NextExactMatchRlmt < | ||
186 | SK_ADDR_FIRST_MATCH_RLMT) { | ||
187 | Next0[i] |= 8; | ||
188 | } | ||
189 | } | ||
190 | #endif /* DEBUG */ | ||
191 | |||
192 | /* Read permanent logical MAC address from Control Register File. */ | ||
193 | for (j = 0; j < SK_MAC_ADDR_LEN; j++) { | ||
194 | InAddr = (SK_U8 *) &pAC->Addr.Net[0].PermanentMacAddress.a[j]; | ||
195 | SK_IN8(IoC, B2_MAC_1 + j, InAddr); | ||
196 | } | ||
197 | |||
198 | if (!pAC->Addr.Net[0].CurrentMacAddressSet) { | ||
199 | /* Set the current logical MAC address to the permanent one. */ | ||
200 | pAC->Addr.Net[0].CurrentMacAddress = | ||
201 | pAC->Addr.Net[0].PermanentMacAddress; | ||
202 | pAC->Addr.Net[0].CurrentMacAddressSet = SK_TRUE; | ||
203 | } | ||
204 | |||
205 | /* Set the current logical MAC address. */ | ||
206 | pAC->Addr.Port[pAC->Addr.Net[0].ActivePort].Exact[0] = | ||
207 | pAC->Addr.Net[0].CurrentMacAddress; | ||
208 | #if SK_MAX_NETS > 1 | ||
209 | /* Set logical MAC address for net 2 to (log | 3). */ | ||
210 | if (!pAC->Addr.Net[1].CurrentMacAddressSet) { | ||
211 | pAC->Addr.Net[1].PermanentMacAddress = | ||
212 | pAC->Addr.Net[0].PermanentMacAddress; | ||
213 | pAC->Addr.Net[1].PermanentMacAddress.a[5] |= 3; | ||
214 | /* Set the current logical MAC address to the permanent one. */ | ||
215 | pAC->Addr.Net[1].CurrentMacAddress = | ||
216 | pAC->Addr.Net[1].PermanentMacAddress; | ||
217 | pAC->Addr.Net[1].CurrentMacAddressSet = SK_TRUE; | ||
218 | } | ||
219 | #endif /* SK_MAX_NETS > 1 */ | ||
220 | |||
221 | #ifdef DEBUG | ||
222 | for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { | ||
223 | SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT, | ||
224 | ("Permanent MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n", | ||
225 | i, | ||
226 | pAC->Addr.Net[i].PermanentMacAddress.a[0], | ||
227 | pAC->Addr.Net[i].PermanentMacAddress.a[1], | ||
228 | pAC->Addr.Net[i].PermanentMacAddress.a[2], | ||
229 | pAC->Addr.Net[i].PermanentMacAddress.a[3], | ||
230 | pAC->Addr.Net[i].PermanentMacAddress.a[4], | ||
231 | pAC->Addr.Net[i].PermanentMacAddress.a[5])) | ||
232 | |||
233 | SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT, | ||
234 | ("Logical MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n", | ||
235 | i, | ||
236 | pAC->Addr.Net[i].CurrentMacAddress.a[0], | ||
237 | pAC->Addr.Net[i].CurrentMacAddress.a[1], | ||
238 | pAC->Addr.Net[i].CurrentMacAddress.a[2], | ||
239 | pAC->Addr.Net[i].CurrentMacAddress.a[3], | ||
240 | pAC->Addr.Net[i].CurrentMacAddress.a[4], | ||
241 | pAC->Addr.Net[i].CurrentMacAddress.a[5])) | ||
242 | } | ||
243 | #endif /* DEBUG */ | ||
244 | |||
245 | for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { | ||
246 | pAPort = &pAC->Addr.Port[i]; | ||
247 | |||
248 | /* Read permanent port addresses from Control Register File. */ | ||
249 | for (j = 0; j < SK_MAC_ADDR_LEN; j++) { | ||
250 | InAddr = (SK_U8 *) &pAPort->PermanentMacAddress.a[j]; | ||
251 | SK_IN8(IoC, B2_MAC_2 + 8 * i + j, InAddr); | ||
252 | } | ||
253 | |||
254 | if (!pAPort->CurrentMacAddressSet) { | ||
255 | /* | ||
256 | * Set the current and previous physical MAC address | ||
257 | * of this port to its permanent MAC address. | ||
258 | */ | ||
259 | pAPort->CurrentMacAddress = pAPort->PermanentMacAddress; | ||
260 | pAPort->PreviousMacAddress = pAPort->PermanentMacAddress; | ||
261 | pAPort->CurrentMacAddressSet = SK_TRUE; | ||
262 | } | ||
263 | |||
264 | /* Set port's current physical MAC address. */ | ||
265 | OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0]; | ||
266 | #ifdef GENESIS | ||
267 | if (pAC->GIni.GIGenesis) { | ||
268 | XM_OUTADDR(IoC, i, XM_SA, OutAddr); | ||
269 | } | ||
270 | #endif /* GENESIS */ | ||
271 | #ifdef YUKON | ||
272 | if (!pAC->GIni.GIGenesis) { | ||
273 | GM_OUTADDR(IoC, i, GM_SRC_ADDR_1L, OutAddr); | ||
274 | } | ||
275 | #endif /* YUKON */ | ||
276 | #ifdef DEBUG | ||
277 | SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT, | ||
278 | ("SkAddrInit: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n", | ||
279 | pAPort->PermanentMacAddress.a[0], | ||
280 | pAPort->PermanentMacAddress.a[1], | ||
281 | pAPort->PermanentMacAddress.a[2], | ||
282 | pAPort->PermanentMacAddress.a[3], | ||
283 | pAPort->PermanentMacAddress.a[4], | ||
284 | pAPort->PermanentMacAddress.a[5])) | ||
285 | |||
286 | SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT, | ||
287 | ("SkAddrInit: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n", | ||
288 | pAPort->CurrentMacAddress.a[0], | ||
289 | pAPort->CurrentMacAddress.a[1], | ||
290 | pAPort->CurrentMacAddress.a[2], | ||
291 | pAPort->CurrentMacAddress.a[3], | ||
292 | pAPort->CurrentMacAddress.a[4], | ||
293 | pAPort->CurrentMacAddress.a[5])) | ||
294 | #endif /* DEBUG */ | ||
295 | } | ||
296 | /* pAC->Addr.InitDone = SK_INIT_IO; */ | ||
297 | break; | ||
298 | |||
299 | case SK_INIT_RUN: | ||
300 | #ifdef xDEBUG | ||
301 | for (i = 0; i < SK_MAX_MACS; i++) { | ||
302 | if (pAC->Addr.Port[i].NextExactMatchRlmt < | ||
303 | SK_ADDR_FIRST_MATCH_RLMT) { | ||
304 | Next0[i] |= 16; | ||
305 | } | ||
306 | } | ||
307 | #endif /* DEBUG */ | ||
308 | |||
309 | /* pAC->Addr.InitDone = SK_INIT_RUN; */ | ||
310 | break; | ||
311 | |||
312 | default: /* error */ | ||
313 | break; | ||
314 | } | ||
315 | |||
316 | return (SK_ADDR_SUCCESS); | ||
317 | |||
318 | } /* SkAddrInit */ | ||
319 | |||
320 | #ifndef SK_SLIM | ||
321 | |||
322 | /****************************************************************************** | ||
323 | * | ||
324 | * SkAddrMcClear - clear the multicast table | ||
325 | * | ||
326 | * Description: | ||
327 | * This routine clears the multicast table. | ||
328 | * | ||
329 | * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated | ||
330 | * immediately. | ||
331 | * | ||
332 | * It calls either SkAddrXmacMcClear or SkAddrGmacMcClear, according | ||
333 | * to the adapter in use. The real work is done there. | ||
334 | * | ||
335 | * Context: | ||
336 | * runtime, pageable | ||
337 | * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY | ||
338 | * may be called after SK_INIT_IO without limitation | ||
339 | * | ||
340 | * Returns: | ||
341 | * SK_ADDR_SUCCESS | ||
342 | * SK_ADDR_ILLEGAL_PORT | ||
343 | */ | ||
344 | int SkAddrMcClear( | ||
345 | SK_AC *pAC, /* adapter context */ | ||
346 | SK_IOC IoC, /* I/O context */ | ||
347 | SK_U32 PortNumber, /* Index of affected port */ | ||
348 | int Flags) /* permanent/non-perm, sw-only */ | ||
349 | { | ||
350 | int ReturnCode; | ||
351 | |||
352 | if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { | ||
353 | return (SK_ADDR_ILLEGAL_PORT); | ||
354 | } | ||
355 | |||
356 | if (pAC->GIni.GIGenesis) { | ||
357 | ReturnCode = SkAddrXmacMcClear(pAC, IoC, PortNumber, Flags); | ||
358 | } | ||
359 | else { | ||
360 | ReturnCode = SkAddrGmacMcClear(pAC, IoC, PortNumber, Flags); | ||
361 | } | ||
362 | |||
363 | return (ReturnCode); | ||
364 | |||
365 | } /* SkAddrMcClear */ | ||
366 | |||
367 | #endif /* !SK_SLIM */ | ||
368 | |||
369 | #ifndef SK_SLIM | ||
370 | |||
371 | /****************************************************************************** | ||
372 | * | ||
373 | * SkAddrXmacMcClear - clear the multicast table | ||
374 | * | ||
375 | * Description: | ||
376 | * This routine clears the multicast table | ||
377 | * (either entry 2 or entries 3-16 and InexactFilter) of the given port. | ||
378 | * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated | ||
379 | * immediately. | ||
380 | * | ||
381 | * Context: | ||
382 | * runtime, pageable | ||
383 | * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY | ||
384 | * may be called after SK_INIT_IO without limitation | ||
385 | * | ||
386 | * Returns: | ||
387 | * SK_ADDR_SUCCESS | ||
388 | * SK_ADDR_ILLEGAL_PORT | ||
389 | */ | ||
390 | static int SkAddrXmacMcClear( | ||
391 | SK_AC *pAC, /* adapter context */ | ||
392 | SK_IOC IoC, /* I/O context */ | ||
393 | SK_U32 PortNumber, /* Index of affected port */ | ||
394 | int Flags) /* permanent/non-perm, sw-only */ | ||
395 | { | ||
396 | int i; | ||
397 | |||
398 | if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */ | ||
399 | |||
400 | /* Clear RLMT multicast addresses. */ | ||
401 | pAC->Addr.Port[PortNumber].NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT; | ||
402 | } | ||
403 | else { /* not permanent => DRV */ | ||
404 | |||
405 | /* Clear InexactFilter */ | ||
406 | for (i = 0; i < 8; i++) { | ||
407 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0; | ||
408 | } | ||
409 | |||
410 | /* Clear DRV multicast addresses. */ | ||
411 | |||
412 | pAC->Addr.Port[PortNumber].NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV; | ||
413 | } | ||
414 | |||
415 | if (!(Flags & SK_MC_SW_ONLY)) { | ||
416 | (void) SkAddrXmacMcUpdate(pAC, IoC, PortNumber); | ||
417 | } | ||
418 | |||
419 | return (SK_ADDR_SUCCESS); | ||
420 | |||
421 | } /* SkAddrXmacMcClear */ | ||
422 | |||
423 | #endif /* !SK_SLIM */ | ||
424 | |||
425 | #ifndef SK_SLIM | ||
426 | |||
427 | /****************************************************************************** | ||
428 | * | ||
429 | * SkAddrGmacMcClear - clear the multicast table | ||
430 | * | ||
431 | * Description: | ||
432 | * This routine clears the multicast hashing table (InexactFilter) | ||
433 | * (either the RLMT or the driver bits) of the given port. | ||
434 | * | ||
435 | * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated | ||
436 | * immediately. | ||
437 | * | ||
438 | * Context: | ||
439 | * runtime, pageable | ||
440 | * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY | ||
441 | * may be called after SK_INIT_IO without limitation | ||
442 | * | ||
443 | * Returns: | ||
444 | * SK_ADDR_SUCCESS | ||
445 | * SK_ADDR_ILLEGAL_PORT | ||
446 | */ | ||
447 | static int SkAddrGmacMcClear( | ||
448 | SK_AC *pAC, /* adapter context */ | ||
449 | SK_IOC IoC, /* I/O context */ | ||
450 | SK_U32 PortNumber, /* Index of affected port */ | ||
451 | int Flags) /* permanent/non-perm, sw-only */ | ||
452 | { | ||
453 | int i; | ||
454 | |||
455 | #ifdef DEBUG | ||
456 | SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
457 | ("GMAC InexactFilter (not cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n", | ||
458 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0], | ||
459 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1], | ||
460 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2], | ||
461 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3], | ||
462 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4], | ||
463 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5], | ||
464 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6], | ||
465 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7])) | ||
466 | #endif /* DEBUG */ | ||
467 | |||
468 | /* Clear InexactFilter */ | ||
469 | for (i = 0; i < 8; i++) { | ||
470 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0; | ||
471 | } | ||
472 | |||
473 | if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */ | ||
474 | |||
475 | /* Copy DRV bits to InexactFilter. */ | ||
476 | for (i = 0; i < 8; i++) { | ||
477 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= | ||
478 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i]; | ||
479 | |||
480 | /* Clear InexactRlmtFilter. */ | ||
481 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i] = 0; | ||
482 | |||
483 | } | ||
484 | } | ||
485 | else { /* not permanent => DRV */ | ||
486 | |||
487 | /* Copy RLMT bits to InexactFilter. */ | ||
488 | for (i = 0; i < 8; i++) { | ||
489 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= | ||
490 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i]; | ||
491 | |||
492 | /* Clear InexactDrvFilter. */ | ||
493 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i] = 0; | ||
494 | } | ||
495 | } | ||
496 | |||
497 | #ifdef DEBUG | ||
498 | SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
499 | ("GMAC InexactFilter (cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n", | ||
500 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0], | ||
501 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1], | ||
502 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2], | ||
503 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3], | ||
504 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4], | ||
505 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5], | ||
506 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6], | ||
507 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7])) | ||
508 | #endif /* DEBUG */ | ||
509 | |||
510 | if (!(Flags & SK_MC_SW_ONLY)) { | ||
511 | (void) SkAddrGmacMcUpdate(pAC, IoC, PortNumber); | ||
512 | } | ||
513 | |||
514 | return (SK_ADDR_SUCCESS); | ||
515 | |||
516 | } /* SkAddrGmacMcClear */ | ||
517 | |||
518 | #ifndef SK_ADDR_CHEAT | ||
519 | |||
520 | /****************************************************************************** | ||
521 | * | ||
522 | * SkXmacMcHash - hash multicast address | ||
523 | * | ||
524 | * Description: | ||
525 | * This routine computes the hash value for a multicast address. | ||
526 | * A CRC32 algorithm is used. | ||
527 | * | ||
528 | * Notes: | ||
529 | * The code was adapted from the XaQti data sheet. | ||
530 | * | ||
531 | * Context: | ||
532 | * runtime, pageable | ||
533 | * | ||
534 | * Returns: | ||
535 | * Hash value of multicast address. | ||
536 | */ | ||
537 | static SK_U32 SkXmacMcHash( | ||
538 | unsigned char *pMc) /* Multicast address */ | ||
539 | { | ||
540 | SK_U32 Idx; | ||
541 | SK_U32 Bit; | ||
542 | SK_U32 Data; | ||
543 | SK_U32 Crc; | ||
544 | |||
545 | Crc = 0xFFFFFFFFUL; | ||
546 | for (Idx = 0; Idx < SK_MAC_ADDR_LEN; Idx++) { | ||
547 | Data = *pMc++; | ||
548 | for (Bit = 0; Bit < 8; Bit++, Data >>= 1) { | ||
549 | Crc = (Crc >> 1) ^ (((Crc ^ Data) & 1) ? XMAC_POLY : 0); | ||
550 | } | ||
551 | } | ||
552 | |||
553 | return (Crc & ((1 << HASH_BITS) - 1)); | ||
554 | |||
555 | } /* SkXmacMcHash */ | ||
556 | |||
557 | |||
558 | /****************************************************************************** | ||
559 | * | ||
560 | * SkGmacMcHash - hash multicast address | ||
561 | * | ||
562 | * Description: | ||
563 | * This routine computes the hash value for a multicast address. | ||
564 | * A CRC16 algorithm is used. | ||
565 | * | ||
566 | * Notes: | ||
567 | * | ||
568 | * | ||
569 | * Context: | ||
570 | * runtime, pageable | ||
571 | * | ||
572 | * Returns: | ||
573 | * Hash value of multicast address. | ||
574 | */ | ||
575 | static SK_U32 SkGmacMcHash( | ||
576 | unsigned char *pMc) /* Multicast address */ | ||
577 | { | ||
578 | SK_U32 Data; | ||
579 | SK_U32 TmpData; | ||
580 | SK_U32 Crc; | ||
581 | int Byte; | ||
582 | int Bit; | ||
583 | |||
584 | Crc = 0xFFFFFFFFUL; | ||
585 | for (Byte = 0; Byte < 6; Byte++) { | ||
586 | /* Get next byte. */ | ||
587 | Data = (SK_U32) pMc[Byte]; | ||
588 | |||
589 | /* Change bit order in byte. */ | ||
590 | TmpData = Data; | ||
591 | for (Bit = 0; Bit < 8; Bit++) { | ||
592 | if (TmpData & 1L) { | ||
593 | Data |= 1L << (7 - Bit); | ||
594 | } | ||
595 | else { | ||
596 | Data &= ~(1L << (7 - Bit)); | ||
597 | } | ||
598 | TmpData >>= 1; | ||
599 | } | ||
600 | |||
601 | Crc ^= (Data << 24); | ||
602 | for (Bit = 0; Bit < 8; Bit++) { | ||
603 | if (Crc & 0x80000000) { | ||
604 | Crc = (Crc << 1) ^ GMAC_POLY; | ||
605 | } | ||
606 | else { | ||
607 | Crc <<= 1; | ||
608 | } | ||
609 | } | ||
610 | } | ||
611 | |||
612 | return (Crc & ((1 << HASH_BITS) - 1)); | ||
613 | |||
614 | } /* SkGmacMcHash */ | ||
615 | |||
616 | #endif /* !SK_ADDR_CHEAT */ | ||
617 | |||
618 | /****************************************************************************** | ||
619 | * | ||
620 | * SkAddrMcAdd - add a multicast address to a port | ||
621 | * | ||
622 | * Description: | ||
623 | * This routine enables reception for a given address on the given port. | ||
624 | * | ||
625 | * It calls either SkAddrXmacMcAdd or SkAddrGmacMcAdd, according to the | ||
626 | * adapter in use. The real work is done there. | ||
627 | * | ||
628 | * Notes: | ||
629 | * The return code is only valid for SK_PROM_MODE_NONE. | ||
630 | * | ||
631 | * Context: | ||
632 | * runtime, pageable | ||
633 | * may be called after SK_INIT_DATA | ||
634 | * | ||
635 | * Returns: | ||
636 | * SK_MC_FILTERING_EXACT | ||
637 | * SK_MC_FILTERING_INEXACT | ||
638 | * SK_MC_ILLEGAL_ADDRESS | ||
639 | * SK_MC_ILLEGAL_PORT | ||
640 | * SK_MC_RLMT_OVERFLOW | ||
641 | */ | ||
642 | int SkAddrMcAdd( | ||
643 | SK_AC *pAC, /* adapter context */ | ||
644 | SK_IOC IoC, /* I/O context */ | ||
645 | SK_U32 PortNumber, /* Port Number */ | ||
646 | SK_MAC_ADDR *pMc, /* multicast address to be added */ | ||
647 | int Flags) /* permanent/non-permanent */ | ||
648 | { | ||
649 | int ReturnCode; | ||
650 | |||
651 | if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { | ||
652 | return (SK_ADDR_ILLEGAL_PORT); | ||
653 | } | ||
654 | |||
655 | if (pAC->GIni.GIGenesis) { | ||
656 | ReturnCode = SkAddrXmacMcAdd(pAC, IoC, PortNumber, pMc, Flags); | ||
657 | } | ||
658 | else { | ||
659 | ReturnCode = SkAddrGmacMcAdd(pAC, IoC, PortNumber, pMc, Flags); | ||
660 | } | ||
661 | |||
662 | return (ReturnCode); | ||
663 | |||
664 | } /* SkAddrMcAdd */ | ||
665 | |||
666 | |||
667 | /****************************************************************************** | ||
668 | * | ||
669 | * SkAddrXmacMcAdd - add a multicast address to a port | ||
670 | * | ||
671 | * Description: | ||
672 | * This routine enables reception for a given address on the given port. | ||
673 | * | ||
674 | * Notes: | ||
675 | * The return code is only valid for SK_PROM_MODE_NONE. | ||
676 | * | ||
677 | * The multicast bit is only checked if there are no free exact match | ||
678 | * entries. | ||
679 | * | ||
680 | * Context: | ||
681 | * runtime, pageable | ||
682 | * may be called after SK_INIT_DATA | ||
683 | * | ||
684 | * Returns: | ||
685 | * SK_MC_FILTERING_EXACT | ||
686 | * SK_MC_FILTERING_INEXACT | ||
687 | * SK_MC_ILLEGAL_ADDRESS | ||
688 | * SK_MC_RLMT_OVERFLOW | ||
689 | */ | ||
690 | static int SkAddrXmacMcAdd( | ||
691 | SK_AC *pAC, /* adapter context */ | ||
692 | SK_IOC IoC, /* I/O context */ | ||
693 | SK_U32 PortNumber, /* Port Number */ | ||
694 | SK_MAC_ADDR *pMc, /* multicast address to be added */ | ||
695 | int Flags) /* permanent/non-permanent */ | ||
696 | { | ||
697 | int i; | ||
698 | SK_U8 Inexact; | ||
699 | #ifndef SK_ADDR_CHEAT | ||
700 | SK_U32 HashBit; | ||
701 | #endif /* !defined(SK_ADDR_CHEAT) */ | ||
702 | |||
703 | if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */ | ||
704 | #ifdef xDEBUG | ||
705 | if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt < | ||
706 | SK_ADDR_FIRST_MATCH_RLMT) { | ||
707 | Next0[PortNumber] |= 1; | ||
708 | return (SK_MC_RLMT_OVERFLOW); | ||
709 | } | ||
710 | #endif /* DEBUG */ | ||
711 | |||
712 | if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt > | ||
713 | SK_ADDR_LAST_MATCH_RLMT) { | ||
714 | return (SK_MC_RLMT_OVERFLOW); | ||
715 | } | ||
716 | |||
717 | /* Set a RLMT multicast address. */ | ||
718 | |||
719 | pAC->Addr.Port[PortNumber].Exact[ | ||
720 | pAC->Addr.Port[PortNumber].NextExactMatchRlmt++] = *pMc; | ||
721 | |||
722 | return (SK_MC_FILTERING_EXACT); | ||
723 | } | ||
724 | |||
725 | #ifdef xDEBUG | ||
726 | if (pAC->Addr.Port[PortNumber].NextExactMatchDrv < | ||
727 | SK_ADDR_FIRST_MATCH_DRV) { | ||
728 | Next0[PortNumber] |= 2; | ||
729 | return (SK_MC_RLMT_OVERFLOW); | ||
730 | } | ||
731 | #endif /* DEBUG */ | ||
732 | |||
733 | if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) { | ||
734 | |||
735 | /* Set exact match entry. */ | ||
736 | pAC->Addr.Port[PortNumber].Exact[ | ||
737 | pAC->Addr.Port[PortNumber].NextExactMatchDrv++] = *pMc; | ||
738 | |||
739 | /* Clear InexactFilter */ | ||
740 | for (i = 0; i < 8; i++) { | ||
741 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0; | ||
742 | } | ||
743 | } | ||
744 | else { | ||
745 | if (!(pMc->a[0] & SK_MC_BIT)) { | ||
746 | /* Hashing only possible with multicast addresses */ | ||
747 | return (SK_MC_ILLEGAL_ADDRESS); | ||
748 | } | ||
749 | #ifndef SK_ADDR_CHEAT | ||
750 | /* Compute hash value of address. */ | ||
751 | HashBit = 63 - SkXmacMcHash(&pMc->a[0]); | ||
752 | |||
753 | /* Add bit to InexactFilter. */ | ||
754 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[HashBit / 8] |= | ||
755 | 1 << (HashBit % 8); | ||
756 | #else /* SK_ADDR_CHEAT */ | ||
757 | /* Set all bits in InexactFilter. */ | ||
758 | for (i = 0; i < 8; i++) { | ||
759 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF; | ||
760 | } | ||
761 | #endif /* SK_ADDR_CHEAT */ | ||
762 | } | ||
763 | |||
764 | for (Inexact = 0, i = 0; i < 8; i++) { | ||
765 | Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i]; | ||
766 | } | ||
767 | |||
768 | if (Inexact == 0 && pAC->Addr.Port[PortNumber].PromMode == 0) { | ||
769 | return (SK_MC_FILTERING_EXACT); | ||
770 | } | ||
771 | else { | ||
772 | return (SK_MC_FILTERING_INEXACT); | ||
773 | } | ||
774 | |||
775 | } /* SkAddrXmacMcAdd */ | ||
776 | |||
777 | |||
778 | /****************************************************************************** | ||
779 | * | ||
780 | * SkAddrGmacMcAdd - add a multicast address to a port | ||
781 | * | ||
782 | * Description: | ||
783 | * This routine enables reception for a given address on the given port. | ||
784 | * | ||
785 | * Notes: | ||
786 | * The return code is only valid for SK_PROM_MODE_NONE. | ||
787 | * | ||
788 | * Context: | ||
789 | * runtime, pageable | ||
790 | * may be called after SK_INIT_DATA | ||
791 | * | ||
792 | * Returns: | ||
793 | * SK_MC_FILTERING_INEXACT | ||
794 | * SK_MC_ILLEGAL_ADDRESS | ||
795 | */ | ||
796 | static int SkAddrGmacMcAdd( | ||
797 | SK_AC *pAC, /* adapter context */ | ||
798 | SK_IOC IoC, /* I/O context */ | ||
799 | SK_U32 PortNumber, /* Port Number */ | ||
800 | SK_MAC_ADDR *pMc, /* multicast address to be added */ | ||
801 | int Flags) /* permanent/non-permanent */ | ||
802 | { | ||
803 | int i; | ||
804 | #ifndef SK_ADDR_CHEAT | ||
805 | SK_U32 HashBit; | ||
806 | #endif /* !defined(SK_ADDR_CHEAT) */ | ||
807 | |||
808 | if (!(pMc->a[0] & SK_MC_BIT)) { | ||
809 | /* Hashing only possible with multicast addresses */ | ||
810 | return (SK_MC_ILLEGAL_ADDRESS); | ||
811 | } | ||
812 | |||
813 | #ifndef SK_ADDR_CHEAT | ||
814 | |||
815 | /* Compute hash value of address. */ | ||
816 | HashBit = SkGmacMcHash(&pMc->a[0]); | ||
817 | |||
818 | if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */ | ||
819 | |||
820 | /* Add bit to InexactRlmtFilter. */ | ||
821 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[HashBit / 8] |= | ||
822 | 1 << (HashBit % 8); | ||
823 | |||
824 | /* Copy bit to InexactFilter. */ | ||
825 | for (i = 0; i < 8; i++) { | ||
826 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= | ||
827 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i]; | ||
828 | } | ||
829 | #ifdef DEBUG | ||
830 | SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
831 | ("GMAC InexactRlmtFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n", | ||
832 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[0], | ||
833 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[1], | ||
834 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[2], | ||
835 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[3], | ||
836 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[4], | ||
837 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[5], | ||
838 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[6], | ||
839 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[7])) | ||
840 | #endif /* DEBUG */ | ||
841 | } | ||
842 | else { /* not permanent => DRV */ | ||
843 | |||
844 | /* Add bit to InexactDrvFilter. */ | ||
845 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[HashBit / 8] |= | ||
846 | 1 << (HashBit % 8); | ||
847 | |||
848 | /* Copy bit to InexactFilter. */ | ||
849 | for (i = 0; i < 8; i++) { | ||
850 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= | ||
851 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i]; | ||
852 | } | ||
853 | #ifdef DEBUG | ||
854 | SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
855 | ("GMAC InexactDrvFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n", | ||
856 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[0], | ||
857 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[1], | ||
858 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[2], | ||
859 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[3], | ||
860 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[4], | ||
861 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[5], | ||
862 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[6], | ||
863 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[7])) | ||
864 | #endif /* DEBUG */ | ||
865 | } | ||
866 | |||
867 | #else /* SK_ADDR_CHEAT */ | ||
868 | |||
869 | /* Set all bits in InexactFilter. */ | ||
870 | for (i = 0; i < 8; i++) { | ||
871 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF; | ||
872 | } | ||
873 | #endif /* SK_ADDR_CHEAT */ | ||
874 | |||
875 | return (SK_MC_FILTERING_INEXACT); | ||
876 | |||
877 | } /* SkAddrGmacMcAdd */ | ||
878 | |||
879 | #endif /* !SK_SLIM */ | ||
880 | |||
881 | /****************************************************************************** | ||
882 | * | ||
883 | * SkAddrMcUpdate - update the HW MC address table and set the MAC address | ||
884 | * | ||
885 | * Description: | ||
886 | * This routine enables reception of the addresses contained in a local | ||
887 | * table for a given port. | ||
888 | * It also programs the port's current physical MAC address. | ||
889 | * | ||
890 | * It calls either SkAddrXmacMcUpdate or SkAddrGmacMcUpdate, according | ||
891 | * to the adapter in use. The real work is done there. | ||
892 | * | ||
893 | * Notes: | ||
894 | * The return code is only valid for SK_PROM_MODE_NONE. | ||
895 | * | ||
896 | * Context: | ||
897 | * runtime, pageable | ||
898 | * may be called after SK_INIT_IO | ||
899 | * | ||
900 | * Returns: | ||
901 | * SK_MC_FILTERING_EXACT | ||
902 | * SK_MC_FILTERING_INEXACT | ||
903 | * SK_ADDR_ILLEGAL_PORT | ||
904 | */ | ||
905 | int SkAddrMcUpdate( | ||
906 | SK_AC *pAC, /* adapter context */ | ||
907 | SK_IOC IoC, /* I/O context */ | ||
908 | SK_U32 PortNumber) /* Port Number */ | ||
909 | { | ||
910 | int ReturnCode = 0; | ||
911 | #if (!defined(SK_SLIM) || defined(DEBUG)) | ||
912 | if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { | ||
913 | return (SK_ADDR_ILLEGAL_PORT); | ||
914 | } | ||
915 | #endif /* !SK_SLIM || DEBUG */ | ||
916 | |||
917 | #ifdef GENESIS | ||
918 | if (pAC->GIni.GIGenesis) { | ||
919 | ReturnCode = SkAddrXmacMcUpdate(pAC, IoC, PortNumber); | ||
920 | } | ||
921 | #endif /* GENESIS */ | ||
922 | #ifdef YUKON | ||
923 | if (!pAC->GIni.GIGenesis) { | ||
924 | ReturnCode = SkAddrGmacMcUpdate(pAC, IoC, PortNumber); | ||
925 | } | ||
926 | #endif /* YUKON */ | ||
927 | return (ReturnCode); | ||
928 | |||
929 | } /* SkAddrMcUpdate */ | ||
930 | |||
931 | |||
932 | #ifdef GENESIS | ||
933 | |||
934 | /****************************************************************************** | ||
935 | * | ||
936 | * SkAddrXmacMcUpdate - update the HW MC address table and set the MAC address | ||
937 | * | ||
938 | * Description: | ||
939 | * This routine enables reception of the addresses contained in a local | ||
940 | * table for a given port. | ||
941 | * It also programs the port's current physical MAC address. | ||
942 | * | ||
943 | * Notes: | ||
944 | * The return code is only valid for SK_PROM_MODE_NONE. | ||
945 | * | ||
946 | * Context: | ||
947 | * runtime, pageable | ||
948 | * may be called after SK_INIT_IO | ||
949 | * | ||
950 | * Returns: | ||
951 | * SK_MC_FILTERING_EXACT | ||
952 | * SK_MC_FILTERING_INEXACT | ||
953 | * SK_ADDR_ILLEGAL_PORT | ||
954 | */ | ||
955 | static int SkAddrXmacMcUpdate( | ||
956 | SK_AC *pAC, /* adapter context */ | ||
957 | SK_IOC IoC, /* I/O context */ | ||
958 | SK_U32 PortNumber) /* Port Number */ | ||
959 | { | ||
960 | SK_U32 i; | ||
961 | SK_U8 Inexact; | ||
962 | SK_U16 *OutAddr; | ||
963 | SK_ADDR_PORT *pAPort; | ||
964 | |||
965 | SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
966 | ("SkAddrXmacMcUpdate on Port %u.\n", PortNumber)) | ||
967 | |||
968 | pAPort = &pAC->Addr.Port[PortNumber]; | ||
969 | |||
970 | #ifdef DEBUG | ||
971 | SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
972 | ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber])) | ||
973 | #endif /* DEBUG */ | ||
974 | |||
975 | /* Start with 0 to also program the logical MAC address. */ | ||
976 | for (i = 0; i < pAPort->NextExactMatchRlmt; i++) { | ||
977 | /* Set exact match address i on XMAC */ | ||
978 | OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0]; | ||
979 | XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr); | ||
980 | } | ||
981 | |||
982 | /* Clear other permanent exact match addresses on XMAC */ | ||
983 | if (pAPort->NextExactMatchRlmt <= SK_ADDR_LAST_MATCH_RLMT) { | ||
984 | |||
985 | SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchRlmt, | ||
986 | SK_ADDR_LAST_MATCH_RLMT); | ||
987 | } | ||
988 | |||
989 | for (i = pAPort->FirstExactMatchDrv; i < pAPort->NextExactMatchDrv; i++) { | ||
990 | OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0]; | ||
991 | XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr); | ||
992 | } | ||
993 | |||
994 | /* Clear other non-permanent exact match addresses on XMAC */ | ||
995 | if (pAPort->NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) { | ||
996 | |||
997 | SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchDrv, | ||
998 | SK_ADDR_LAST_MATCH_DRV); | ||
999 | } | ||
1000 | |||
1001 | for (Inexact = 0, i = 0; i < 8; i++) { | ||
1002 | Inexact |= pAPort->InexactFilter.Bytes[i]; | ||
1003 | } | ||
1004 | |||
1005 | if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) { | ||
1006 | |||
1007 | /* Set all bits in 64-bit hash register. */ | ||
1008 | XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash); | ||
1009 | |||
1010 | /* Enable Hashing */ | ||
1011 | SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); | ||
1012 | } | ||
1013 | else if (Inexact != 0) { | ||
1014 | |||
1015 | /* Set 64-bit hash register to InexactFilter. */ | ||
1016 | XM_OUTHASH(IoC, PortNumber, XM_HSM, &pAPort->InexactFilter.Bytes[0]); | ||
1017 | |||
1018 | /* Enable Hashing */ | ||
1019 | SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); | ||
1020 | } | ||
1021 | else { | ||
1022 | /* Disable Hashing */ | ||
1023 | SkMacHashing(pAC, IoC, (int) PortNumber, SK_FALSE); | ||
1024 | } | ||
1025 | |||
1026 | if (pAPort->PromMode != SK_PROM_MODE_NONE) { | ||
1027 | (void) SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode); | ||
1028 | } | ||
1029 | |||
1030 | /* Set port's current physical MAC address. */ | ||
1031 | OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0]; | ||
1032 | |||
1033 | XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr); | ||
1034 | |||
1035 | #ifdef xDEBUG | ||
1036 | for (i = 0; i < pAPort->NextExactMatchRlmt; i++) { | ||
1037 | SK_U8 InAddr8[6]; | ||
1038 | SK_U16 *InAddr; | ||
1039 | |||
1040 | /* Get exact match address i from port PortNumber. */ | ||
1041 | InAddr = (SK_U16 *) &InAddr8[0]; | ||
1042 | |||
1043 | XM_INADDR(IoC, PortNumber, XM_EXM(i), InAddr); | ||
1044 | |||
1045 | SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
1046 | ("SkAddrXmacMcUpdate: MC address %d on Port %u: ", | ||
1047 | "%02x %02x %02x %02x %02x %02x -- %02x %02x %02x %02x %02x %02x\n", | ||
1048 | i, | ||
1049 | PortNumber, | ||
1050 | InAddr8[0], | ||
1051 | InAddr8[1], | ||
1052 | InAddr8[2], | ||
1053 | InAddr8[3], | ||
1054 | InAddr8[4], | ||
1055 | InAddr8[5], | ||
1056 | pAPort->Exact[i].a[0], | ||
1057 | pAPort->Exact[i].a[1], | ||
1058 | pAPort->Exact[i].a[2], | ||
1059 | pAPort->Exact[i].a[3], | ||
1060 | pAPort->Exact[i].a[4], | ||
1061 | pAPort->Exact[i].a[5])) | ||
1062 | } | ||
1063 | #endif /* DEBUG */ | ||
1064 | |||
1065 | /* Determine return value. */ | ||
1066 | if (Inexact == 0 && pAPort->PromMode == 0) { | ||
1067 | return (SK_MC_FILTERING_EXACT); | ||
1068 | } | ||
1069 | else { | ||
1070 | return (SK_MC_FILTERING_INEXACT); | ||
1071 | } | ||
1072 | |||
1073 | } /* SkAddrXmacMcUpdate */ | ||
1074 | |||
1075 | #endif /* GENESIS */ | ||
1076 | |||
1077 | #ifdef YUKON | ||
1078 | |||
1079 | /****************************************************************************** | ||
1080 | * | ||
1081 | * SkAddrGmacMcUpdate - update the HW MC address table and set the MAC address | ||
1082 | * | ||
1083 | * Description: | ||
1084 | * This routine enables reception of the addresses contained in a local | ||
1085 | * table for a given port. | ||
1086 | * It also programs the port's current physical MAC address. | ||
1087 | * | ||
1088 | * Notes: | ||
1089 | * The return code is only valid for SK_PROM_MODE_NONE. | ||
1090 | * | ||
1091 | * Context: | ||
1092 | * runtime, pageable | ||
1093 | * may be called after SK_INIT_IO | ||
1094 | * | ||
1095 | * Returns: | ||
1096 | * SK_MC_FILTERING_EXACT | ||
1097 | * SK_MC_FILTERING_INEXACT | ||
1098 | * SK_ADDR_ILLEGAL_PORT | ||
1099 | */ | ||
1100 | static int SkAddrGmacMcUpdate( | ||
1101 | SK_AC *pAC, /* adapter context */ | ||
1102 | SK_IOC IoC, /* I/O context */ | ||
1103 | SK_U32 PortNumber) /* Port Number */ | ||
1104 | { | ||
1105 | #ifndef SK_SLIM | ||
1106 | SK_U32 i; | ||
1107 | SK_U8 Inexact; | ||
1108 | #endif /* not SK_SLIM */ | ||
1109 | SK_U16 *OutAddr; | ||
1110 | SK_ADDR_PORT *pAPort; | ||
1111 | |||
1112 | SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
1113 | ("SkAddrGmacMcUpdate on Port %u.\n", PortNumber)) | ||
1114 | |||
1115 | pAPort = &pAC->Addr.Port[PortNumber]; | ||
1116 | |||
1117 | #ifdef DEBUG | ||
1118 | SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
1119 | ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber])) | ||
1120 | #endif /* DEBUG */ | ||
1121 | |||
1122 | #ifndef SK_SLIM | ||
1123 | for (Inexact = 0, i = 0; i < 8; i++) { | ||
1124 | Inexact |= pAPort->InexactFilter.Bytes[i]; | ||
1125 | } | ||
1126 | |||
1127 | /* Set 64-bit hash register to InexactFilter. */ | ||
1128 | GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, | ||
1129 | &pAPort->InexactFilter.Bytes[0]); | ||
1130 | |||
1131 | if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) { | ||
1132 | |||
1133 | /* Set all bits in 64-bit hash register. */ | ||
1134 | GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash); | ||
1135 | |||
1136 | /* Enable Hashing */ | ||
1137 | SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); | ||
1138 | } | ||
1139 | else { | ||
1140 | /* Enable Hashing. */ | ||
1141 | SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); | ||
1142 | } | ||
1143 | |||
1144 | if (pAPort->PromMode != SK_PROM_MODE_NONE) { | ||
1145 | (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode); | ||
1146 | } | ||
1147 | #else /* SK_SLIM */ | ||
1148 | |||
1149 | /* Set all bits in 64-bit hash register. */ | ||
1150 | GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash); | ||
1151 | |||
1152 | /* Enable Hashing */ | ||
1153 | SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); | ||
1154 | |||
1155 | (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode); | ||
1156 | |||
1157 | #endif /* SK_SLIM */ | ||
1158 | |||
1159 | /* Set port's current physical MAC address. */ | ||
1160 | OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0]; | ||
1161 | GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr); | ||
1162 | |||
1163 | /* Set port's current logical MAC address. */ | ||
1164 | OutAddr = (SK_U16 *) &pAPort->Exact[0].a[0]; | ||
1165 | GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_2L, OutAddr); | ||
1166 | |||
1167 | #ifdef DEBUG | ||
1168 | SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
1169 | ("SkAddrGmacMcUpdate: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n", | ||
1170 | pAPort->Exact[0].a[0], | ||
1171 | pAPort->Exact[0].a[1], | ||
1172 | pAPort->Exact[0].a[2], | ||
1173 | pAPort->Exact[0].a[3], | ||
1174 | pAPort->Exact[0].a[4], | ||
1175 | pAPort->Exact[0].a[5])) | ||
1176 | |||
1177 | SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
1178 | ("SkAddrGmacMcUpdate: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n", | ||
1179 | pAPort->CurrentMacAddress.a[0], | ||
1180 | pAPort->CurrentMacAddress.a[1], | ||
1181 | pAPort->CurrentMacAddress.a[2], | ||
1182 | pAPort->CurrentMacAddress.a[3], | ||
1183 | pAPort->CurrentMacAddress.a[4], | ||
1184 | pAPort->CurrentMacAddress.a[5])) | ||
1185 | #endif /* DEBUG */ | ||
1186 | |||
1187 | #ifndef SK_SLIM | ||
1188 | /* Determine return value. */ | ||
1189 | if (Inexact == 0 && pAPort->PromMode == 0) { | ||
1190 | return (SK_MC_FILTERING_EXACT); | ||
1191 | } | ||
1192 | else { | ||
1193 | return (SK_MC_FILTERING_INEXACT); | ||
1194 | } | ||
1195 | #else /* SK_SLIM */ | ||
1196 | return (SK_MC_FILTERING_INEXACT); | ||
1197 | #endif /* SK_SLIM */ | ||
1198 | |||
1199 | } /* SkAddrGmacMcUpdate */ | ||
1200 | |||
1201 | #endif /* YUKON */ | ||
1202 | |||
1203 | #ifndef SK_NO_MAO | ||
1204 | |||
1205 | /****************************************************************************** | ||
1206 | * | ||
1207 | * SkAddrOverride - override a port's MAC address | ||
1208 | * | ||
1209 | * Description: | ||
1210 | * This routine overrides the MAC address of one port. | ||
1211 | * | ||
1212 | * Context: | ||
1213 | * runtime, pageable | ||
1214 | * may be called after SK_INIT_IO | ||
1215 | * | ||
1216 | * Returns: | ||
1217 | * SK_ADDR_SUCCESS if successful. | ||
1218 | * SK_ADDR_DUPLICATE_ADDRESS if duplicate MAC address. | ||
1219 | * SK_ADDR_MULTICAST_ADDRESS if multicast or broadcast address. | ||
1220 | * SK_ADDR_TOO_EARLY if SK_INIT_IO was not executed before. | ||
1221 | */ | ||
1222 | int SkAddrOverride( | ||
1223 | SK_AC *pAC, /* adapter context */ | ||
1224 | SK_IOC IoC, /* I/O context */ | ||
1225 | SK_U32 PortNumber, /* Port Number */ | ||
1226 | SK_MAC_ADDR SK_FAR *pNewAddr, /* new MAC address */ | ||
1227 | int Flags) /* logical/physical MAC address */ | ||
1228 | { | ||
1229 | #ifndef SK_NO_RLMT | ||
1230 | SK_EVPARA Para; | ||
1231 | #endif /* !SK_NO_RLMT */ | ||
1232 | SK_U32 NetNumber; | ||
1233 | SK_U32 i; | ||
1234 | SK_U16 SK_FAR *OutAddr; | ||
1235 | |||
1236 | #ifndef SK_NO_RLMT | ||
1237 | NetNumber = pAC->Rlmt.Port[PortNumber].Net->NetNumber; | ||
1238 | #else | ||
1239 | NetNumber = 0; | ||
1240 | #endif /* SK_NO_RLMT */ | ||
1241 | #if (!defined(SK_SLIM) || defined(DEBUG)) | ||
1242 | if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { | ||
1243 | return (SK_ADDR_ILLEGAL_PORT); | ||
1244 | } | ||
1245 | #endif /* !SK_SLIM || DEBUG */ | ||
1246 | if (pNewAddr != NULL && (pNewAddr->a[0] & SK_MC_BIT) != 0) { | ||
1247 | return (SK_ADDR_MULTICAST_ADDRESS); | ||
1248 | } | ||
1249 | |||
1250 | if (!pAC->Addr.Net[NetNumber].CurrentMacAddressSet) { | ||
1251 | return (SK_ADDR_TOO_EARLY); | ||
1252 | } | ||
1253 | |||
1254 | if (Flags & SK_ADDR_SET_LOGICAL) { /* Activate logical MAC address. */ | ||
1255 | /* Parameter *pNewAddr is ignored. */ | ||
1256 | for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { | ||
1257 | if (!pAC->Addr.Port[i].CurrentMacAddressSet) { | ||
1258 | return (SK_ADDR_TOO_EARLY); | ||
1259 | } | ||
1260 | } | ||
1261 | #ifndef SK_NO_RLMT | ||
1262 | /* Set PortNumber to number of net's active port. */ | ||
1263 | PortNumber = pAC->Rlmt.Net[NetNumber]. | ||
1264 | Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber; | ||
1265 | #endif /* !SK_NO_RLMT */ | ||
1266 | pAC->Addr.Port[PortNumber].Exact[0] = | ||
1267 | pAC->Addr.Net[NetNumber].CurrentMacAddress; | ||
1268 | |||
1269 | /* Write address to first exact match entry of active port. */ | ||
1270 | (void) SkAddrMcUpdate(pAC, IoC, PortNumber); | ||
1271 | } | ||
1272 | else if (Flags & SK_ADDR_CLEAR_LOGICAL) { | ||
1273 | /* Deactivate logical MAC address. */ | ||
1274 | /* Parameter *pNewAddr is ignored. */ | ||
1275 | for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { | ||
1276 | if (!pAC->Addr.Port[i].CurrentMacAddressSet) { | ||
1277 | return (SK_ADDR_TOO_EARLY); | ||
1278 | } | ||
1279 | } | ||
1280 | #ifndef SK_NO_RLMT | ||
1281 | /* Set PortNumber to number of net's active port. */ | ||
1282 | PortNumber = pAC->Rlmt.Net[NetNumber]. | ||
1283 | Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber; | ||
1284 | #endif /* !SK_NO_RLMT */ | ||
1285 | for (i = 0; i < SK_MAC_ADDR_LEN; i++ ) { | ||
1286 | pAC->Addr.Port[PortNumber].Exact[0].a[i] = 0; | ||
1287 | } | ||
1288 | |||
1289 | /* Write address to first exact match entry of active port. */ | ||
1290 | (void) SkAddrMcUpdate(pAC, IoC, PortNumber); | ||
1291 | } | ||
1292 | else if (Flags & SK_ADDR_PHYSICAL_ADDRESS) { /* Physical MAC address. */ | ||
1293 | if (SK_ADDR_EQUAL(pNewAddr->a, | ||
1294 | pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) { | ||
1295 | return (SK_ADDR_DUPLICATE_ADDRESS); | ||
1296 | } | ||
1297 | |||
1298 | for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { | ||
1299 | if (!pAC->Addr.Port[i].CurrentMacAddressSet) { | ||
1300 | return (SK_ADDR_TOO_EARLY); | ||
1301 | } | ||
1302 | |||
1303 | if (SK_ADDR_EQUAL(pNewAddr->a, | ||
1304 | pAC->Addr.Port[i].CurrentMacAddress.a)) { | ||
1305 | if (i == PortNumber) { | ||
1306 | return (SK_ADDR_SUCCESS); | ||
1307 | } | ||
1308 | else { | ||
1309 | return (SK_ADDR_DUPLICATE_ADDRESS); | ||
1310 | } | ||
1311 | } | ||
1312 | } | ||
1313 | |||
1314 | pAC->Addr.Port[PortNumber].PreviousMacAddress = | ||
1315 | pAC->Addr.Port[PortNumber].CurrentMacAddress; | ||
1316 | pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr; | ||
1317 | |||
1318 | /* Change port's physical MAC address. */ | ||
1319 | OutAddr = (SK_U16 SK_FAR *) pNewAddr; | ||
1320 | #ifdef GENESIS | ||
1321 | if (pAC->GIni.GIGenesis) { | ||
1322 | XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr); | ||
1323 | } | ||
1324 | #endif /* GENESIS */ | ||
1325 | #ifdef YUKON | ||
1326 | if (!pAC->GIni.GIGenesis) { | ||
1327 | GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr); | ||
1328 | } | ||
1329 | #endif /* YUKON */ | ||
1330 | |||
1331 | #ifndef SK_NO_RLMT | ||
1332 | /* Report address change to RLMT. */ | ||
1333 | Para.Para32[0] = PortNumber; | ||
1334 | Para.Para32[0] = -1; | ||
1335 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para); | ||
1336 | #endif /* !SK_NO_RLMT */ | ||
1337 | } | ||
1338 | else { /* Logical MAC address. */ | ||
1339 | if (SK_ADDR_EQUAL(pNewAddr->a, | ||
1340 | pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) { | ||
1341 | return (SK_ADDR_SUCCESS); | ||
1342 | } | ||
1343 | |||
1344 | for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { | ||
1345 | if (!pAC->Addr.Port[i].CurrentMacAddressSet) { | ||
1346 | return (SK_ADDR_TOO_EARLY); | ||
1347 | } | ||
1348 | |||
1349 | if (SK_ADDR_EQUAL(pNewAddr->a, | ||
1350 | pAC->Addr.Port[i].CurrentMacAddress.a)) { | ||
1351 | return (SK_ADDR_DUPLICATE_ADDRESS); | ||
1352 | } | ||
1353 | } | ||
1354 | |||
1355 | /* | ||
1356 | * In case that the physical and the logical MAC addresses are equal | ||
1357 | * we must also change the physical MAC address here. | ||
1358 | * In this case we have an adapter which initially was programmed with | ||
1359 | * two identical MAC addresses. | ||
1360 | */ | ||
1361 | if (SK_ADDR_EQUAL(pAC->Addr.Port[PortNumber].CurrentMacAddress.a, | ||
1362 | pAC->Addr.Port[PortNumber].Exact[0].a)) { | ||
1363 | |||
1364 | pAC->Addr.Port[PortNumber].PreviousMacAddress = | ||
1365 | pAC->Addr.Port[PortNumber].CurrentMacAddress; | ||
1366 | pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr; | ||
1367 | |||
1368 | #ifndef SK_NO_RLMT | ||
1369 | /* Report address change to RLMT. */ | ||
1370 | Para.Para32[0] = PortNumber; | ||
1371 | Para.Para32[0] = -1; | ||
1372 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para); | ||
1373 | #endif /* !SK_NO_RLMT */ | ||
1374 | } | ||
1375 | |||
1376 | #ifndef SK_NO_RLMT | ||
1377 | /* Set PortNumber to number of net's active port. */ | ||
1378 | PortNumber = pAC->Rlmt.Net[NetNumber]. | ||
1379 | Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber; | ||
1380 | #endif /* !SK_NO_RLMT */ | ||
1381 | pAC->Addr.Net[NetNumber].CurrentMacAddress = *pNewAddr; | ||
1382 | pAC->Addr.Port[PortNumber].Exact[0] = *pNewAddr; | ||
1383 | #ifdef DEBUG | ||
1384 | SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
1385 | ("SkAddrOverride: Permanent MAC Address: %02X %02X %02X %02X %02X %02X\n", | ||
1386 | pAC->Addr.Net[NetNumber].PermanentMacAddress.a[0], | ||
1387 | pAC->Addr.Net[NetNumber].PermanentMacAddress.a[1], | ||
1388 | pAC->Addr.Net[NetNumber].PermanentMacAddress.a[2], | ||
1389 | pAC->Addr.Net[NetNumber].PermanentMacAddress.a[3], | ||
1390 | pAC->Addr.Net[NetNumber].PermanentMacAddress.a[4], | ||
1391 | pAC->Addr.Net[NetNumber].PermanentMacAddress.a[5])) | ||
1392 | |||
1393 | SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
1394 | ("SkAddrOverride: New logical MAC Address: %02X %02X %02X %02X %02X %02X\n", | ||
1395 | pAC->Addr.Net[NetNumber].CurrentMacAddress.a[0], | ||
1396 | pAC->Addr.Net[NetNumber].CurrentMacAddress.a[1], | ||
1397 | pAC->Addr.Net[NetNumber].CurrentMacAddress.a[2], | ||
1398 | pAC->Addr.Net[NetNumber].CurrentMacAddress.a[3], | ||
1399 | pAC->Addr.Net[NetNumber].CurrentMacAddress.a[4], | ||
1400 | pAC->Addr.Net[NetNumber].CurrentMacAddress.a[5])) | ||
1401 | #endif /* DEBUG */ | ||
1402 | |||
1403 | /* Write address to first exact match entry of active port. */ | ||
1404 | (void) SkAddrMcUpdate(pAC, IoC, PortNumber); | ||
1405 | } | ||
1406 | |||
1407 | return (SK_ADDR_SUCCESS); | ||
1408 | |||
1409 | } /* SkAddrOverride */ | ||
1410 | |||
1411 | |||
1412 | #endif /* SK_NO_MAO */ | ||
1413 | |||
1414 | /****************************************************************************** | ||
1415 | * | ||
1416 | * SkAddrPromiscuousChange - set promiscuous mode for given port | ||
1417 | * | ||
1418 | * Description: | ||
1419 | * This routine manages promiscuous mode: | ||
1420 | * - none | ||
1421 | * - all LLC frames | ||
1422 | * - all MC frames | ||
1423 | * | ||
1424 | * It calls either SkAddrXmacPromiscuousChange or | ||
1425 | * SkAddrGmacPromiscuousChange, according to the adapter in use. | ||
1426 | * The real work is done there. | ||
1427 | * | ||
1428 | * Context: | ||
1429 | * runtime, pageable | ||
1430 | * may be called after SK_INIT_IO | ||
1431 | * | ||
1432 | * Returns: | ||
1433 | * SK_ADDR_SUCCESS | ||
1434 | * SK_ADDR_ILLEGAL_PORT | ||
1435 | */ | ||
1436 | int SkAddrPromiscuousChange( | ||
1437 | SK_AC *pAC, /* adapter context */ | ||
1438 | SK_IOC IoC, /* I/O context */ | ||
1439 | SK_U32 PortNumber, /* port whose promiscuous mode changes */ | ||
1440 | int NewPromMode) /* new promiscuous mode */ | ||
1441 | { | ||
1442 | int ReturnCode = 0; | ||
1443 | #if (!defined(SK_SLIM) || defined(DEBUG)) | ||
1444 | if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { | ||
1445 | return (SK_ADDR_ILLEGAL_PORT); | ||
1446 | } | ||
1447 | #endif /* !SK_SLIM || DEBUG */ | ||
1448 | |||
1449 | #ifdef GENESIS | ||
1450 | if (pAC->GIni.GIGenesis) { | ||
1451 | ReturnCode = | ||
1452 | SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode); | ||
1453 | } | ||
1454 | #endif /* GENESIS */ | ||
1455 | #ifdef YUKON | ||
1456 | if (!pAC->GIni.GIGenesis) { | ||
1457 | ReturnCode = | ||
1458 | SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode); | ||
1459 | } | ||
1460 | #endif /* YUKON */ | ||
1461 | |||
1462 | return (ReturnCode); | ||
1463 | |||
1464 | } /* SkAddrPromiscuousChange */ | ||
1465 | |||
1466 | #ifdef GENESIS | ||
1467 | |||
1468 | /****************************************************************************** | ||
1469 | * | ||
1470 | * SkAddrXmacPromiscuousChange - set promiscuous mode for given port | ||
1471 | * | ||
1472 | * Description: | ||
1473 | * This routine manages promiscuous mode: | ||
1474 | * - none | ||
1475 | * - all LLC frames | ||
1476 | * - all MC frames | ||
1477 | * | ||
1478 | * Context: | ||
1479 | * runtime, pageable | ||
1480 | * may be called after SK_INIT_IO | ||
1481 | * | ||
1482 | * Returns: | ||
1483 | * SK_ADDR_SUCCESS | ||
1484 | * SK_ADDR_ILLEGAL_PORT | ||
1485 | */ | ||
1486 | static int SkAddrXmacPromiscuousChange( | ||
1487 | SK_AC *pAC, /* adapter context */ | ||
1488 | SK_IOC IoC, /* I/O context */ | ||
1489 | SK_U32 PortNumber, /* port whose promiscuous mode changes */ | ||
1490 | int NewPromMode) /* new promiscuous mode */ | ||
1491 | { | ||
1492 | int i; | ||
1493 | SK_BOOL InexactModeBit; | ||
1494 | SK_U8 Inexact; | ||
1495 | SK_U8 HwInexact; | ||
1496 | SK_FILTER64 HwInexactFilter; | ||
1497 | SK_U16 LoMode; /* Lower 16 bits of XMAC Mode Register. */ | ||
1498 | int CurPromMode = SK_PROM_MODE_NONE; | ||
1499 | |||
1500 | /* Read CurPromMode from Hardware. */ | ||
1501 | XM_IN16(IoC, PortNumber, XM_MODE, &LoMode); | ||
1502 | |||
1503 | if ((LoMode & XM_MD_ENA_PROM) != 0) { | ||
1504 | /* Promiscuous mode! */ | ||
1505 | CurPromMode |= SK_PROM_MODE_LLC; | ||
1506 | } | ||
1507 | |||
1508 | for (Inexact = 0xFF, i = 0; i < 8; i++) { | ||
1509 | Inexact &= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i]; | ||
1510 | } | ||
1511 | if (Inexact == 0xFF) { | ||
1512 | CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC); | ||
1513 | } | ||
1514 | else { | ||
1515 | /* Get InexactModeBit (bit XM_MD_ENA_HASH in mode register) */ | ||
1516 | XM_IN16(IoC, PortNumber, XM_MODE, &LoMode); | ||
1517 | |||
1518 | InexactModeBit = (LoMode & XM_MD_ENA_HASH) != 0; | ||
1519 | |||
1520 | /* Read 64-bit hash register from XMAC */ | ||
1521 | XM_INHASH(IoC, PortNumber, XM_HSM, &HwInexactFilter.Bytes[0]); | ||
1522 | |||
1523 | for (HwInexact = 0xFF, i = 0; i < 8; i++) { | ||
1524 | HwInexact &= HwInexactFilter.Bytes[i]; | ||
1525 | } | ||
1526 | |||
1527 | if (InexactModeBit && (HwInexact == 0xFF)) { | ||
1528 | CurPromMode |= SK_PROM_MODE_ALL_MC; | ||
1529 | } | ||
1530 | } | ||
1531 | |||
1532 | pAC->Addr.Port[PortNumber].PromMode = NewPromMode; | ||
1533 | |||
1534 | if (NewPromMode == CurPromMode) { | ||
1535 | return (SK_ADDR_SUCCESS); | ||
1536 | } | ||
1537 | |||
1538 | if ((NewPromMode & SK_PROM_MODE_ALL_MC) && | ||
1539 | !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC. */ | ||
1540 | |||
1541 | /* Set all bits in 64-bit hash register. */ | ||
1542 | XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash); | ||
1543 | |||
1544 | /* Enable Hashing */ | ||
1545 | SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); | ||
1546 | } | ||
1547 | else if ((CurPromMode & SK_PROM_MODE_ALL_MC) && | ||
1548 | !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm MC. */ | ||
1549 | for (Inexact = 0, i = 0; i < 8; i++) { | ||
1550 | Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i]; | ||
1551 | } | ||
1552 | if (Inexact == 0) { | ||
1553 | /* Disable Hashing */ | ||
1554 | SkMacHashing(pAC, IoC, (int) PortNumber, SK_FALSE); | ||
1555 | } | ||
1556 | else { | ||
1557 | /* Set 64-bit hash register to InexactFilter. */ | ||
1558 | XM_OUTHASH(IoC, PortNumber, XM_HSM, | ||
1559 | &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]); | ||
1560 | |||
1561 | /* Enable Hashing */ | ||
1562 | SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); | ||
1563 | } | ||
1564 | } | ||
1565 | |||
1566 | if ((NewPromMode & SK_PROM_MODE_LLC) && | ||
1567 | !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */ | ||
1568 | /* Set the MAC in Promiscuous Mode */ | ||
1569 | SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_TRUE); | ||
1570 | } | ||
1571 | else if ((CurPromMode & SK_PROM_MODE_LLC) && | ||
1572 | !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC. */ | ||
1573 | /* Clear Promiscuous Mode */ | ||
1574 | SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_FALSE); | ||
1575 | } | ||
1576 | |||
1577 | return (SK_ADDR_SUCCESS); | ||
1578 | |||
1579 | } /* SkAddrXmacPromiscuousChange */ | ||
1580 | |||
1581 | #endif /* GENESIS */ | ||
1582 | |||
1583 | #ifdef YUKON | ||
1584 | |||
1585 | /****************************************************************************** | ||
1586 | * | ||
1587 | * SkAddrGmacPromiscuousChange - set promiscuous mode for given port | ||
1588 | * | ||
1589 | * Description: | ||
1590 | * This routine manages promiscuous mode: | ||
1591 | * - none | ||
1592 | * - all LLC frames | ||
1593 | * - all MC frames | ||
1594 | * | ||
1595 | * Context: | ||
1596 | * runtime, pageable | ||
1597 | * may be called after SK_INIT_IO | ||
1598 | * | ||
1599 | * Returns: | ||
1600 | * SK_ADDR_SUCCESS | ||
1601 | * SK_ADDR_ILLEGAL_PORT | ||
1602 | */ | ||
1603 | static int SkAddrGmacPromiscuousChange( | ||
1604 | SK_AC *pAC, /* adapter context */ | ||
1605 | SK_IOC IoC, /* I/O context */ | ||
1606 | SK_U32 PortNumber, /* port whose promiscuous mode changes */ | ||
1607 | int NewPromMode) /* new promiscuous mode */ | ||
1608 | { | ||
1609 | SK_U16 ReceiveControl; /* GMAC Receive Control Register */ | ||
1610 | int CurPromMode = SK_PROM_MODE_NONE; | ||
1611 | |||
1612 | /* Read CurPromMode from Hardware. */ | ||
1613 | GM_IN16(IoC, PortNumber, GM_RX_CTRL, &ReceiveControl); | ||
1614 | |||
1615 | if ((ReceiveControl & (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA)) == 0) { | ||
1616 | /* Promiscuous mode! */ | ||
1617 | CurPromMode |= SK_PROM_MODE_LLC; | ||
1618 | } | ||
1619 | |||
1620 | if ((ReceiveControl & GM_RXCR_MCF_ENA) == 0) { | ||
1621 | /* All Multicast mode! */ | ||
1622 | CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC); | ||
1623 | } | ||
1624 | |||
1625 | pAC->Addr.Port[PortNumber].PromMode = NewPromMode; | ||
1626 | |||
1627 | if (NewPromMode == CurPromMode) { | ||
1628 | return (SK_ADDR_SUCCESS); | ||
1629 | } | ||
1630 | |||
1631 | if ((NewPromMode & SK_PROM_MODE_ALL_MC) && | ||
1632 | !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC */ | ||
1633 | |||
1634 | /* Set all bits in 64-bit hash register. */ | ||
1635 | GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash); | ||
1636 | |||
1637 | /* Enable Hashing */ | ||
1638 | SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); | ||
1639 | } | ||
1640 | |||
1641 | if ((CurPromMode & SK_PROM_MODE_ALL_MC) && | ||
1642 | !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm. MC */ | ||
1643 | |||
1644 | /* Set 64-bit hash register to InexactFilter. */ | ||
1645 | GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, | ||
1646 | &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]); | ||
1647 | |||
1648 | /* Enable Hashing. */ | ||
1649 | SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); | ||
1650 | } | ||
1651 | |||
1652 | if ((NewPromMode & SK_PROM_MODE_LLC) && | ||
1653 | !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */ | ||
1654 | |||
1655 | /* Set the MAC to Promiscuous Mode. */ | ||
1656 | SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_TRUE); | ||
1657 | } | ||
1658 | else if ((CurPromMode & SK_PROM_MODE_LLC) && | ||
1659 | !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC */ | ||
1660 | |||
1661 | /* Clear Promiscuous Mode. */ | ||
1662 | SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_FALSE); | ||
1663 | } | ||
1664 | |||
1665 | return (SK_ADDR_SUCCESS); | ||
1666 | |||
1667 | } /* SkAddrGmacPromiscuousChange */ | ||
1668 | |||
1669 | #endif /* YUKON */ | ||
1670 | |||
1671 | #ifndef SK_SLIM | ||
1672 | |||
1673 | /****************************************************************************** | ||
1674 | * | ||
1675 | * SkAddrSwap - swap address info | ||
1676 | * | ||
1677 | * Description: | ||
1678 | * This routine swaps address info of two ports. | ||
1679 | * | ||
1680 | * Context: | ||
1681 | * runtime, pageable | ||
1682 | * may be called after SK_INIT_IO | ||
1683 | * | ||
1684 | * Returns: | ||
1685 | * SK_ADDR_SUCCESS | ||
1686 | * SK_ADDR_ILLEGAL_PORT | ||
1687 | */ | ||
1688 | int SkAddrSwap( | ||
1689 | SK_AC *pAC, /* adapter context */ | ||
1690 | SK_IOC IoC, /* I/O context */ | ||
1691 | SK_U32 FromPortNumber, /* Port1 Index */ | ||
1692 | SK_U32 ToPortNumber) /* Port2 Index */ | ||
1693 | { | ||
1694 | int i; | ||
1695 | SK_U8 Byte; | ||
1696 | SK_MAC_ADDR MacAddr; | ||
1697 | SK_U32 DWord; | ||
1698 | |||
1699 | if (FromPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { | ||
1700 | return (SK_ADDR_ILLEGAL_PORT); | ||
1701 | } | ||
1702 | |||
1703 | if (ToPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { | ||
1704 | return (SK_ADDR_ILLEGAL_PORT); | ||
1705 | } | ||
1706 | |||
1707 | if (pAC->Rlmt.Port[FromPortNumber].Net != pAC->Rlmt.Port[ToPortNumber].Net) { | ||
1708 | return (SK_ADDR_ILLEGAL_PORT); | ||
1709 | } | ||
1710 | |||
1711 | /* | ||
1712 | * Swap: | ||
1713 | * - Exact Match Entries (GEnesis and Yukon) | ||
1714 | * Yukon uses first entry for the logical MAC | ||
1715 | * address (stored in the second GMAC register). | ||
1716 | * - FirstExactMatchRlmt (GEnesis only) | ||
1717 | * - NextExactMatchRlmt (GEnesis only) | ||
1718 | * - FirstExactMatchDrv (GEnesis only) | ||
1719 | * - NextExactMatchDrv (GEnesis only) | ||
1720 | * - 64-bit filter (InexactFilter) | ||
1721 | * - Promiscuous Mode | ||
1722 | * of ports. | ||
1723 | */ | ||
1724 | |||
1725 | for (i = 0; i < SK_ADDR_EXACT_MATCHES; i++) { | ||
1726 | MacAddr = pAC->Addr.Port[FromPortNumber].Exact[i]; | ||
1727 | pAC->Addr.Port[FromPortNumber].Exact[i] = | ||
1728 | pAC->Addr.Port[ToPortNumber].Exact[i]; | ||
1729 | pAC->Addr.Port[ToPortNumber].Exact[i] = MacAddr; | ||
1730 | } | ||
1731 | |||
1732 | for (i = 0; i < 8; i++) { | ||
1733 | Byte = pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i]; | ||
1734 | pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i] = | ||
1735 | pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i]; | ||
1736 | pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i] = Byte; | ||
1737 | } | ||
1738 | |||
1739 | i = pAC->Addr.Port[FromPortNumber].PromMode; | ||
1740 | pAC->Addr.Port[FromPortNumber].PromMode = pAC->Addr.Port[ToPortNumber].PromMode; | ||
1741 | pAC->Addr.Port[ToPortNumber].PromMode = i; | ||
1742 | |||
1743 | if (pAC->GIni.GIGenesis) { | ||
1744 | DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt; | ||
1745 | pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt = | ||
1746 | pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt; | ||
1747 | pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt = DWord; | ||
1748 | |||
1749 | DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt; | ||
1750 | pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt = | ||
1751 | pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt; | ||
1752 | pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt = DWord; | ||
1753 | |||
1754 | DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv; | ||
1755 | pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv = | ||
1756 | pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv; | ||
1757 | pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv = DWord; | ||
1758 | |||
1759 | DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchDrv; | ||
1760 | pAC->Addr.Port[FromPortNumber].NextExactMatchDrv = | ||
1761 | pAC->Addr.Port[ToPortNumber].NextExactMatchDrv; | ||
1762 | pAC->Addr.Port[ToPortNumber].NextExactMatchDrv = DWord; | ||
1763 | } | ||
1764 | |||
1765 | /* CAUTION: Solution works if only ports of one adapter are in use. */ | ||
1766 | for (i = 0; (SK_U32) i < pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber]. | ||
1767 | Net->NetNumber].NumPorts; i++) { | ||
1768 | if (pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber]. | ||
1769 | Port[i]->PortNumber == ToPortNumber) { | ||
1770 | pAC->Addr.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber]. | ||
1771 | ActivePort = i; | ||
1772 | /* 20001207 RA: Was "ToPortNumber;". */ | ||
1773 | } | ||
1774 | } | ||
1775 | |||
1776 | (void) SkAddrMcUpdate(pAC, IoC, FromPortNumber); | ||
1777 | (void) SkAddrMcUpdate(pAC, IoC, ToPortNumber); | ||
1778 | |||
1779 | return (SK_ADDR_SUCCESS); | ||
1780 | |||
1781 | } /* SkAddrSwap */ | ||
1782 | |||
1783 | #endif /* !SK_SLIM */ | ||
1784 | |||
1785 | #ifdef __cplusplus | ||
1786 | } | ||
1787 | #endif /* __cplusplus */ | ||
1788 | |||
diff --git a/drivers/net/sk98lin/skdim.c b/drivers/net/sk98lin/skdim.c new file mode 100644 index 000000000000..37ce03fb8de3 --- /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 useful | ||
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 regarding 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 : Disables 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..5a6da8950faa --- /dev/null +++ b/drivers/net/sk98lin/skethtool.c | |||
@@ -0,0 +1,627 @@ | |||
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 | /* Only Yukon supports checksum offload. */ | ||
543 | static int setScatterGather(struct net_device *dev, u32 data) | ||
544 | { | ||
545 | DEV_NET *pNet = netdev_priv(dev); | ||
546 | SK_AC *pAC = pNet->pAC; | ||
547 | |||
548 | if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) | ||
549 | return -EOPNOTSUPP; | ||
550 | return ethtool_op_set_sg(dev, data); | ||
551 | } | ||
552 | |||
553 | static int setTxCsum(struct net_device *dev, u32 data) | ||
554 | { | ||
555 | DEV_NET *pNet = netdev_priv(dev); | ||
556 | SK_AC *pAC = pNet->pAC; | ||
557 | |||
558 | if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) | ||
559 | return -EOPNOTSUPP; | ||
560 | |||
561 | return ethtool_op_set_tx_csum(dev, data); | ||
562 | } | ||
563 | |||
564 | static u32 getRxCsum(struct net_device *dev) | ||
565 | { | ||
566 | DEV_NET *pNet = netdev_priv(dev); | ||
567 | SK_AC *pAC = pNet->pAC; | ||
568 | |||
569 | return pAC->RxPort[pNet->PortNr].RxCsum; | ||
570 | } | ||
571 | |||
572 | static int setRxCsum(struct net_device *dev, u32 data) | ||
573 | { | ||
574 | DEV_NET *pNet = netdev_priv(dev); | ||
575 | SK_AC *pAC = pNet->pAC; | ||
576 | |||
577 | if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) | ||
578 | return -EOPNOTSUPP; | ||
579 | |||
580 | pAC->RxPort[pNet->PortNr].RxCsum = data != 0; | ||
581 | return 0; | ||
582 | } | ||
583 | |||
584 | static int getRegsLen(struct net_device *dev) | ||
585 | { | ||
586 | return 0x4000; | ||
587 | } | ||
588 | |||
589 | /* | ||
590 | * Returns copy of whole control register region | ||
591 | * Note: skip RAM address register because accessing it will | ||
592 | * cause bus hangs! | ||
593 | */ | ||
594 | static void getRegs(struct net_device *dev, struct ethtool_regs *regs, | ||
595 | void *p) | ||
596 | { | ||
597 | DEV_NET *pNet = netdev_priv(dev); | ||
598 | const void __iomem *io = pNet->pAC->IoBase; | ||
599 | |||
600 | regs->version = 1; | ||
601 | memset(p, 0, regs->len); | ||
602 | memcpy_fromio(p, io, B3_RAM_ADDR); | ||
603 | |||
604 | memcpy_fromio(p + B3_RI_WTO_R1, io + B3_RI_WTO_R1, | ||
605 | regs->len - B3_RI_WTO_R1); | ||
606 | } | ||
607 | |||
608 | const struct ethtool_ops SkGeEthtoolOps = { | ||
609 | .get_settings = getSettings, | ||
610 | .set_settings = setSettings, | ||
611 | .get_drvinfo = getDriverInfo, | ||
612 | .get_strings = getStrings, | ||
613 | .get_stats_count = getStatsCount, | ||
614 | .get_ethtool_stats = getEthtoolStats, | ||
615 | .phys_id = locateDevice, | ||
616 | .get_pauseparam = getPauseParams, | ||
617 | .set_pauseparam = setPauseParams, | ||
618 | .get_link = ethtool_op_get_link, | ||
619 | .get_sg = ethtool_op_get_sg, | ||
620 | .set_sg = setScatterGather, | ||
621 | .get_tx_csum = ethtool_op_get_tx_csum, | ||
622 | .set_tx_csum = setTxCsum, | ||
623 | .get_rx_csum = getRxCsum, | ||
624 | .set_rx_csum = setRxCsum, | ||
625 | .get_regs = getRegs, | ||
626 | .get_regs_len = getRegsLen, | ||
627 | }; | ||
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c new file mode 100644 index 000000000000..7dc9c9ebf5e7 --- /dev/null +++ b/drivers/net/sk98lin/skge.c | |||
@@ -0,0 +1,5219 @@ | |||
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/skrlmt.h" | ||
105 | * | ||
106 | ******************************************************************************/ | ||
107 | |||
108 | #include "h/skversion.h" | ||
109 | |||
110 | #include <linux/in.h> | ||
111 | #include <linux/module.h> | ||
112 | #include <linux/moduleparam.h> | ||
113 | #include <linux/init.h> | ||
114 | #include <linux/dma-mapping.h> | ||
115 | #include <linux/ip.h> | ||
116 | #include <linux/mii.h> | ||
117 | #include <linux/mm.h> | ||
118 | |||
119 | #include "h/skdrv1st.h" | ||
120 | #include "h/skdrv2nd.h" | ||
121 | |||
122 | /******************************************************************************* | ||
123 | * | ||
124 | * Defines | ||
125 | * | ||
126 | ******************************************************************************/ | ||
127 | |||
128 | /* for debuging on x86 only */ | ||
129 | /* #define BREAKPOINT() asm(" int $3"); */ | ||
130 | |||
131 | /* use the transmit hw checksum driver functionality */ | ||
132 | #define USE_SK_TX_CHECKSUM | ||
133 | |||
134 | /* use the receive hw checksum driver functionality */ | ||
135 | #define USE_SK_RX_CHECKSUM | ||
136 | |||
137 | /* use the scatter-gather functionality with sendfile() */ | ||
138 | #define SK_ZEROCOPY | ||
139 | |||
140 | /* use of a transmit complete interrupt */ | ||
141 | #define USE_TX_COMPLETE | ||
142 | |||
143 | /* | ||
144 | * threshold for copying small receive frames | ||
145 | * set to 0 to avoid copying, set to 9001 to copy all frames | ||
146 | */ | ||
147 | #define SK_COPY_THRESHOLD 50 | ||
148 | |||
149 | /* number of adapters that can be configured via command line params */ | ||
150 | #define SK_MAX_CARD_PARAM 16 | ||
151 | |||
152 | |||
153 | |||
154 | /* | ||
155 | * use those defines for a compile-in version of the driver instead | ||
156 | * of command line parameters | ||
157 | */ | ||
158 | // #define LINK_SPEED_A {"Auto", } | ||
159 | // #define LINK_SPEED_B {"Auto", } | ||
160 | // #define AUTO_NEG_A {"Sense", } | ||
161 | // #define AUTO_NEG_B {"Sense", } | ||
162 | // #define DUP_CAP_A {"Both", } | ||
163 | // #define DUP_CAP_B {"Both", } | ||
164 | // #define FLOW_CTRL_A {"SymOrRem", } | ||
165 | // #define FLOW_CTRL_B {"SymOrRem", } | ||
166 | // #define ROLE_A {"Auto", } | ||
167 | // #define ROLE_B {"Auto", } | ||
168 | // #define PREF_PORT {"A", } | ||
169 | // #define CON_TYPE {"Auto", } | ||
170 | // #define RLMT_MODE {"CheckLinkState", } | ||
171 | |||
172 | #define DEV_KFREE_SKB(skb) dev_kfree_skb(skb) | ||
173 | #define DEV_KFREE_SKB_IRQ(skb) dev_kfree_skb_irq(skb) | ||
174 | #define DEV_KFREE_SKB_ANY(skb) dev_kfree_skb_any(skb) | ||
175 | |||
176 | |||
177 | /* Set blink mode*/ | ||
178 | #define OEM_CONFIG_VALUE ( SK_ACT_LED_BLINK | \ | ||
179 | SK_DUP_LED_NORMAL | \ | ||
180 | SK_LED_LINK100_ON) | ||
181 | |||
182 | |||
183 | /* Isr return value */ | ||
184 | #define SkIsrRetVar irqreturn_t | ||
185 | #define SkIsrRetNone IRQ_NONE | ||
186 | #define SkIsrRetHandled IRQ_HANDLED | ||
187 | |||
188 | |||
189 | /******************************************************************************* | ||
190 | * | ||
191 | * Local Function Prototypes | ||
192 | * | ||
193 | ******************************************************************************/ | ||
194 | |||
195 | static void FreeResources(struct SK_NET_DEVICE *dev); | ||
196 | static int SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC); | ||
197 | static SK_BOOL BoardAllocMem(SK_AC *pAC); | ||
198 | static void BoardFreeMem(SK_AC *pAC); | ||
199 | static void BoardInitMem(SK_AC *pAC); | ||
200 | static void SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**, int*, SK_BOOL); | ||
201 | static SkIsrRetVar SkGeIsr(int irq, void *dev_id); | ||
202 | static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id); | ||
203 | static int SkGeOpen(struct SK_NET_DEVICE *dev); | ||
204 | static int SkGeClose(struct SK_NET_DEVICE *dev); | ||
205 | static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev); | ||
206 | static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p); | ||
207 | static void SkGeSetRxMode(struct SK_NET_DEVICE *dev); | ||
208 | static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev); | ||
209 | static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd); | ||
210 | static void GetConfiguration(SK_AC*); | ||
211 | static int XmitFrame(SK_AC*, TX_PORT*, struct sk_buff*); | ||
212 | static void FreeTxDescriptors(SK_AC*pAC, TX_PORT*); | ||
213 | static void FillRxRing(SK_AC*, RX_PORT*); | ||
214 | static SK_BOOL FillRxDescriptor(SK_AC*, RX_PORT*); | ||
215 | static void ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL); | ||
216 | static void ClearAndStartRx(SK_AC*, int); | ||
217 | static void ClearTxIrq(SK_AC*, int, int); | ||
218 | static void ClearRxRing(SK_AC*, RX_PORT*); | ||
219 | static void ClearTxRing(SK_AC*, TX_PORT*); | ||
220 | static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int new_mtu); | ||
221 | static void PortReInitBmu(SK_AC*, int); | ||
222 | static int SkGeIocMib(DEV_NET*, unsigned int, int); | ||
223 | static int SkGeInitPCI(SK_AC *pAC); | ||
224 | static void StartDrvCleanupTimer(SK_AC *pAC); | ||
225 | static void StopDrvCleanupTimer(SK_AC *pAC); | ||
226 | static int XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*); | ||
227 | |||
228 | #ifdef SK_DIAG_SUPPORT | ||
229 | static SK_U32 ParseDeviceNbrFromSlotName(const char *SlotName); | ||
230 | static int SkDrvInitAdapter(SK_AC *pAC, int devNbr); | ||
231 | static int SkDrvDeInitAdapter(SK_AC *pAC, int devNbr); | ||
232 | #endif | ||
233 | |||
234 | /******************************************************************************* | ||
235 | * | ||
236 | * Extern Function Prototypes | ||
237 | * | ||
238 | ******************************************************************************/ | ||
239 | extern void SkDimEnableModerationIfNeeded(SK_AC *pAC); | ||
240 | extern void SkDimDisplayModerationSettings(SK_AC *pAC); | ||
241 | extern void SkDimStartModerationTimer(SK_AC *pAC); | ||
242 | extern void SkDimModerate(SK_AC *pAC); | ||
243 | extern void SkGeBlinkTimer(unsigned long data); | ||
244 | |||
245 | #ifdef DEBUG | ||
246 | static void DumpMsg(struct sk_buff*, char*); | ||
247 | static void DumpData(char*, int); | ||
248 | static void DumpLong(char*, int); | ||
249 | #endif | ||
250 | |||
251 | /* global variables *********************************************************/ | ||
252 | static SK_BOOL DoPrintInterfaceChange = SK_TRUE; | ||
253 | extern const struct ethtool_ops SkGeEthtoolOps; | ||
254 | |||
255 | /* local variables **********************************************************/ | ||
256 | static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}}; | ||
257 | static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480}; | ||
258 | |||
259 | /***************************************************************************** | ||
260 | * | ||
261 | * SkPciWriteCfgDWord - write a 32 bit value to pci config space | ||
262 | * | ||
263 | * Description: | ||
264 | * This routine writes a 32 bit value to the pci configuration | ||
265 | * space. | ||
266 | * | ||
267 | * Returns: | ||
268 | * 0 - indicate everything worked ok. | ||
269 | * != 0 - error indication | ||
270 | */ | ||
271 | static inline int SkPciWriteCfgDWord( | ||
272 | SK_AC *pAC, /* Adapter Control structure pointer */ | ||
273 | int PciAddr, /* PCI register address */ | ||
274 | SK_U32 Val) /* pointer to store the read value */ | ||
275 | { | ||
276 | pci_write_config_dword(pAC->PciDev, PciAddr, Val); | ||
277 | return(0); | ||
278 | } /* SkPciWriteCfgDWord */ | ||
279 | |||
280 | /***************************************************************************** | ||
281 | * | ||
282 | * SkGeInitPCI - Init the PCI resources | ||
283 | * | ||
284 | * Description: | ||
285 | * This function initialize the PCI resources and IO | ||
286 | * | ||
287 | * Returns: | ||
288 | * 0 - indicate everything worked ok. | ||
289 | * != 0 - error indication | ||
290 | */ | ||
291 | static __devinit int SkGeInitPCI(SK_AC *pAC) | ||
292 | { | ||
293 | struct SK_NET_DEVICE *dev = pAC->dev[0]; | ||
294 | struct pci_dev *pdev = pAC->PciDev; | ||
295 | int retval; | ||
296 | |||
297 | dev->mem_start = pci_resource_start (pdev, 0); | ||
298 | pci_set_master(pdev); | ||
299 | |||
300 | retval = pci_request_regions(pdev, "sk98lin"); | ||
301 | if (retval) | ||
302 | goto out; | ||
303 | |||
304 | #ifdef SK_BIG_ENDIAN | ||
305 | /* | ||
306 | * On big endian machines, we use the adapter's aibility of | ||
307 | * reading the descriptors as big endian. | ||
308 | */ | ||
309 | { | ||
310 | SK_U32 our2; | ||
311 | SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2); | ||
312 | our2 |= PCI_REV_DESC; | ||
313 | SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2); | ||
314 | } | ||
315 | #endif | ||
316 | |||
317 | /* | ||
318 | * Remap the regs into kernel space. | ||
319 | */ | ||
320 | pAC->IoBase = ioremap_nocache(dev->mem_start, 0x4000); | ||
321 | if (!pAC->IoBase) { | ||
322 | retval = -EIO; | ||
323 | goto out_release; | ||
324 | } | ||
325 | |||
326 | return 0; | ||
327 | |||
328 | out_release: | ||
329 | pci_release_regions(pdev); | ||
330 | out: | ||
331 | return retval; | ||
332 | } | ||
333 | |||
334 | |||
335 | /***************************************************************************** | ||
336 | * | ||
337 | * FreeResources - release resources allocated for adapter | ||
338 | * | ||
339 | * Description: | ||
340 | * This function releases the IRQ, unmaps the IO and | ||
341 | * frees the desriptor ring. | ||
342 | * | ||
343 | * Returns: N/A | ||
344 | * | ||
345 | */ | ||
346 | static void FreeResources(struct SK_NET_DEVICE *dev) | ||
347 | { | ||
348 | SK_U32 AllocFlag; | ||
349 | DEV_NET *pNet; | ||
350 | SK_AC *pAC; | ||
351 | |||
352 | pNet = netdev_priv(dev); | ||
353 | pAC = pNet->pAC; | ||
354 | AllocFlag = pAC->AllocFlag; | ||
355 | if (pAC->PciDev) { | ||
356 | pci_release_regions(pAC->PciDev); | ||
357 | } | ||
358 | if (AllocFlag & SK_ALLOC_IRQ) { | ||
359 | free_irq(dev->irq, dev); | ||
360 | } | ||
361 | if (pAC->IoBase) { | ||
362 | iounmap(pAC->IoBase); | ||
363 | } | ||
364 | if (pAC->pDescrMem) { | ||
365 | BoardFreeMem(pAC); | ||
366 | } | ||
367 | |||
368 | } /* FreeResources */ | ||
369 | |||
370 | MODULE_AUTHOR("Mirko Lindner <mlindner@syskonnect.de>"); | ||
371 | MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver"); | ||
372 | MODULE_LICENSE("GPL"); | ||
373 | |||
374 | #ifdef LINK_SPEED_A | ||
375 | static char *Speed_A[SK_MAX_CARD_PARAM] = LINK_SPEED; | ||
376 | #else | ||
377 | static char *Speed_A[SK_MAX_CARD_PARAM] = {"", }; | ||
378 | #endif | ||
379 | |||
380 | #ifdef LINK_SPEED_B | ||
381 | static char *Speed_B[SK_MAX_CARD_PARAM] = LINK_SPEED; | ||
382 | #else | ||
383 | static char *Speed_B[SK_MAX_CARD_PARAM] = {"", }; | ||
384 | #endif | ||
385 | |||
386 | #ifdef AUTO_NEG_A | ||
387 | static char *AutoNeg_A[SK_MAX_CARD_PARAM] = AUTO_NEG_A; | ||
388 | #else | ||
389 | static char *AutoNeg_A[SK_MAX_CARD_PARAM] = {"", }; | ||
390 | #endif | ||
391 | |||
392 | #ifdef DUP_CAP_A | ||
393 | static char *DupCap_A[SK_MAX_CARD_PARAM] = DUP_CAP_A; | ||
394 | #else | ||
395 | static char *DupCap_A[SK_MAX_CARD_PARAM] = {"", }; | ||
396 | #endif | ||
397 | |||
398 | #ifdef FLOW_CTRL_A | ||
399 | static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = FLOW_CTRL_A; | ||
400 | #else | ||
401 | static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = {"", }; | ||
402 | #endif | ||
403 | |||
404 | #ifdef ROLE_A | ||
405 | static char *Role_A[SK_MAX_CARD_PARAM] = ROLE_A; | ||
406 | #else | ||
407 | static char *Role_A[SK_MAX_CARD_PARAM] = {"", }; | ||
408 | #endif | ||
409 | |||
410 | #ifdef AUTO_NEG_B | ||
411 | static char *AutoNeg_B[SK_MAX_CARD_PARAM] = AUTO_NEG_B; | ||
412 | #else | ||
413 | static char *AutoNeg_B[SK_MAX_CARD_PARAM] = {"", }; | ||
414 | #endif | ||
415 | |||
416 | #ifdef DUP_CAP_B | ||
417 | static char *DupCap_B[SK_MAX_CARD_PARAM] = DUP_CAP_B; | ||
418 | #else | ||
419 | static char *DupCap_B[SK_MAX_CARD_PARAM] = {"", }; | ||
420 | #endif | ||
421 | |||
422 | #ifdef FLOW_CTRL_B | ||
423 | static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = FLOW_CTRL_B; | ||
424 | #else | ||
425 | static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = {"", }; | ||
426 | #endif | ||
427 | |||
428 | #ifdef ROLE_B | ||
429 | static char *Role_B[SK_MAX_CARD_PARAM] = ROLE_B; | ||
430 | #else | ||
431 | static char *Role_B[SK_MAX_CARD_PARAM] = {"", }; | ||
432 | #endif | ||
433 | |||
434 | #ifdef CON_TYPE | ||
435 | static char *ConType[SK_MAX_CARD_PARAM] = CON_TYPE; | ||
436 | #else | ||
437 | static char *ConType[SK_MAX_CARD_PARAM] = {"", }; | ||
438 | #endif | ||
439 | |||
440 | #ifdef PREF_PORT | ||
441 | static char *PrefPort[SK_MAX_CARD_PARAM] = PREF_PORT; | ||
442 | #else | ||
443 | static char *PrefPort[SK_MAX_CARD_PARAM] = {"", }; | ||
444 | #endif | ||
445 | |||
446 | #ifdef RLMT_MODE | ||
447 | static char *RlmtMode[SK_MAX_CARD_PARAM] = RLMT_MODE; | ||
448 | #else | ||
449 | static char *RlmtMode[SK_MAX_CARD_PARAM] = {"", }; | ||
450 | #endif | ||
451 | |||
452 | static int IntsPerSec[SK_MAX_CARD_PARAM]; | ||
453 | static char *Moderation[SK_MAX_CARD_PARAM]; | ||
454 | static char *ModerationMask[SK_MAX_CARD_PARAM]; | ||
455 | static char *AutoSizing[SK_MAX_CARD_PARAM]; | ||
456 | static char *Stats[SK_MAX_CARD_PARAM]; | ||
457 | |||
458 | module_param_array(Speed_A, charp, NULL, 0); | ||
459 | module_param_array(Speed_B, charp, NULL, 0); | ||
460 | module_param_array(AutoNeg_A, charp, NULL, 0); | ||
461 | module_param_array(AutoNeg_B, charp, NULL, 0); | ||
462 | module_param_array(DupCap_A, charp, NULL, 0); | ||
463 | module_param_array(DupCap_B, charp, NULL, 0); | ||
464 | module_param_array(FlowCtrl_A, charp, NULL, 0); | ||
465 | module_param_array(FlowCtrl_B, charp, NULL, 0); | ||
466 | module_param_array(Role_A, charp, NULL, 0); | ||
467 | module_param_array(Role_B, charp, NULL, 0); | ||
468 | module_param_array(ConType, charp, NULL, 0); | ||
469 | module_param_array(PrefPort, charp, NULL, 0); | ||
470 | module_param_array(RlmtMode, charp, NULL, 0); | ||
471 | /* used for interrupt moderation */ | ||
472 | module_param_array(IntsPerSec, int, NULL, 0); | ||
473 | module_param_array(Moderation, charp, NULL, 0); | ||
474 | module_param_array(Stats, charp, NULL, 0); | ||
475 | module_param_array(ModerationMask, charp, NULL, 0); | ||
476 | module_param_array(AutoSizing, charp, NULL, 0); | ||
477 | |||
478 | /***************************************************************************** | ||
479 | * | ||
480 | * SkGeBoardInit - do level 0 and 1 initialization | ||
481 | * | ||
482 | * Description: | ||
483 | * This function prepares the board hardware for running. The desriptor | ||
484 | * ring is set up, the IRQ is allocated and the configuration settings | ||
485 | * are examined. | ||
486 | * | ||
487 | * Returns: | ||
488 | * 0, if everything is ok | ||
489 | * !=0, on error | ||
490 | */ | ||
491 | static int __devinit SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC) | ||
492 | { | ||
493 | short i; | ||
494 | unsigned long Flags; | ||
495 | char *DescrString = "sk98lin: Driver for Linux"; /* this is given to PNMI */ | ||
496 | char *VerStr = VER_STRING; | ||
497 | int Ret; /* return code of request_irq */ | ||
498 | SK_BOOL DualNet; | ||
499 | |||
500 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, | ||
501 | ("IoBase: %08lX\n", (unsigned long)pAC->IoBase)); | ||
502 | for (i=0; i<SK_MAX_MACS; i++) { | ||
503 | pAC->TxPort[i][0].HwAddr = pAC->IoBase + TxQueueAddr[i][0]; | ||
504 | pAC->TxPort[i][0].PortIndex = i; | ||
505 | pAC->RxPort[i].HwAddr = pAC->IoBase + RxQueueAddr[i]; | ||
506 | pAC->RxPort[i].PortIndex = i; | ||
507 | } | ||
508 | |||
509 | /* Initialize the mutexes */ | ||
510 | for (i=0; i<SK_MAX_MACS; i++) { | ||
511 | spin_lock_init(&pAC->TxPort[i][0].TxDesRingLock); | ||
512 | spin_lock_init(&pAC->RxPort[i].RxDesRingLock); | ||
513 | } | ||
514 | spin_lock_init(&pAC->SlowPathLock); | ||
515 | |||
516 | /* setup phy_id blink timer */ | ||
517 | pAC->BlinkTimer.function = SkGeBlinkTimer; | ||
518 | pAC->BlinkTimer.data = (unsigned long) dev; | ||
519 | init_timer(&pAC->BlinkTimer); | ||
520 | |||
521 | /* level 0 init common modules here */ | ||
522 | |||
523 | spin_lock_irqsave(&pAC->SlowPathLock, Flags); | ||
524 | /* Does a RESET on board ...*/ | ||
525 | if (SkGeInit(pAC, pAC->IoBase, SK_INIT_DATA) != 0) { | ||
526 | printk("HWInit (0) failed.\n"); | ||
527 | spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); | ||
528 | return -EIO; | ||
529 | } | ||
530 | SkI2cInit( pAC, pAC->IoBase, SK_INIT_DATA); | ||
531 | SkEventInit(pAC, pAC->IoBase, SK_INIT_DATA); | ||
532 | SkPnmiInit( pAC, pAC->IoBase, SK_INIT_DATA); | ||
533 | SkAddrInit( pAC, pAC->IoBase, SK_INIT_DATA); | ||
534 | SkRlmtInit( pAC, pAC->IoBase, SK_INIT_DATA); | ||
535 | SkTimerInit(pAC, pAC->IoBase, SK_INIT_DATA); | ||
536 | |||
537 | pAC->BoardLevel = SK_INIT_DATA; | ||
538 | pAC->RxBufSize = ETH_BUF_SIZE; | ||
539 | |||
540 | SK_PNMI_SET_DRIVER_DESCR(pAC, DescrString); | ||
541 | SK_PNMI_SET_DRIVER_VER(pAC, VerStr); | ||
542 | |||
543 | spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); | ||
544 | |||
545 | /* level 1 init common modules here (HW init) */ | ||
546 | spin_lock_irqsave(&pAC->SlowPathLock, Flags); | ||
547 | if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) { | ||
548 | printk("sk98lin: HWInit (1) failed.\n"); | ||
549 | spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); | ||
550 | return -EIO; | ||
551 | } | ||
552 | SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO); | ||
553 | SkEventInit(pAC, pAC->IoBase, SK_INIT_IO); | ||
554 | SkPnmiInit( pAC, pAC->IoBase, SK_INIT_IO); | ||
555 | SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO); | ||
556 | SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO); | ||
557 | SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO); | ||
558 | |||
559 | /* Set chipset type support */ | ||
560 | pAC->ChipsetType = 0; | ||
561 | if ((pAC->GIni.GIChipId == CHIP_ID_YUKON) || | ||
562 | (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE)) { | ||
563 | pAC->ChipsetType = 1; | ||
564 | } | ||
565 | |||
566 | GetConfiguration(pAC); | ||
567 | if (pAC->RlmtNets == 2) { | ||
568 | pAC->GIni.GIPortUsage = SK_MUL_LINK; | ||
569 | } | ||
570 | |||
571 | pAC->BoardLevel = SK_INIT_IO; | ||
572 | spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); | ||
573 | |||
574 | if (pAC->GIni.GIMacsFound == 2) { | ||
575 | Ret = request_irq(dev->irq, SkGeIsr, IRQF_SHARED, "sk98lin", dev); | ||
576 | } else if (pAC->GIni.GIMacsFound == 1) { | ||
577 | Ret = request_irq(dev->irq, SkGeIsrOnePort, IRQF_SHARED, | ||
578 | "sk98lin", dev); | ||
579 | } else { | ||
580 | printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n", | ||
581 | pAC->GIni.GIMacsFound); | ||
582 | return -EIO; | ||
583 | } | ||
584 | |||
585 | if (Ret) { | ||
586 | printk(KERN_WARNING "sk98lin: Requested IRQ %d is busy.\n", | ||
587 | dev->irq); | ||
588 | return Ret; | ||
589 | } | ||
590 | pAC->AllocFlag |= SK_ALLOC_IRQ; | ||
591 | |||
592 | /* Alloc memory for this board (Mem for RxD/TxD) : */ | ||
593 | if(!BoardAllocMem(pAC)) { | ||
594 | printk("No memory for descriptor rings.\n"); | ||
595 | return -ENOMEM; | ||
596 | } | ||
597 | |||
598 | BoardInitMem(pAC); | ||
599 | /* tschilling: New common function with minimum size check. */ | ||
600 | DualNet = SK_FALSE; | ||
601 | if (pAC->RlmtNets == 2) { | ||
602 | DualNet = SK_TRUE; | ||
603 | } | ||
604 | |||
605 | if (SkGeInitAssignRamToQueues( | ||
606 | pAC, | ||
607 | pAC->ActivePort, | ||
608 | DualNet)) { | ||
609 | BoardFreeMem(pAC); | ||
610 | printk("sk98lin: SkGeInitAssignRamToQueues failed.\n"); | ||
611 | return -EIO; | ||
612 | } | ||
613 | |||
614 | return (0); | ||
615 | } /* SkGeBoardInit */ | ||
616 | |||
617 | |||
618 | /***************************************************************************** | ||
619 | * | ||
620 | * BoardAllocMem - allocate the memory for the descriptor rings | ||
621 | * | ||
622 | * Description: | ||
623 | * This function allocates the memory for all descriptor rings. | ||
624 | * Each ring is aligned for the desriptor alignment and no ring | ||
625 | * has a 4 GByte boundary in it (because the upper 32 bit must | ||
626 | * be constant for all descriptiors in one rings). | ||
627 | * | ||
628 | * Returns: | ||
629 | * SK_TRUE, if all memory could be allocated | ||
630 | * SK_FALSE, if not | ||
631 | */ | ||
632 | static __devinit SK_BOOL BoardAllocMem(SK_AC *pAC) | ||
633 | { | ||
634 | caddr_t pDescrMem; /* pointer to descriptor memory area */ | ||
635 | size_t AllocLength; /* length of complete descriptor area */ | ||
636 | int i; /* loop counter */ | ||
637 | unsigned long BusAddr; | ||
638 | |||
639 | |||
640 | /* rings plus one for alignment (do not cross 4 GB boundary) */ | ||
641 | /* RX_RING_SIZE is assumed bigger than TX_RING_SIZE */ | ||
642 | #if (BITS_PER_LONG == 32) | ||
643 | AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8; | ||
644 | #else | ||
645 | AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound | ||
646 | + RX_RING_SIZE + 8; | ||
647 | #endif | ||
648 | |||
649 | pDescrMem = pci_alloc_consistent(pAC->PciDev, AllocLength, | ||
650 | &pAC->pDescrMemDMA); | ||
651 | |||
652 | if (pDescrMem == NULL) { | ||
653 | return (SK_FALSE); | ||
654 | } | ||
655 | pAC->pDescrMem = pDescrMem; | ||
656 | BusAddr = (unsigned long) pAC->pDescrMemDMA; | ||
657 | |||
658 | /* Descriptors need 8 byte alignment, and this is ensured | ||
659 | * by pci_alloc_consistent. | ||
660 | */ | ||
661 | for (i=0; i<pAC->GIni.GIMacsFound; i++) { | ||
662 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, | ||
663 | ("TX%d/A: pDescrMem: %lX, PhysDescrMem: %lX\n", | ||
664 | i, (unsigned long) pDescrMem, | ||
665 | BusAddr)); | ||
666 | pAC->TxPort[i][0].pTxDescrRing = pDescrMem; | ||
667 | pAC->TxPort[i][0].VTxDescrRing = BusAddr; | ||
668 | pDescrMem += TX_RING_SIZE; | ||
669 | BusAddr += TX_RING_SIZE; | ||
670 | |||
671 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, | ||
672 | ("RX%d: pDescrMem: %lX, PhysDescrMem: %lX\n", | ||
673 | i, (unsigned long) pDescrMem, | ||
674 | (unsigned long)BusAddr)); | ||
675 | pAC->RxPort[i].pRxDescrRing = pDescrMem; | ||
676 | pAC->RxPort[i].VRxDescrRing = BusAddr; | ||
677 | pDescrMem += RX_RING_SIZE; | ||
678 | BusAddr += RX_RING_SIZE; | ||
679 | } /* for */ | ||
680 | |||
681 | return (SK_TRUE); | ||
682 | } /* BoardAllocMem */ | ||
683 | |||
684 | |||
685 | /**************************************************************************** | ||
686 | * | ||
687 | * BoardFreeMem - reverse of BoardAllocMem | ||
688 | * | ||
689 | * Description: | ||
690 | * Free all memory allocated in BoardAllocMem: adapter context, | ||
691 | * descriptor rings, locks. | ||
692 | * | ||
693 | * Returns: N/A | ||
694 | */ | ||
695 | static void BoardFreeMem( | ||
696 | SK_AC *pAC) | ||
697 | { | ||
698 | size_t AllocLength; /* length of complete descriptor area */ | ||
699 | |||
700 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, | ||
701 | ("BoardFreeMem\n")); | ||
702 | #if (BITS_PER_LONG == 32) | ||
703 | AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8; | ||
704 | #else | ||
705 | AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound | ||
706 | + RX_RING_SIZE + 8; | ||
707 | #endif | ||
708 | |||
709 | pci_free_consistent(pAC->PciDev, AllocLength, | ||
710 | pAC->pDescrMem, pAC->pDescrMemDMA); | ||
711 | pAC->pDescrMem = NULL; | ||
712 | } /* BoardFreeMem */ | ||
713 | |||
714 | |||
715 | /***************************************************************************** | ||
716 | * | ||
717 | * BoardInitMem - initiate the descriptor rings | ||
718 | * | ||
719 | * Description: | ||
720 | * This function sets the descriptor rings up in memory. | ||
721 | * The adapter is initialized with the descriptor start addresses. | ||
722 | * | ||
723 | * Returns: N/A | ||
724 | */ | ||
725 | static __devinit void BoardInitMem(SK_AC *pAC) | ||
726 | { | ||
727 | int i; /* loop counter */ | ||
728 | int RxDescrSize; /* the size of a rx descriptor rounded up to alignment*/ | ||
729 | int TxDescrSize; /* the size of a tx descriptor rounded up to alignment*/ | ||
730 | |||
731 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, | ||
732 | ("BoardInitMem\n")); | ||
733 | |||
734 | RxDescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN; | ||
735 | pAC->RxDescrPerRing = RX_RING_SIZE / RxDescrSize; | ||
736 | TxDescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN; | ||
737 | pAC->TxDescrPerRing = TX_RING_SIZE / RxDescrSize; | ||
738 | |||
739 | for (i=0; i<pAC->GIni.GIMacsFound; i++) { | ||
740 | SetupRing( | ||
741 | pAC, | ||
742 | pAC->TxPort[i][0].pTxDescrRing, | ||
743 | pAC->TxPort[i][0].VTxDescrRing, | ||
744 | (RXD**)&pAC->TxPort[i][0].pTxdRingHead, | ||
745 | (RXD**)&pAC->TxPort[i][0].pTxdRingTail, | ||
746 | (RXD**)&pAC->TxPort[i][0].pTxdRingPrev, | ||
747 | &pAC->TxPort[i][0].TxdRingFree, | ||
748 | SK_TRUE); | ||
749 | SetupRing( | ||
750 | pAC, | ||
751 | pAC->RxPort[i].pRxDescrRing, | ||
752 | pAC->RxPort[i].VRxDescrRing, | ||
753 | &pAC->RxPort[i].pRxdRingHead, | ||
754 | &pAC->RxPort[i].pRxdRingTail, | ||
755 | &pAC->RxPort[i].pRxdRingPrev, | ||
756 | &pAC->RxPort[i].RxdRingFree, | ||
757 | SK_FALSE); | ||
758 | } | ||
759 | } /* BoardInitMem */ | ||
760 | |||
761 | |||
762 | /***************************************************************************** | ||
763 | * | ||
764 | * SetupRing - create one descriptor ring | ||
765 | * | ||
766 | * Description: | ||
767 | * This function creates one descriptor ring in the given memory area. | ||
768 | * The head, tail and number of free descriptors in the ring are set. | ||
769 | * | ||
770 | * Returns: | ||
771 | * none | ||
772 | */ | ||
773 | static void SetupRing( | ||
774 | SK_AC *pAC, | ||
775 | void *pMemArea, /* a pointer to the memory area for the ring */ | ||
776 | uintptr_t VMemArea, /* the virtual bus address of the memory area */ | ||
777 | RXD **ppRingHead, /* address where the head should be written */ | ||
778 | RXD **ppRingTail, /* address where the tail should be written */ | ||
779 | RXD **ppRingPrev, /* address where the tail should be written */ | ||
780 | int *pRingFree, /* address where the # of free descr. goes */ | ||
781 | SK_BOOL IsTx) /* flag: is this a tx ring */ | ||
782 | { | ||
783 | int i; /* loop counter */ | ||
784 | int DescrSize; /* the size of a descriptor rounded up to alignment*/ | ||
785 | int DescrNum; /* number of descriptors per ring */ | ||
786 | RXD *pDescr; /* pointer to a descriptor (receive or transmit) */ | ||
787 | RXD *pNextDescr; /* pointer to the next descriptor */ | ||
788 | RXD *pPrevDescr; /* pointer to the previous descriptor */ | ||
789 | uintptr_t VNextDescr; /* the virtual bus address of the next descriptor */ | ||
790 | |||
791 | if (IsTx == SK_TRUE) { | ||
792 | DescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) * | ||
793 | DESCR_ALIGN; | ||
794 | DescrNum = TX_RING_SIZE / DescrSize; | ||
795 | } else { | ||
796 | DescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) * | ||
797 | DESCR_ALIGN; | ||
798 | DescrNum = RX_RING_SIZE / DescrSize; | ||
799 | } | ||
800 | |||
801 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, | ||
802 | ("Descriptor size: %d Descriptor Number: %d\n", | ||
803 | DescrSize,DescrNum)); | ||
804 | |||
805 | pDescr = (RXD*) pMemArea; | ||
806 | pPrevDescr = NULL; | ||
807 | pNextDescr = (RXD*) (((char*)pDescr) + DescrSize); | ||
808 | VNextDescr = VMemArea + DescrSize; | ||
809 | for(i=0; i<DescrNum; i++) { | ||
810 | /* set the pointers right */ | ||
811 | pDescr->VNextRxd = VNextDescr & 0xffffffffULL; | ||
812 | pDescr->pNextRxd = pNextDescr; | ||
813 | if (!IsTx) pDescr->TcpSumStarts = ETH_HLEN << 16 | ETH_HLEN; | ||
814 | |||
815 | /* advance one step */ | ||
816 | pPrevDescr = pDescr; | ||
817 | pDescr = pNextDescr; | ||
818 | pNextDescr = (RXD*) (((char*)pDescr) + DescrSize); | ||
819 | VNextDescr += DescrSize; | ||
820 | } | ||
821 | pPrevDescr->pNextRxd = (RXD*) pMemArea; | ||
822 | pPrevDescr->VNextRxd = VMemArea; | ||
823 | pDescr = (RXD*) pMemArea; | ||
824 | *ppRingHead = (RXD*) pMemArea; | ||
825 | *ppRingTail = *ppRingHead; | ||
826 | *ppRingPrev = pPrevDescr; | ||
827 | *pRingFree = DescrNum; | ||
828 | } /* SetupRing */ | ||
829 | |||
830 | |||
831 | /***************************************************************************** | ||
832 | * | ||
833 | * PortReInitBmu - re-initiate the descriptor rings for one port | ||
834 | * | ||
835 | * Description: | ||
836 | * This function reinitializes the descriptor rings of one port | ||
837 | * in memory. The port must be stopped before. | ||
838 | * The HW is initialized with the descriptor start addresses. | ||
839 | * | ||
840 | * Returns: | ||
841 | * none | ||
842 | */ | ||
843 | static void PortReInitBmu( | ||
844 | SK_AC *pAC, /* pointer to adapter context */ | ||
845 | int PortIndex) /* index of the port for which to re-init */ | ||
846 | { | ||
847 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, | ||
848 | ("PortReInitBmu ")); | ||
849 | |||
850 | /* set address of first descriptor of ring in BMU */ | ||
851 | SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ Q_DA_L, | ||
852 | (uint32_t)(((caddr_t) | ||
853 | (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) - | ||
854 | pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing + | ||
855 | pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) & | ||
856 | 0xFFFFFFFF)); | ||
857 | SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ Q_DA_H, | ||
858 | (uint32_t)(((caddr_t) | ||
859 | (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) - | ||
860 | pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing + | ||
861 | pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) >> 32)); | ||
862 | SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+Q_DA_L, | ||
863 | (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) - | ||
864 | pAC->RxPort[PortIndex].pRxDescrRing + | ||
865 | pAC->RxPort[PortIndex].VRxDescrRing) & 0xFFFFFFFF)); | ||
866 | SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+Q_DA_H, | ||
867 | (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) - | ||
868 | pAC->RxPort[PortIndex].pRxDescrRing + | ||
869 | pAC->RxPort[PortIndex].VRxDescrRing) >> 32)); | ||
870 | } /* PortReInitBmu */ | ||
871 | |||
872 | |||
873 | /**************************************************************************** | ||
874 | * | ||
875 | * SkGeIsr - handle adapter interrupts | ||
876 | * | ||
877 | * Description: | ||
878 | * The interrupt routine is called when the network adapter | ||
879 | * generates an interrupt. It may also be called if another device | ||
880 | * shares this interrupt vector with the driver. | ||
881 | * | ||
882 | * Returns: N/A | ||
883 | * | ||
884 | */ | ||
885 | static SkIsrRetVar SkGeIsr(int irq, void *dev_id) | ||
886 | { | ||
887 | struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id; | ||
888 | DEV_NET *pNet; | ||
889 | SK_AC *pAC; | ||
890 | SK_U32 IntSrc; /* interrupts source register contents */ | ||
891 | |||
892 | pNet = netdev_priv(dev); | ||
893 | pAC = pNet->pAC; | ||
894 | |||
895 | /* | ||
896 | * Check and process if its our interrupt | ||
897 | */ | ||
898 | SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc); | ||
899 | if (IntSrc == 0) { | ||
900 | return SkIsrRetNone; | ||
901 | } | ||
902 | |||
903 | while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) { | ||
904 | #if 0 /* software irq currently not used */ | ||
905 | if (IntSrc & IS_IRQ_SW) { | ||
906 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, | ||
907 | SK_DBGCAT_DRV_INT_SRC, | ||
908 | ("Software IRQ\n")); | ||
909 | } | ||
910 | #endif | ||
911 | if (IntSrc & IS_R1_F) { | ||
912 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, | ||
913 | SK_DBGCAT_DRV_INT_SRC, | ||
914 | ("EOF RX1 IRQ\n")); | ||
915 | ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE); | ||
916 | SK_PNMI_CNT_RX_INTR(pAC, 0); | ||
917 | } | ||
918 | if (IntSrc & IS_R2_F) { | ||
919 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, | ||
920 | SK_DBGCAT_DRV_INT_SRC, | ||
921 | ("EOF RX2 IRQ\n")); | ||
922 | ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE); | ||
923 | SK_PNMI_CNT_RX_INTR(pAC, 1); | ||
924 | } | ||
925 | #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ | ||
926 | if (IntSrc & IS_XA1_F) { | ||
927 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, | ||
928 | SK_DBGCAT_DRV_INT_SRC, | ||
929 | ("EOF AS TX1 IRQ\n")); | ||
930 | SK_PNMI_CNT_TX_INTR(pAC, 0); | ||
931 | spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); | ||
932 | FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]); | ||
933 | spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); | ||
934 | } | ||
935 | if (IntSrc & IS_XA2_F) { | ||
936 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, | ||
937 | SK_DBGCAT_DRV_INT_SRC, | ||
938 | ("EOF AS TX2 IRQ\n")); | ||
939 | SK_PNMI_CNT_TX_INTR(pAC, 1); | ||
940 | spin_lock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock); | ||
941 | FreeTxDescriptors(pAC, &pAC->TxPort[1][TX_PRIO_LOW]); | ||
942 | spin_unlock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock); | ||
943 | } | ||
944 | #if 0 /* only if sync. queues used */ | ||
945 | if (IntSrc & IS_XS1_F) { | ||
946 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, | ||
947 | SK_DBGCAT_DRV_INT_SRC, | ||
948 | ("EOF SY TX1 IRQ\n")); | ||
949 | SK_PNMI_CNT_TX_INTR(pAC, 1); | ||
950 | spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock); | ||
951 | FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH); | ||
952 | spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock); | ||
953 | ClearTxIrq(pAC, 0, TX_PRIO_HIGH); | ||
954 | } | ||
955 | if (IntSrc & IS_XS2_F) { | ||
956 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, | ||
957 | SK_DBGCAT_DRV_INT_SRC, | ||
958 | ("EOF SY TX2 IRQ\n")); | ||
959 | SK_PNMI_CNT_TX_INTR(pAC, 1); | ||
960 | spin_lock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock); | ||
961 | FreeTxDescriptors(pAC, 1, TX_PRIO_HIGH); | ||
962 | spin_unlock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock); | ||
963 | ClearTxIrq(pAC, 1, TX_PRIO_HIGH); | ||
964 | } | ||
965 | #endif | ||
966 | #endif | ||
967 | |||
968 | /* do all IO at once */ | ||
969 | if (IntSrc & IS_R1_F) | ||
970 | ClearAndStartRx(pAC, 0); | ||
971 | if (IntSrc & IS_R2_F) | ||
972 | ClearAndStartRx(pAC, 1); | ||
973 | #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ | ||
974 | if (IntSrc & IS_XA1_F) | ||
975 | ClearTxIrq(pAC, 0, TX_PRIO_LOW); | ||
976 | if (IntSrc & IS_XA2_F) | ||
977 | ClearTxIrq(pAC, 1, TX_PRIO_LOW); | ||
978 | #endif | ||
979 | SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc); | ||
980 | } /* while (IntSrc & IRQ_MASK != 0) */ | ||
981 | |||
982 | IntSrc &= pAC->GIni.GIValIrqMask; | ||
983 | if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) { | ||
984 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, | ||
985 | ("SPECIAL IRQ DP-Cards => %x\n", IntSrc)); | ||
986 | pAC->CheckQueue = SK_FALSE; | ||
987 | spin_lock(&pAC->SlowPathLock); | ||
988 | if (IntSrc & SPECIAL_IRQS) | ||
989 | SkGeSirqIsr(pAC, pAC->IoBase, IntSrc); | ||
990 | |||
991 | SkEventDispatcher(pAC, pAC->IoBase); | ||
992 | spin_unlock(&pAC->SlowPathLock); | ||
993 | } | ||
994 | /* | ||
995 | * do it all again is case we cleared an interrupt that | ||
996 | * came in after handling the ring (OUTs may be delayed | ||
997 | * in hardware buffers, but are through after IN) | ||
998 | * | ||
999 | * rroesler: has been commented out and shifted to | ||
1000 | * SkGeDrvEvent(), because it is timer | ||
1001 | * guarded now | ||
1002 | * | ||
1003 | ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE); | ||
1004 | ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE); | ||
1005 | */ | ||
1006 | |||
1007 | if (pAC->CheckQueue) { | ||
1008 | pAC->CheckQueue = SK_FALSE; | ||
1009 | spin_lock(&pAC->SlowPathLock); | ||
1010 | SkEventDispatcher(pAC, pAC->IoBase); | ||
1011 | spin_unlock(&pAC->SlowPathLock); | ||
1012 | } | ||
1013 | |||
1014 | /* IRQ is processed - Enable IRQs again*/ | ||
1015 | SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); | ||
1016 | |||
1017 | return SkIsrRetHandled; | ||
1018 | } /* SkGeIsr */ | ||
1019 | |||
1020 | |||
1021 | /**************************************************************************** | ||
1022 | * | ||
1023 | * SkGeIsrOnePort - handle adapter interrupts for single port adapter | ||
1024 | * | ||
1025 | * Description: | ||
1026 | * The interrupt routine is called when the network adapter | ||
1027 | * generates an interrupt. It may also be called if another device | ||
1028 | * shares this interrupt vector with the driver. | ||
1029 | * This is the same as above, but handles only one port. | ||
1030 | * | ||
1031 | * Returns: N/A | ||
1032 | * | ||
1033 | */ | ||
1034 | static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id) | ||
1035 | { | ||
1036 | struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id; | ||
1037 | DEV_NET *pNet; | ||
1038 | SK_AC *pAC; | ||
1039 | SK_U32 IntSrc; /* interrupts source register contents */ | ||
1040 | |||
1041 | pNet = netdev_priv(dev); | ||
1042 | pAC = pNet->pAC; | ||
1043 | |||
1044 | /* | ||
1045 | * Check and process if its our interrupt | ||
1046 | */ | ||
1047 | SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc); | ||
1048 | if (IntSrc == 0) { | ||
1049 | return SkIsrRetNone; | ||
1050 | } | ||
1051 | |||
1052 | while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) { | ||
1053 | #if 0 /* software irq currently not used */ | ||
1054 | if (IntSrc & IS_IRQ_SW) { | ||
1055 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, | ||
1056 | SK_DBGCAT_DRV_INT_SRC, | ||
1057 | ("Software IRQ\n")); | ||
1058 | } | ||
1059 | #endif | ||
1060 | if (IntSrc & IS_R1_F) { | ||
1061 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, | ||
1062 | SK_DBGCAT_DRV_INT_SRC, | ||
1063 | ("EOF RX1 IRQ\n")); | ||
1064 | ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE); | ||
1065 | SK_PNMI_CNT_RX_INTR(pAC, 0); | ||
1066 | } | ||
1067 | #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ | ||
1068 | if (IntSrc & IS_XA1_F) { | ||
1069 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, | ||
1070 | SK_DBGCAT_DRV_INT_SRC, | ||
1071 | ("EOF AS TX1 IRQ\n")); | ||
1072 | SK_PNMI_CNT_TX_INTR(pAC, 0); | ||
1073 | spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); | ||
1074 | FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]); | ||
1075 | spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); | ||
1076 | } | ||
1077 | #if 0 /* only if sync. queues used */ | ||
1078 | if (IntSrc & IS_XS1_F) { | ||
1079 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, | ||
1080 | SK_DBGCAT_DRV_INT_SRC, | ||
1081 | ("EOF SY TX1 IRQ\n")); | ||
1082 | SK_PNMI_CNT_TX_INTR(pAC, 0); | ||
1083 | spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock); | ||
1084 | FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH); | ||
1085 | spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock); | ||
1086 | ClearTxIrq(pAC, 0, TX_PRIO_HIGH); | ||
1087 | } | ||
1088 | #endif | ||
1089 | #endif | ||
1090 | |||
1091 | /* do all IO at once */ | ||
1092 | if (IntSrc & IS_R1_F) | ||
1093 | ClearAndStartRx(pAC, 0); | ||
1094 | #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ | ||
1095 | if (IntSrc & IS_XA1_F) | ||
1096 | ClearTxIrq(pAC, 0, TX_PRIO_LOW); | ||
1097 | #endif | ||
1098 | SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc); | ||
1099 | } /* while (IntSrc & IRQ_MASK != 0) */ | ||
1100 | |||
1101 | IntSrc &= pAC->GIni.GIValIrqMask; | ||
1102 | if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) { | ||
1103 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, | ||
1104 | ("SPECIAL IRQ SP-Cards => %x\n", IntSrc)); | ||
1105 | pAC->CheckQueue = SK_FALSE; | ||
1106 | spin_lock(&pAC->SlowPathLock); | ||
1107 | if (IntSrc & SPECIAL_IRQS) | ||
1108 | SkGeSirqIsr(pAC, pAC->IoBase, IntSrc); | ||
1109 | |||
1110 | SkEventDispatcher(pAC, pAC->IoBase); | ||
1111 | spin_unlock(&pAC->SlowPathLock); | ||
1112 | } | ||
1113 | /* | ||
1114 | * do it all again is case we cleared an interrupt that | ||
1115 | * came in after handling the ring (OUTs may be delayed | ||
1116 | * in hardware buffers, but are through after IN) | ||
1117 | * | ||
1118 | * rroesler: has been commented out and shifted to | ||
1119 | * SkGeDrvEvent(), because it is timer | ||
1120 | * guarded now | ||
1121 | * | ||
1122 | ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE); | ||
1123 | */ | ||
1124 | |||
1125 | /* IRQ is processed - Enable IRQs again*/ | ||
1126 | SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); | ||
1127 | |||
1128 | return SkIsrRetHandled; | ||
1129 | } /* SkGeIsrOnePort */ | ||
1130 | |||
1131 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
1132 | /**************************************************************************** | ||
1133 | * | ||
1134 | * SkGePollController - polling receive, for netconsole | ||
1135 | * | ||
1136 | * Description: | ||
1137 | * Polling receive - used by netconsole and other diagnostic tools | ||
1138 | * to allow network i/o with interrupts disabled. | ||
1139 | * | ||
1140 | * Returns: N/A | ||
1141 | */ | ||
1142 | static void SkGePollController(struct net_device *dev) | ||
1143 | { | ||
1144 | disable_irq(dev->irq); | ||
1145 | SkGeIsr(dev->irq, dev); | ||
1146 | enable_irq(dev->irq); | ||
1147 | } | ||
1148 | #endif | ||
1149 | |||
1150 | /**************************************************************************** | ||
1151 | * | ||
1152 | * SkGeOpen - handle start of initialized adapter | ||
1153 | * | ||
1154 | * Description: | ||
1155 | * This function starts the initialized adapter. | ||
1156 | * The board level variable is set and the adapter is | ||
1157 | * brought to full functionality. | ||
1158 | * The device flags are set for operation. | ||
1159 | * Do all necessary level 2 initialization, enable interrupts and | ||
1160 | * give start command to RLMT. | ||
1161 | * | ||
1162 | * Returns: | ||
1163 | * 0 on success | ||
1164 | * != 0 on error | ||
1165 | */ | ||
1166 | static int SkGeOpen( | ||
1167 | struct SK_NET_DEVICE *dev) | ||
1168 | { | ||
1169 | DEV_NET *pNet; | ||
1170 | SK_AC *pAC; | ||
1171 | unsigned long Flags; /* for spin lock */ | ||
1172 | int i; | ||
1173 | SK_EVPARA EvPara; /* an event parameter union */ | ||
1174 | |||
1175 | pNet = netdev_priv(dev); | ||
1176 | pAC = pNet->pAC; | ||
1177 | |||
1178 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, | ||
1179 | ("SkGeOpen: pAC=0x%lX:\n", (unsigned long)pAC)); | ||
1180 | |||
1181 | #ifdef SK_DIAG_SUPPORT | ||
1182 | if (pAC->DiagModeActive == DIAG_ACTIVE) { | ||
1183 | if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) { | ||
1184 | return (-1); /* still in use by diag; deny actions */ | ||
1185 | } | ||
1186 | } | ||
1187 | #endif | ||
1188 | |||
1189 | /* Set blink mode */ | ||
1190 | if ((pAC->PciDev->vendor == 0x1186) || (pAC->PciDev->vendor == 0x11ab )) | ||
1191 | pAC->GIni.GILedBlinkCtrl = OEM_CONFIG_VALUE; | ||
1192 | |||
1193 | if (pAC->BoardLevel == SK_INIT_DATA) { | ||
1194 | /* level 1 init common modules here */ | ||
1195 | if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) { | ||
1196 | printk("%s: HWInit (1) failed.\n", pAC->dev[pNet->PortNr]->name); | ||
1197 | return (-1); | ||
1198 | } | ||
1199 | SkI2cInit (pAC, pAC->IoBase, SK_INIT_IO); | ||
1200 | SkEventInit (pAC, pAC->IoBase, SK_INIT_IO); | ||
1201 | SkPnmiInit (pAC, pAC->IoBase, SK_INIT_IO); | ||
1202 | SkAddrInit (pAC, pAC->IoBase, SK_INIT_IO); | ||
1203 | SkRlmtInit (pAC, pAC->IoBase, SK_INIT_IO); | ||
1204 | SkTimerInit (pAC, pAC->IoBase, SK_INIT_IO); | ||
1205 | pAC->BoardLevel = SK_INIT_IO; | ||
1206 | } | ||
1207 | |||
1208 | if (pAC->BoardLevel != SK_INIT_RUN) { | ||
1209 | /* tschilling: Level 2 init modules here, check return value. */ | ||
1210 | if (SkGeInit(pAC, pAC->IoBase, SK_INIT_RUN) != 0) { | ||
1211 | printk("%s: HWInit (2) failed.\n", pAC->dev[pNet->PortNr]->name); | ||
1212 | return (-1); | ||
1213 | } | ||
1214 | SkI2cInit (pAC, pAC->IoBase, SK_INIT_RUN); | ||
1215 | SkEventInit (pAC, pAC->IoBase, SK_INIT_RUN); | ||
1216 | SkPnmiInit (pAC, pAC->IoBase, SK_INIT_RUN); | ||
1217 | SkAddrInit (pAC, pAC->IoBase, SK_INIT_RUN); | ||
1218 | SkRlmtInit (pAC, pAC->IoBase, SK_INIT_RUN); | ||
1219 | SkTimerInit (pAC, pAC->IoBase, SK_INIT_RUN); | ||
1220 | pAC->BoardLevel = SK_INIT_RUN; | ||
1221 | } | ||
1222 | |||
1223 | for (i=0; i<pAC->GIni.GIMacsFound; i++) { | ||
1224 | /* Enable transmit descriptor polling. */ | ||
1225 | SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE); | ||
1226 | FillRxRing(pAC, &pAC->RxPort[i]); | ||
1227 | } | ||
1228 | SkGeYellowLED(pAC, pAC->IoBase, 1); | ||
1229 | |||
1230 | StartDrvCleanupTimer(pAC); | ||
1231 | SkDimEnableModerationIfNeeded(pAC); | ||
1232 | SkDimDisplayModerationSettings(pAC); | ||
1233 | |||
1234 | pAC->GIni.GIValIrqMask &= IRQ_MASK; | ||
1235 | |||
1236 | /* enable Interrupts */ | ||
1237 | SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); | ||
1238 | SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK); | ||
1239 | |||
1240 | spin_lock_irqsave(&pAC->SlowPathLock, Flags); | ||
1241 | |||
1242 | if ((pAC->RlmtMode != 0) && (pAC->MaxPorts == 0)) { | ||
1243 | EvPara.Para32[0] = pAC->RlmtNets; | ||
1244 | EvPara.Para32[1] = -1; | ||
1245 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS, | ||
1246 | EvPara); | ||
1247 | EvPara.Para32[0] = pAC->RlmtMode; | ||
1248 | EvPara.Para32[1] = 0; | ||
1249 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_MODE_CHANGE, | ||
1250 | EvPara); | ||
1251 | } | ||
1252 | |||
1253 | EvPara.Para32[0] = pNet->NetNr; | ||
1254 | EvPara.Para32[1] = -1; | ||
1255 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara); | ||
1256 | SkEventDispatcher(pAC, pAC->IoBase); | ||
1257 | spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); | ||
1258 | |||
1259 | pAC->MaxPorts++; | ||
1260 | |||
1261 | |||
1262 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, | ||
1263 | ("SkGeOpen suceeded\n")); | ||
1264 | |||
1265 | return (0); | ||
1266 | } /* SkGeOpen */ | ||
1267 | |||
1268 | |||
1269 | /**************************************************************************** | ||
1270 | * | ||
1271 | * SkGeClose - Stop initialized adapter | ||
1272 | * | ||
1273 | * Description: | ||
1274 | * Close initialized adapter. | ||
1275 | * | ||
1276 | * Returns: | ||
1277 | * 0 - on success | ||
1278 | * error code - on error | ||
1279 | */ | ||
1280 | static int SkGeClose( | ||
1281 | struct SK_NET_DEVICE *dev) | ||
1282 | { | ||
1283 | DEV_NET *pNet; | ||
1284 | DEV_NET *newPtrNet; | ||
1285 | SK_AC *pAC; | ||
1286 | |||
1287 | unsigned long Flags; /* for spin lock */ | ||
1288 | int i; | ||
1289 | int PortIdx; | ||
1290 | SK_EVPARA EvPara; | ||
1291 | |||
1292 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, | ||
1293 | ("SkGeClose: pAC=0x%lX ", (unsigned long)pAC)); | ||
1294 | |||
1295 | pNet = netdev_priv(dev); | ||
1296 | pAC = pNet->pAC; | ||
1297 | |||
1298 | #ifdef SK_DIAG_SUPPORT | ||
1299 | if (pAC->DiagModeActive == DIAG_ACTIVE) { | ||
1300 | if (pAC->DiagFlowCtrl == SK_FALSE) { | ||
1301 | /* | ||
1302 | ** notify that the interface which has been closed | ||
1303 | ** by operator interaction must not be started up | ||
1304 | ** again when the DIAG has finished. | ||
1305 | */ | ||
1306 | newPtrNet = netdev_priv(pAC->dev[0]); | ||
1307 | if (newPtrNet == pNet) { | ||
1308 | pAC->WasIfUp[0] = SK_FALSE; | ||
1309 | } else { | ||
1310 | pAC->WasIfUp[1] = SK_FALSE; | ||
1311 | } | ||
1312 | return 0; /* return to system everything is fine... */ | ||
1313 | } else { | ||
1314 | pAC->DiagFlowCtrl = SK_FALSE; | ||
1315 | } | ||
1316 | } | ||
1317 | #endif | ||
1318 | |||
1319 | netif_stop_queue(dev); | ||
1320 | |||
1321 | if (pAC->RlmtNets == 1) | ||
1322 | PortIdx = pAC->ActivePort; | ||
1323 | else | ||
1324 | PortIdx = pNet->NetNr; | ||
1325 | |||
1326 | StopDrvCleanupTimer(pAC); | ||
1327 | |||
1328 | /* | ||
1329 | * Clear multicast table, promiscuous mode .... | ||
1330 | */ | ||
1331 | SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0); | ||
1332 | SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx, | ||
1333 | SK_PROM_MODE_NONE); | ||
1334 | |||
1335 | if (pAC->MaxPorts == 1) { | ||
1336 | spin_lock_irqsave(&pAC->SlowPathLock, Flags); | ||
1337 | /* disable interrupts */ | ||
1338 | SK_OUT32(pAC->IoBase, B0_IMSK, 0); | ||
1339 | EvPara.Para32[0] = pNet->NetNr; | ||
1340 | EvPara.Para32[1] = -1; | ||
1341 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); | ||
1342 | SkEventDispatcher(pAC, pAC->IoBase); | ||
1343 | SK_OUT32(pAC->IoBase, B0_IMSK, 0); | ||
1344 | /* stop the hardware */ | ||
1345 | SkGeDeInit(pAC, pAC->IoBase); | ||
1346 | pAC->BoardLevel = SK_INIT_DATA; | ||
1347 | spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); | ||
1348 | } else { | ||
1349 | |||
1350 | spin_lock_irqsave(&pAC->SlowPathLock, Flags); | ||
1351 | EvPara.Para32[0] = pNet->NetNr; | ||
1352 | EvPara.Para32[1] = -1; | ||
1353 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); | ||
1354 | SkPnmiEvent(pAC, pAC->IoBase, SK_PNMI_EVT_XMAC_RESET, EvPara); | ||
1355 | SkEventDispatcher(pAC, pAC->IoBase); | ||
1356 | spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); | ||
1357 | |||
1358 | /* Stop port */ | ||
1359 | spin_lock_irqsave(&pAC->TxPort[pNet->PortNr] | ||
1360 | [TX_PRIO_LOW].TxDesRingLock, Flags); | ||
1361 | SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr, | ||
1362 | SK_STOP_ALL, SK_HARD_RST); | ||
1363 | spin_unlock_irqrestore(&pAC->TxPort[pNet->PortNr] | ||
1364 | [TX_PRIO_LOW].TxDesRingLock, Flags); | ||
1365 | } | ||
1366 | |||
1367 | if (pAC->RlmtNets == 1) { | ||
1368 | /* clear all descriptor rings */ | ||
1369 | for (i=0; i<pAC->GIni.GIMacsFound; i++) { | ||
1370 | ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE); | ||
1371 | ClearRxRing(pAC, &pAC->RxPort[i]); | ||
1372 | ClearTxRing(pAC, &pAC->TxPort[i][TX_PRIO_LOW]); | ||
1373 | } | ||
1374 | } else { | ||
1375 | /* clear port descriptor rings */ | ||
1376 | ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE); | ||
1377 | ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]); | ||
1378 | ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]); | ||
1379 | } | ||
1380 | |||
1381 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, | ||
1382 | ("SkGeClose: done ")); | ||
1383 | |||
1384 | SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA)); | ||
1385 | SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct), | ||
1386 | sizeof(SK_PNMI_STRUCT_DATA)); | ||
1387 | |||
1388 | pAC->MaxPorts--; | ||
1389 | |||
1390 | return (0); | ||
1391 | } /* SkGeClose */ | ||
1392 | |||
1393 | |||
1394 | /***************************************************************************** | ||
1395 | * | ||
1396 | * SkGeXmit - Linux frame transmit function | ||
1397 | * | ||
1398 | * Description: | ||
1399 | * The system calls this function to send frames onto the wire. | ||
1400 | * It puts the frame in the tx descriptor ring. If the ring is | ||
1401 | * full then, the 'tbusy' flag is set. | ||
1402 | * | ||
1403 | * Returns: | ||
1404 | * 0, if everything is ok | ||
1405 | * !=0, on error | ||
1406 | * WARNING: returning 1 in 'tbusy' case caused system crashes (double | ||
1407 | * allocated skb's) !!! | ||
1408 | */ | ||
1409 | static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev) | ||
1410 | { | ||
1411 | DEV_NET *pNet; | ||
1412 | SK_AC *pAC; | ||
1413 | int Rc; /* return code of XmitFrame */ | ||
1414 | |||
1415 | pNet = netdev_priv(dev); | ||
1416 | pAC = pNet->pAC; | ||
1417 | |||
1418 | if ((!skb_shinfo(skb)->nr_frags) || | ||
1419 | (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) { | ||
1420 | /* Don't activate scatter-gather and hardware checksum */ | ||
1421 | |||
1422 | if (pAC->RlmtNets == 2) | ||
1423 | Rc = XmitFrame( | ||
1424 | pAC, | ||
1425 | &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW], | ||
1426 | skb); | ||
1427 | else | ||
1428 | Rc = XmitFrame( | ||
1429 | pAC, | ||
1430 | &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW], | ||
1431 | skb); | ||
1432 | } else { | ||
1433 | /* scatter-gather and hardware TCP checksumming anabled*/ | ||
1434 | if (pAC->RlmtNets == 2) | ||
1435 | Rc = XmitFrameSG( | ||
1436 | pAC, | ||
1437 | &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW], | ||
1438 | skb); | ||
1439 | else | ||
1440 | Rc = XmitFrameSG( | ||
1441 | pAC, | ||
1442 | &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW], | ||
1443 | skb); | ||
1444 | } | ||
1445 | |||
1446 | /* Transmitter out of resources? */ | ||
1447 | if (Rc <= 0) { | ||
1448 | netif_stop_queue(dev); | ||
1449 | } | ||
1450 | |||
1451 | /* If not taken, give buffer ownership back to the | ||
1452 | * queueing layer. | ||
1453 | */ | ||
1454 | if (Rc < 0) | ||
1455 | return (1); | ||
1456 | |||
1457 | dev->trans_start = jiffies; | ||
1458 | return (0); | ||
1459 | } /* SkGeXmit */ | ||
1460 | |||
1461 | |||
1462 | /***************************************************************************** | ||
1463 | * | ||
1464 | * XmitFrame - fill one socket buffer into the transmit ring | ||
1465 | * | ||
1466 | * Description: | ||
1467 | * This function puts a message into the transmit descriptor ring | ||
1468 | * if there is a descriptors left. | ||
1469 | * Linux skb's consist of only one continuous buffer. | ||
1470 | * The first step locks the ring. It is held locked | ||
1471 | * all time to avoid problems with SWITCH_../PORT_RESET. | ||
1472 | * Then the descriptoris allocated. | ||
1473 | * The second part is linking the buffer to the descriptor. | ||
1474 | * At the very last, the Control field of the descriptor | ||
1475 | * is made valid for the BMU and a start TX command is given | ||
1476 | * if necessary. | ||
1477 | * | ||
1478 | * Returns: | ||
1479 | * > 0 - on succes: the number of bytes in the message | ||
1480 | * = 0 - on resource shortage: this frame sent or dropped, now | ||
1481 | * the ring is full ( -> set tbusy) | ||
1482 | * < 0 - on failure: other problems ( -> return failure to upper layers) | ||
1483 | */ | ||
1484 | static int XmitFrame( | ||
1485 | SK_AC *pAC, /* pointer to adapter context */ | ||
1486 | TX_PORT *pTxPort, /* pointer to struct of port to send to */ | ||
1487 | struct sk_buff *pMessage) /* pointer to send-message */ | ||
1488 | { | ||
1489 | TXD *pTxd; /* the rxd to fill */ | ||
1490 | TXD *pOldTxd; | ||
1491 | unsigned long Flags; | ||
1492 | SK_U64 PhysAddr; | ||
1493 | int BytesSend = pMessage->len; | ||
1494 | |||
1495 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ("X")); | ||
1496 | |||
1497 | spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags); | ||
1498 | #ifndef USE_TX_COMPLETE | ||
1499 | FreeTxDescriptors(pAC, pTxPort); | ||
1500 | #endif | ||
1501 | if (pTxPort->TxdRingFree == 0) { | ||
1502 | /* | ||
1503 | ** no enough free descriptors in ring at the moment. | ||
1504 | ** Maybe free'ing some old one help? | ||
1505 | */ | ||
1506 | FreeTxDescriptors(pAC, pTxPort); | ||
1507 | if (pTxPort->TxdRingFree == 0) { | ||
1508 | spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); | ||
1509 | SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex); | ||
1510 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, | ||
1511 | SK_DBGCAT_DRV_TX_PROGRESS, | ||
1512 | ("XmitFrame failed\n")); | ||
1513 | /* | ||
1514 | ** the desired message can not be sent | ||
1515 | ** Because tbusy seems to be set, the message | ||
1516 | ** should not be freed here. It will be used | ||
1517 | ** by the scheduler of the ethernet handler | ||
1518 | */ | ||
1519 | return (-1); | ||
1520 | } | ||
1521 | } | ||
1522 | |||
1523 | /* | ||
1524 | ** If the passed socket buffer is of smaller MTU-size than 60, | ||
1525 | ** copy everything into new buffer and fill all bytes between | ||
1526 | ** the original packet end and the new packet end of 60 with 0x00. | ||
1527 | ** This is to resolve faulty padding by the HW with 0xaa bytes. | ||
1528 | */ | ||
1529 | if (BytesSend < C_LEN_ETHERNET_MINSIZE) { | ||
1530 | if (skb_padto(pMessage, C_LEN_ETHERNET_MINSIZE)) { | ||
1531 | spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); | ||
1532 | return 0; | ||
1533 | } | ||
1534 | pMessage->len = C_LEN_ETHERNET_MINSIZE; | ||
1535 | } | ||
1536 | |||
1537 | /* | ||
1538 | ** advance head counter behind descriptor needed for this frame, | ||
1539 | ** so that needed descriptor is reserved from that on. The next | ||
1540 | ** action will be to add the passed buffer to the TX-descriptor | ||
1541 | */ | ||
1542 | pTxd = pTxPort->pTxdRingHead; | ||
1543 | pTxPort->pTxdRingHead = pTxd->pNextTxd; | ||
1544 | pTxPort->TxdRingFree--; | ||
1545 | |||
1546 | #ifdef SK_DUMP_TX | ||
1547 | DumpMsg(pMessage, "XmitFrame"); | ||
1548 | #endif | ||
1549 | |||
1550 | /* | ||
1551 | ** First step is to map the data to be sent via the adapter onto | ||
1552 | ** the DMA memory. Kernel 2.2 uses virt_to_bus(), but kernels 2.4 | ||
1553 | ** and 2.6 need to use pci_map_page() for that mapping. | ||
1554 | */ | ||
1555 | PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, | ||
1556 | virt_to_page(pMessage->data), | ||
1557 | ((unsigned long) pMessage->data & ~PAGE_MASK), | ||
1558 | pMessage->len, | ||
1559 | PCI_DMA_TODEVICE); | ||
1560 | pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); | ||
1561 | pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32); | ||
1562 | pTxd->pMBuf = pMessage; | ||
1563 | |||
1564 | if (pMessage->ip_summed == CHECKSUM_PARTIAL) { | ||
1565 | u16 hdrlen = skb_transport_offset(pMessage); | ||
1566 | u16 offset = hdrlen + pMessage->csum_offset; | ||
1567 | |||
1568 | if ((ipip_hdr(pMessage)->protocol == IPPROTO_UDP) && | ||
1569 | (pAC->GIni.GIChipRev == 0) && | ||
1570 | (pAC->GIni.GIChipId == CHIP_ID_YUKON)) { | ||
1571 | pTxd->TBControl = BMU_TCP_CHECK; | ||
1572 | } else { | ||
1573 | pTxd->TBControl = BMU_UDP_CHECK; | ||
1574 | } | ||
1575 | |||
1576 | pTxd->TcpSumOfs = 0; | ||
1577 | pTxd->TcpSumSt = hdrlen; | ||
1578 | pTxd->TcpSumWr = offset; | ||
1579 | |||
1580 | pTxd->TBControl |= BMU_OWN | BMU_STF | | ||
1581 | BMU_SW | BMU_EOF | | ||
1582 | #ifdef USE_TX_COMPLETE | ||
1583 | BMU_IRQ_EOF | | ||
1584 | #endif | ||
1585 | pMessage->len; | ||
1586 | } else { | ||
1587 | pTxd->TBControl = BMU_OWN | BMU_STF | BMU_CHECK | | ||
1588 | BMU_SW | BMU_EOF | | ||
1589 | #ifdef USE_TX_COMPLETE | ||
1590 | BMU_IRQ_EOF | | ||
1591 | #endif | ||
1592 | pMessage->len; | ||
1593 | } | ||
1594 | |||
1595 | /* | ||
1596 | ** If previous descriptor already done, give TX start cmd | ||
1597 | */ | ||
1598 | pOldTxd = xchg(&pTxPort->pTxdRingPrev, pTxd); | ||
1599 | if ((pOldTxd->TBControl & BMU_OWN) == 0) { | ||
1600 | SK_OUT8(pTxPort->HwAddr, Q_CSR, CSR_START); | ||
1601 | } | ||
1602 | |||
1603 | /* | ||
1604 | ** after releasing the lock, the skb may immediately be free'd | ||
1605 | */ | ||
1606 | spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); | ||
1607 | if (pTxPort->TxdRingFree != 0) { | ||
1608 | return (BytesSend); | ||
1609 | } else { | ||
1610 | return (0); | ||
1611 | } | ||
1612 | |||
1613 | } /* XmitFrame */ | ||
1614 | |||
1615 | /***************************************************************************** | ||
1616 | * | ||
1617 | * XmitFrameSG - fill one socket buffer into the transmit ring | ||
1618 | * (use SG and TCP/UDP hardware checksumming) | ||
1619 | * | ||
1620 | * Description: | ||
1621 | * This function puts a message into the transmit descriptor ring | ||
1622 | * if there is a descriptors left. | ||
1623 | * | ||
1624 | * Returns: | ||
1625 | * > 0 - on succes: the number of bytes in the message | ||
1626 | * = 0 - on resource shortage: this frame sent or dropped, now | ||
1627 | * the ring is full ( -> set tbusy) | ||
1628 | * < 0 - on failure: other problems ( -> return failure to upper layers) | ||
1629 | */ | ||
1630 | static int XmitFrameSG( | ||
1631 | SK_AC *pAC, /* pointer to adapter context */ | ||
1632 | TX_PORT *pTxPort, /* pointer to struct of port to send to */ | ||
1633 | struct sk_buff *pMessage) /* pointer to send-message */ | ||
1634 | { | ||
1635 | |||
1636 | TXD *pTxd; | ||
1637 | TXD *pTxdFst; | ||
1638 | TXD *pTxdLst; | ||
1639 | int CurrFrag; | ||
1640 | int BytesSend; | ||
1641 | skb_frag_t *sk_frag; | ||
1642 | SK_U64 PhysAddr; | ||
1643 | unsigned long Flags; | ||
1644 | SK_U32 Control; | ||
1645 | |||
1646 | spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags); | ||
1647 | #ifndef USE_TX_COMPLETE | ||
1648 | FreeTxDescriptors(pAC, pTxPort); | ||
1649 | #endif | ||
1650 | if ((skb_shinfo(pMessage)->nr_frags +1) > pTxPort->TxdRingFree) { | ||
1651 | FreeTxDescriptors(pAC, pTxPort); | ||
1652 | if ((skb_shinfo(pMessage)->nr_frags + 1) > pTxPort->TxdRingFree) { | ||
1653 | spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); | ||
1654 | SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex); | ||
1655 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, | ||
1656 | SK_DBGCAT_DRV_TX_PROGRESS, | ||
1657 | ("XmitFrameSG failed - Ring full\n")); | ||
1658 | /* this message can not be sent now */ | ||
1659 | return(-1); | ||
1660 | } | ||
1661 | } | ||
1662 | |||
1663 | pTxd = pTxPort->pTxdRingHead; | ||
1664 | pTxdFst = pTxd; | ||
1665 | pTxdLst = pTxd; | ||
1666 | BytesSend = 0; | ||
1667 | |||
1668 | /* | ||
1669 | ** Map the first fragment (header) into the DMA-space | ||
1670 | */ | ||
1671 | PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, | ||
1672 | virt_to_page(pMessage->data), | ||
1673 | ((unsigned long) pMessage->data & ~PAGE_MASK), | ||
1674 | skb_headlen(pMessage), | ||
1675 | PCI_DMA_TODEVICE); | ||
1676 | |||
1677 | pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); | ||
1678 | pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32); | ||
1679 | |||
1680 | /* | ||
1681 | ** Does the HW need to evaluate checksum for TCP or UDP packets? | ||
1682 | */ | ||
1683 | if (pMessage->ip_summed == CHECKSUM_PARTIAL) { | ||
1684 | u16 hdrlen = skb_transport_offset(pMessage); | ||
1685 | u16 offset = hdrlen + pMessage->csum_offset; | ||
1686 | |||
1687 | Control = BMU_STFWD; | ||
1688 | |||
1689 | /* | ||
1690 | ** We have to use the opcode for tcp here, because the | ||
1691 | ** opcode for udp is not working in the hardware yet | ||
1692 | ** (Revision 2.0) | ||
1693 | */ | ||
1694 | if ((ipip_hdr(pMessage)->protocol == IPPROTO_UDP) && | ||
1695 | (pAC->GIni.GIChipRev == 0) && | ||
1696 | (pAC->GIni.GIChipId == CHIP_ID_YUKON)) { | ||
1697 | Control |= BMU_TCP_CHECK; | ||
1698 | } else { | ||
1699 | Control |= BMU_UDP_CHECK; | ||
1700 | } | ||
1701 | |||
1702 | pTxd->TcpSumOfs = 0; | ||
1703 | pTxd->TcpSumSt = hdrlen; | ||
1704 | pTxd->TcpSumWr = offset; | ||
1705 | } else | ||
1706 | Control = BMU_CHECK | BMU_SW; | ||
1707 | |||
1708 | pTxd->TBControl = BMU_STF | Control | skb_headlen(pMessage); | ||
1709 | |||
1710 | pTxd = pTxd->pNextTxd; | ||
1711 | pTxPort->TxdRingFree--; | ||
1712 | BytesSend += skb_headlen(pMessage); | ||
1713 | |||
1714 | /* | ||
1715 | ** Browse over all SG fragments and map each of them into the DMA space | ||
1716 | */ | ||
1717 | for (CurrFrag = 0; CurrFrag < skb_shinfo(pMessage)->nr_frags; CurrFrag++) { | ||
1718 | sk_frag = &skb_shinfo(pMessage)->frags[CurrFrag]; | ||
1719 | /* | ||
1720 | ** we already have the proper value in entry | ||
1721 | */ | ||
1722 | PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, | ||
1723 | sk_frag->page, | ||
1724 | sk_frag->page_offset, | ||
1725 | sk_frag->size, | ||
1726 | PCI_DMA_TODEVICE); | ||
1727 | |||
1728 | pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); | ||
1729 | pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32); | ||
1730 | pTxd->pMBuf = pMessage; | ||
1731 | |||
1732 | pTxd->TBControl = Control | BMU_OWN | sk_frag->size; | ||
1733 | |||
1734 | /* | ||
1735 | ** Do we have the last fragment? | ||
1736 | */ | ||
1737 | if( (CurrFrag+1) == skb_shinfo(pMessage)->nr_frags ) { | ||
1738 | #ifdef USE_TX_COMPLETE | ||
1739 | pTxd->TBControl |= BMU_EOF | BMU_IRQ_EOF; | ||
1740 | #else | ||
1741 | pTxd->TBControl |= BMU_EOF; | ||
1742 | #endif | ||
1743 | pTxdFst->TBControl |= BMU_OWN | BMU_SW; | ||
1744 | } | ||
1745 | pTxdLst = pTxd; | ||
1746 | pTxd = pTxd->pNextTxd; | ||
1747 | pTxPort->TxdRingFree--; | ||
1748 | BytesSend += sk_frag->size; | ||
1749 | } | ||
1750 | |||
1751 | /* | ||
1752 | ** If previous descriptor already done, give TX start cmd | ||
1753 | */ | ||
1754 | if ((pTxPort->pTxdRingPrev->TBControl & BMU_OWN) == 0) { | ||
1755 | SK_OUT8(pTxPort->HwAddr, Q_CSR, CSR_START); | ||
1756 | } | ||
1757 | |||
1758 | pTxPort->pTxdRingPrev = pTxdLst; | ||
1759 | pTxPort->pTxdRingHead = pTxd; | ||
1760 | |||
1761 | spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); | ||
1762 | |||
1763 | if (pTxPort->TxdRingFree > 0) { | ||
1764 | return (BytesSend); | ||
1765 | } else { | ||
1766 | return (0); | ||
1767 | } | ||
1768 | } | ||
1769 | |||
1770 | /***************************************************************************** | ||
1771 | * | ||
1772 | * FreeTxDescriptors - release descriptors from the descriptor ring | ||
1773 | * | ||
1774 | * Description: | ||
1775 | * This function releases descriptors from a transmit ring if they | ||
1776 | * have been sent by the BMU. | ||
1777 | * If a descriptors is sent, it can be freed and the message can | ||
1778 | * be freed, too. | ||
1779 | * The SOFTWARE controllable bit is used to prevent running around a | ||
1780 | * completely free ring for ever. If this bit is no set in the | ||
1781 | * frame (by XmitFrame), this frame has never been sent or is | ||
1782 | * already freed. | ||
1783 | * The Tx descriptor ring lock must be held while calling this function !!! | ||
1784 | * | ||
1785 | * Returns: | ||
1786 | * none | ||
1787 | */ | ||
1788 | static void FreeTxDescriptors( | ||
1789 | SK_AC *pAC, /* pointer to the adapter context */ | ||
1790 | TX_PORT *pTxPort) /* pointer to destination port structure */ | ||
1791 | { | ||
1792 | TXD *pTxd; /* pointer to the checked descriptor */ | ||
1793 | TXD *pNewTail; /* pointer to 'end' of the ring */ | ||
1794 | SK_U32 Control; /* TBControl field of descriptor */ | ||
1795 | SK_U64 PhysAddr; /* address of DMA mapping */ | ||
1796 | |||
1797 | pNewTail = pTxPort->pTxdRingTail; | ||
1798 | pTxd = pNewTail; | ||
1799 | /* | ||
1800 | ** loop forever; exits if BMU_SW bit not set in start frame | ||
1801 | ** or BMU_OWN bit set in any frame | ||
1802 | */ | ||
1803 | while (1) { | ||
1804 | Control = pTxd->TBControl; | ||
1805 | if ((Control & BMU_SW) == 0) { | ||
1806 | /* | ||
1807 | ** software controllable bit is set in first | ||
1808 | ** fragment when given to BMU. Not set means that | ||
1809 | ** this fragment was never sent or is already | ||
1810 | ** freed ( -> ring completely free now). | ||
1811 | */ | ||
1812 | pTxPort->pTxdRingTail = pTxd; | ||
1813 | netif_wake_queue(pAC->dev[pTxPort->PortIndex]); | ||
1814 | return; | ||
1815 | } | ||
1816 | if (Control & BMU_OWN) { | ||
1817 | pTxPort->pTxdRingTail = pTxd; | ||
1818 | if (pTxPort->TxdRingFree > 0) { | ||
1819 | netif_wake_queue(pAC->dev[pTxPort->PortIndex]); | ||
1820 | } | ||
1821 | return; | ||
1822 | } | ||
1823 | |||
1824 | /* | ||
1825 | ** release the DMA mapping, because until not unmapped | ||
1826 | ** this buffer is considered being under control of the | ||
1827 | ** adapter card! | ||
1828 | */ | ||
1829 | PhysAddr = ((SK_U64) pTxd->VDataHigh) << (SK_U64) 32; | ||
1830 | PhysAddr |= (SK_U64) pTxd->VDataLow; | ||
1831 | pci_unmap_page(pAC->PciDev, PhysAddr, | ||
1832 | pTxd->pMBuf->len, | ||
1833 | PCI_DMA_TODEVICE); | ||
1834 | |||
1835 | if (Control & BMU_EOF) | ||
1836 | DEV_KFREE_SKB_ANY(pTxd->pMBuf); /* free message */ | ||
1837 | |||
1838 | pTxPort->TxdRingFree++; | ||
1839 | pTxd->TBControl &= ~BMU_SW; | ||
1840 | pTxd = pTxd->pNextTxd; /* point behind fragment with EOF */ | ||
1841 | } /* while(forever) */ | ||
1842 | } /* FreeTxDescriptors */ | ||
1843 | |||
1844 | /***************************************************************************** | ||
1845 | * | ||
1846 | * FillRxRing - fill the receive ring with valid descriptors | ||
1847 | * | ||
1848 | * Description: | ||
1849 | * This function fills the receive ring descriptors with data | ||
1850 | * segments and makes them valid for the BMU. | ||
1851 | * The active ring is filled completely, if possible. | ||
1852 | * The non-active ring is filled only partial to save memory. | ||
1853 | * | ||
1854 | * Description of rx ring structure: | ||
1855 | * head - points to the descriptor which will be used next by the BMU | ||
1856 | * tail - points to the next descriptor to give to the BMU | ||
1857 | * | ||
1858 | * Returns: N/A | ||
1859 | */ | ||
1860 | static void FillRxRing( | ||
1861 | SK_AC *pAC, /* pointer to the adapter context */ | ||
1862 | RX_PORT *pRxPort) /* ptr to port struct for which the ring | ||
1863 | should be filled */ | ||
1864 | { | ||
1865 | unsigned long Flags; | ||
1866 | |||
1867 | spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags); | ||
1868 | while (pRxPort->RxdRingFree > pRxPort->RxFillLimit) { | ||
1869 | if(!FillRxDescriptor(pAC, pRxPort)) | ||
1870 | break; | ||
1871 | } | ||
1872 | spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags); | ||
1873 | } /* FillRxRing */ | ||
1874 | |||
1875 | |||
1876 | /***************************************************************************** | ||
1877 | * | ||
1878 | * FillRxDescriptor - fill one buffer into the receive ring | ||
1879 | * | ||
1880 | * Description: | ||
1881 | * The function allocates a new receive buffer and | ||
1882 | * puts it into the next descriptor. | ||
1883 | * | ||
1884 | * Returns: | ||
1885 | * SK_TRUE - a buffer was added to the ring | ||
1886 | * SK_FALSE - a buffer could not be added | ||
1887 | */ | ||
1888 | static SK_BOOL FillRxDescriptor( | ||
1889 | SK_AC *pAC, /* pointer to the adapter context struct */ | ||
1890 | RX_PORT *pRxPort) /* ptr to port struct of ring to fill */ | ||
1891 | { | ||
1892 | struct sk_buff *pMsgBlock; /* pointer to a new message block */ | ||
1893 | RXD *pRxd; /* the rxd to fill */ | ||
1894 | SK_U16 Length; /* data fragment length */ | ||
1895 | SK_U64 PhysAddr; /* physical address of a rx buffer */ | ||
1896 | |||
1897 | pMsgBlock = alloc_skb(pAC->RxBufSize, GFP_ATOMIC); | ||
1898 | if (pMsgBlock == NULL) { | ||
1899 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, | ||
1900 | SK_DBGCAT_DRV_ENTRY, | ||
1901 | ("%s: Allocation of rx buffer failed !\n", | ||
1902 | pAC->dev[pRxPort->PortIndex]->name)); | ||
1903 | SK_PNMI_CNT_NO_RX_BUF(pAC, pRxPort->PortIndex); | ||
1904 | return(SK_FALSE); | ||
1905 | } | ||
1906 | skb_reserve(pMsgBlock, 2); /* to align IP frames */ | ||
1907 | /* skb allocated ok, so add buffer */ | ||
1908 | pRxd = pRxPort->pRxdRingTail; | ||
1909 | pRxPort->pRxdRingTail = pRxd->pNextRxd; | ||
1910 | pRxPort->RxdRingFree--; | ||
1911 | Length = pAC->RxBufSize; | ||
1912 | PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, | ||
1913 | virt_to_page(pMsgBlock->data), | ||
1914 | ((unsigned long) pMsgBlock->data & | ||
1915 | ~PAGE_MASK), | ||
1916 | pAC->RxBufSize - 2, | ||
1917 | PCI_DMA_FROMDEVICE); | ||
1918 | |||
1919 | pRxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); | ||
1920 | pRxd->VDataHigh = (SK_U32) (PhysAddr >> 32); | ||
1921 | pRxd->pMBuf = pMsgBlock; | ||
1922 | pRxd->RBControl = BMU_OWN | | ||
1923 | BMU_STF | | ||
1924 | BMU_IRQ_EOF | | ||
1925 | BMU_TCP_CHECK | | ||
1926 | Length; | ||
1927 | return (SK_TRUE); | ||
1928 | |||
1929 | } /* FillRxDescriptor */ | ||
1930 | |||
1931 | |||
1932 | /***************************************************************************** | ||
1933 | * | ||
1934 | * ReQueueRxBuffer - fill one buffer back into the receive ring | ||
1935 | * | ||
1936 | * Description: | ||
1937 | * Fill a given buffer back into the rx ring. The buffer | ||
1938 | * has been previously allocated and aligned, and its phys. | ||
1939 | * address calculated, so this is no more necessary. | ||
1940 | * | ||
1941 | * Returns: N/A | ||
1942 | */ | ||
1943 | static void ReQueueRxBuffer( | ||
1944 | SK_AC *pAC, /* pointer to the adapter context struct */ | ||
1945 | RX_PORT *pRxPort, /* ptr to port struct of ring to fill */ | ||
1946 | struct sk_buff *pMsg, /* pointer to the buffer */ | ||
1947 | SK_U32 PhysHigh, /* phys address high dword */ | ||
1948 | SK_U32 PhysLow) /* phys address low dword */ | ||
1949 | { | ||
1950 | RXD *pRxd; /* the rxd to fill */ | ||
1951 | SK_U16 Length; /* data fragment length */ | ||
1952 | |||
1953 | pRxd = pRxPort->pRxdRingTail; | ||
1954 | pRxPort->pRxdRingTail = pRxd->pNextRxd; | ||
1955 | pRxPort->RxdRingFree--; | ||
1956 | Length = pAC->RxBufSize; | ||
1957 | |||
1958 | pRxd->VDataLow = PhysLow; | ||
1959 | pRxd->VDataHigh = PhysHigh; | ||
1960 | pRxd->pMBuf = pMsg; | ||
1961 | pRxd->RBControl = BMU_OWN | | ||
1962 | BMU_STF | | ||
1963 | BMU_IRQ_EOF | | ||
1964 | BMU_TCP_CHECK | | ||
1965 | Length; | ||
1966 | return; | ||
1967 | } /* ReQueueRxBuffer */ | ||
1968 | |||
1969 | /***************************************************************************** | ||
1970 | * | ||
1971 | * ReceiveIrq - handle a receive IRQ | ||
1972 | * | ||
1973 | * Description: | ||
1974 | * This function is called when a receive IRQ is set. | ||
1975 | * It walks the receive descriptor ring and sends up all | ||
1976 | * frames that are complete. | ||
1977 | * | ||
1978 | * Returns: N/A | ||
1979 | */ | ||
1980 | static void ReceiveIrq( | ||
1981 | SK_AC *pAC, /* pointer to adapter context */ | ||
1982 | RX_PORT *pRxPort, /* pointer to receive port struct */ | ||
1983 | SK_BOOL SlowPathLock) /* indicates if SlowPathLock is needed */ | ||
1984 | { | ||
1985 | RXD *pRxd; /* pointer to receive descriptors */ | ||
1986 | SK_U32 Control; /* control field of descriptor */ | ||
1987 | struct sk_buff *pMsg; /* pointer to message holding frame */ | ||
1988 | struct sk_buff *pNewMsg; /* pointer to a new message for copying frame */ | ||
1989 | int FrameLength; /* total length of received frame */ | ||
1990 | SK_MBUF *pRlmtMbuf; /* ptr to a buffer for giving a frame to rlmt */ | ||
1991 | SK_EVPARA EvPara; /* an event parameter union */ | ||
1992 | unsigned long Flags; /* for spin lock */ | ||
1993 | int PortIndex = pRxPort->PortIndex; | ||
1994 | unsigned int Offset; | ||
1995 | unsigned int NumBytes; | ||
1996 | unsigned int ForRlmt; | ||
1997 | SK_BOOL IsBc; | ||
1998 | SK_BOOL IsMc; | ||
1999 | SK_BOOL IsBadFrame; /* Bad frame */ | ||
2000 | |||
2001 | SK_U32 FrameStat; | ||
2002 | SK_U64 PhysAddr; | ||
2003 | |||
2004 | rx_start: | ||
2005 | /* do forever; exit if BMU_OWN found */ | ||
2006 | for ( pRxd = pRxPort->pRxdRingHead ; | ||
2007 | pRxPort->RxdRingFree < pAC->RxDescrPerRing ; | ||
2008 | pRxd = pRxd->pNextRxd, | ||
2009 | pRxPort->pRxdRingHead = pRxd, | ||
2010 | pRxPort->RxdRingFree ++) { | ||
2011 | |||
2012 | /* | ||
2013 | * For a better understanding of this loop | ||
2014 | * Go through every descriptor beginning at the head | ||
2015 | * Please note: the ring might be completely received so the OWN bit | ||
2016 | * set is not a good crirteria to leave that loop. | ||
2017 | * Therefore the RingFree counter is used. | ||
2018 | * On entry of this loop pRxd is a pointer to the Rxd that needs | ||
2019 | * to be checked next. | ||
2020 | */ | ||
2021 | |||
2022 | Control = pRxd->RBControl; | ||
2023 | |||
2024 | /* check if this descriptor is ready */ | ||
2025 | if ((Control & BMU_OWN) != 0) { | ||
2026 | /* this descriptor is not yet ready */ | ||
2027 | /* This is the usual end of the loop */ | ||
2028 | /* We don't need to start the ring again */ | ||
2029 | FillRxRing(pAC, pRxPort); | ||
2030 | return; | ||
2031 | } | ||
2032 | pAC->DynIrqModInfo.NbrProcessedDescr++; | ||
2033 | |||
2034 | /* get length of frame and check it */ | ||
2035 | FrameLength = Control & BMU_BBC; | ||
2036 | if (FrameLength > pAC->RxBufSize) { | ||
2037 | goto rx_failed; | ||
2038 | } | ||
2039 | |||
2040 | /* check for STF and EOF */ | ||
2041 | if ((Control & (BMU_STF | BMU_EOF)) != (BMU_STF | BMU_EOF)) { | ||
2042 | goto rx_failed; | ||
2043 | } | ||
2044 | |||
2045 | /* here we have a complete frame in the ring */ | ||
2046 | pMsg = pRxd->pMBuf; | ||
2047 | |||
2048 | FrameStat = pRxd->FrameStat; | ||
2049 | |||
2050 | /* check for frame length mismatch */ | ||
2051 | #define XMR_FS_LEN_SHIFT 18 | ||
2052 | #define GMR_FS_LEN_SHIFT 16 | ||
2053 | if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { | ||
2054 | if (FrameLength != (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)) { | ||
2055 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, | ||
2056 | SK_DBGCAT_DRV_RX_PROGRESS, | ||
2057 | ("skge: Frame length mismatch (%u/%u).\n", | ||
2058 | FrameLength, | ||
2059 | (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT))); | ||
2060 | goto rx_failed; | ||
2061 | } | ||
2062 | } | ||
2063 | else { | ||
2064 | if (FrameLength != (SK_U32) (FrameStat >> GMR_FS_LEN_SHIFT)) { | ||
2065 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, | ||
2066 | SK_DBGCAT_DRV_RX_PROGRESS, | ||
2067 | ("skge: Frame length mismatch (%u/%u).\n", | ||
2068 | FrameLength, | ||
2069 | (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT))); | ||
2070 | goto rx_failed; | ||
2071 | } | ||
2072 | } | ||
2073 | |||
2074 | /* Set Rx Status */ | ||
2075 | if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { | ||
2076 | IsBc = (FrameStat & XMR_FS_BC) != 0; | ||
2077 | IsMc = (FrameStat & XMR_FS_MC) != 0; | ||
2078 | IsBadFrame = (FrameStat & | ||
2079 | (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0; | ||
2080 | } else { | ||
2081 | IsBc = (FrameStat & GMR_FS_BC) != 0; | ||
2082 | IsMc = (FrameStat & GMR_FS_MC) != 0; | ||
2083 | IsBadFrame = (((FrameStat & GMR_FS_ANY_ERR) != 0) || | ||
2084 | ((FrameStat & GMR_FS_RX_OK) == 0)); | ||
2085 | } | ||
2086 | |||
2087 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0, | ||
2088 | ("Received frame of length %d on port %d\n", | ||
2089 | FrameLength, PortIndex)); | ||
2090 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0, | ||
2091 | ("Number of free rx descriptors: %d\n", | ||
2092 | pRxPort->RxdRingFree)); | ||
2093 | /* DumpMsg(pMsg, "Rx"); */ | ||
2094 | |||
2095 | if ((Control & BMU_STAT_VAL) != BMU_STAT_VAL || (IsBadFrame)) { | ||
2096 | #if 0 | ||
2097 | (FrameStat & (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0) { | ||
2098 | #endif | ||
2099 | /* there is a receive error in this frame */ | ||
2100 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, | ||
2101 | SK_DBGCAT_DRV_RX_PROGRESS, | ||
2102 | ("skge: Error in received frame, dropped!\n" | ||
2103 | "Control: %x\nRxStat: %x\n", | ||
2104 | Control, FrameStat)); | ||
2105 | |||
2106 | ReQueueRxBuffer(pAC, pRxPort, pMsg, | ||
2107 | pRxd->VDataHigh, pRxd->VDataLow); | ||
2108 | |||
2109 | continue; | ||
2110 | } | ||
2111 | |||
2112 | /* | ||
2113 | * if short frame then copy data to reduce memory waste | ||
2114 | */ | ||
2115 | if ((FrameLength < SK_COPY_THRESHOLD) && | ||
2116 | ((pNewMsg = alloc_skb(FrameLength+2, GFP_ATOMIC)) != NULL)) { | ||
2117 | /* | ||
2118 | * Short frame detected and allocation successfull | ||
2119 | */ | ||
2120 | /* use new skb and copy data */ | ||
2121 | skb_reserve(pNewMsg, 2); | ||
2122 | skb_put(pNewMsg, FrameLength); | ||
2123 | PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32; | ||
2124 | PhysAddr |= (SK_U64) pRxd->VDataLow; | ||
2125 | |||
2126 | pci_dma_sync_single_for_cpu(pAC->PciDev, | ||
2127 | (dma_addr_t) PhysAddr, | ||
2128 | FrameLength, | ||
2129 | PCI_DMA_FROMDEVICE); | ||
2130 | skb_copy_to_linear_data(pNewMsg, pMsg, FrameLength); | ||
2131 | |||
2132 | pci_dma_sync_single_for_device(pAC->PciDev, | ||
2133 | (dma_addr_t) PhysAddr, | ||
2134 | FrameLength, | ||
2135 | PCI_DMA_FROMDEVICE); | ||
2136 | ReQueueRxBuffer(pAC, pRxPort, pMsg, | ||
2137 | pRxd->VDataHigh, pRxd->VDataLow); | ||
2138 | |||
2139 | pMsg = pNewMsg; | ||
2140 | |||
2141 | } | ||
2142 | else { | ||
2143 | /* | ||
2144 | * if large frame, or SKB allocation failed, pass | ||
2145 | * the SKB directly to the networking | ||
2146 | */ | ||
2147 | |||
2148 | PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32; | ||
2149 | PhysAddr |= (SK_U64) pRxd->VDataLow; | ||
2150 | |||
2151 | /* release the DMA mapping */ | ||
2152 | pci_unmap_single(pAC->PciDev, | ||
2153 | PhysAddr, | ||
2154 | pAC->RxBufSize - 2, | ||
2155 | PCI_DMA_FROMDEVICE); | ||
2156 | |||
2157 | /* set length in message */ | ||
2158 | skb_put(pMsg, FrameLength); | ||
2159 | } /* frame > SK_COPY_TRESHOLD */ | ||
2160 | |||
2161 | #ifdef USE_SK_RX_CHECKSUM | ||
2162 | pMsg->csum = pRxd->TcpSums & 0xffff; | ||
2163 | pMsg->ip_summed = CHECKSUM_COMPLETE; | ||
2164 | #else | ||
2165 | pMsg->ip_summed = CHECKSUM_NONE; | ||
2166 | #endif | ||
2167 | |||
2168 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("V")); | ||
2169 | ForRlmt = SK_RLMT_RX_PROTOCOL; | ||
2170 | #if 0 | ||
2171 | IsBc = (FrameStat & XMR_FS_BC)==XMR_FS_BC; | ||
2172 | #endif | ||
2173 | SK_RLMT_PRE_LOOKAHEAD(pAC, PortIndex, FrameLength, | ||
2174 | IsBc, &Offset, &NumBytes); | ||
2175 | if (NumBytes != 0) { | ||
2176 | #if 0 | ||
2177 | IsMc = (FrameStat & XMR_FS_MC)==XMR_FS_MC; | ||
2178 | #endif | ||
2179 | SK_RLMT_LOOKAHEAD(pAC, PortIndex, | ||
2180 | &pMsg->data[Offset], | ||
2181 | IsBc, IsMc, &ForRlmt); | ||
2182 | } | ||
2183 | if (ForRlmt == SK_RLMT_RX_PROTOCOL) { | ||
2184 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("W")); | ||
2185 | /* send up only frames from active port */ | ||
2186 | if ((PortIndex == pAC->ActivePort) || | ||
2187 | (pAC->RlmtNets == 2)) { | ||
2188 | /* frame for upper layer */ | ||
2189 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("U")); | ||
2190 | #ifdef xDEBUG | ||
2191 | DumpMsg(pMsg, "Rx"); | ||
2192 | #endif | ||
2193 | SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC, | ||
2194 | FrameLength, pRxPort->PortIndex); | ||
2195 | |||
2196 | pMsg->protocol = eth_type_trans(pMsg, | ||
2197 | pAC->dev[pRxPort->PortIndex]); | ||
2198 | netif_rx(pMsg); | ||
2199 | pAC->dev[pRxPort->PortIndex]->last_rx = jiffies; | ||
2200 | } | ||
2201 | else { | ||
2202 | /* drop frame */ | ||
2203 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, | ||
2204 | SK_DBGCAT_DRV_RX_PROGRESS, | ||
2205 | ("D")); | ||
2206 | DEV_KFREE_SKB(pMsg); | ||
2207 | } | ||
2208 | |||
2209 | } /* if not for rlmt */ | ||
2210 | else { | ||
2211 | /* packet for rlmt */ | ||
2212 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, | ||
2213 | SK_DBGCAT_DRV_RX_PROGRESS, ("R")); | ||
2214 | pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC, | ||
2215 | pAC->IoBase, FrameLength); | ||
2216 | if (pRlmtMbuf != NULL) { | ||
2217 | pRlmtMbuf->pNext = NULL; | ||
2218 | pRlmtMbuf->Length = FrameLength; | ||
2219 | pRlmtMbuf->PortIdx = PortIndex; | ||
2220 | EvPara.pParaPtr = pRlmtMbuf; | ||
2221 | memcpy((char*)(pRlmtMbuf->pData), | ||
2222 | (char*)(pMsg->data), | ||
2223 | FrameLength); | ||
2224 | |||
2225 | /* SlowPathLock needed? */ | ||
2226 | if (SlowPathLock == SK_TRUE) { | ||
2227 | spin_lock_irqsave(&pAC->SlowPathLock, Flags); | ||
2228 | SkEventQueue(pAC, SKGE_RLMT, | ||
2229 | SK_RLMT_PACKET_RECEIVED, | ||
2230 | EvPara); | ||
2231 | pAC->CheckQueue = SK_TRUE; | ||
2232 | spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); | ||
2233 | } else { | ||
2234 | SkEventQueue(pAC, SKGE_RLMT, | ||
2235 | SK_RLMT_PACKET_RECEIVED, | ||
2236 | EvPara); | ||
2237 | pAC->CheckQueue = SK_TRUE; | ||
2238 | } | ||
2239 | |||
2240 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, | ||
2241 | SK_DBGCAT_DRV_RX_PROGRESS, | ||
2242 | ("Q")); | ||
2243 | } | ||
2244 | if ((pAC->dev[pRxPort->PortIndex]->flags & | ||
2245 | (IFF_PROMISC | IFF_ALLMULTI)) != 0 || | ||
2246 | (ForRlmt & SK_RLMT_RX_PROTOCOL) == | ||
2247 | SK_RLMT_RX_PROTOCOL) { | ||
2248 | pMsg->protocol = eth_type_trans(pMsg, | ||
2249 | pAC->dev[pRxPort->PortIndex]); | ||
2250 | netif_rx(pMsg); | ||
2251 | pAC->dev[pRxPort->PortIndex]->last_rx = jiffies; | ||
2252 | } | ||
2253 | else { | ||
2254 | DEV_KFREE_SKB(pMsg); | ||
2255 | } | ||
2256 | |||
2257 | } /* if packet for rlmt */ | ||
2258 | } /* for ... scanning the RXD ring */ | ||
2259 | |||
2260 | /* RXD ring is empty -> fill and restart */ | ||
2261 | FillRxRing(pAC, pRxPort); | ||
2262 | /* do not start if called from Close */ | ||
2263 | if (pAC->BoardLevel > SK_INIT_DATA) { | ||
2264 | ClearAndStartRx(pAC, PortIndex); | ||
2265 | } | ||
2266 | return; | ||
2267 | |||
2268 | rx_failed: | ||
2269 | /* remove error frame */ | ||
2270 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR, | ||
2271 | ("Schrottdescriptor, length: 0x%x\n", FrameLength)); | ||
2272 | |||
2273 | /* release the DMA mapping */ | ||
2274 | |||
2275 | PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32; | ||
2276 | PhysAddr |= (SK_U64) pRxd->VDataLow; | ||
2277 | pci_unmap_page(pAC->PciDev, | ||
2278 | PhysAddr, | ||
2279 | pAC->RxBufSize - 2, | ||
2280 | PCI_DMA_FROMDEVICE); | ||
2281 | DEV_KFREE_SKB_IRQ(pRxd->pMBuf); | ||
2282 | pRxd->pMBuf = NULL; | ||
2283 | pRxPort->RxdRingFree++; | ||
2284 | pRxPort->pRxdRingHead = pRxd->pNextRxd; | ||
2285 | goto rx_start; | ||
2286 | |||
2287 | } /* ReceiveIrq */ | ||
2288 | |||
2289 | |||
2290 | /***************************************************************************** | ||
2291 | * | ||
2292 | * ClearAndStartRx - give a start receive command to BMU, clear IRQ | ||
2293 | * | ||
2294 | * Description: | ||
2295 | * This function sends a start command and a clear interrupt | ||
2296 | * command for one receive queue to the BMU. | ||
2297 | * | ||
2298 | * Returns: N/A | ||
2299 | * none | ||
2300 | */ | ||
2301 | static void ClearAndStartRx( | ||
2302 | SK_AC *pAC, /* pointer to the adapter context */ | ||
2303 | int PortIndex) /* index of the receive port (XMAC) */ | ||
2304 | { | ||
2305 | SK_OUT8(pAC->IoBase, | ||
2306 | RxQueueAddr[PortIndex]+Q_CSR, | ||
2307 | CSR_START | CSR_IRQ_CL_F); | ||
2308 | } /* ClearAndStartRx */ | ||
2309 | |||
2310 | |||
2311 | /***************************************************************************** | ||
2312 | * | ||
2313 | * ClearTxIrq - give a clear transmit IRQ command to BMU | ||
2314 | * | ||
2315 | * Description: | ||
2316 | * This function sends a clear tx IRQ command for one | ||
2317 | * transmit queue to the BMU. | ||
2318 | * | ||
2319 | * Returns: N/A | ||
2320 | */ | ||
2321 | static void ClearTxIrq( | ||
2322 | SK_AC *pAC, /* pointer to the adapter context */ | ||
2323 | int PortIndex, /* index of the transmit port (XMAC) */ | ||
2324 | int Prio) /* priority or normal queue */ | ||
2325 | { | ||
2326 | SK_OUT8(pAC->IoBase, | ||
2327 | TxQueueAddr[PortIndex][Prio]+Q_CSR, | ||
2328 | CSR_IRQ_CL_F); | ||
2329 | } /* ClearTxIrq */ | ||
2330 | |||
2331 | |||
2332 | /***************************************************************************** | ||
2333 | * | ||
2334 | * ClearRxRing - remove all buffers from the receive ring | ||
2335 | * | ||
2336 | * Description: | ||
2337 | * This function removes all receive buffers from the ring. | ||
2338 | * The receive BMU must be stopped before calling this function. | ||
2339 | * | ||
2340 | * Returns: N/A | ||
2341 | */ | ||
2342 | static void ClearRxRing( | ||
2343 | SK_AC *pAC, /* pointer to adapter context */ | ||
2344 | RX_PORT *pRxPort) /* pointer to rx port struct */ | ||
2345 | { | ||
2346 | RXD *pRxd; /* pointer to the current descriptor */ | ||
2347 | unsigned long Flags; | ||
2348 | SK_U64 PhysAddr; | ||
2349 | |||
2350 | if (pRxPort->RxdRingFree == pAC->RxDescrPerRing) { | ||
2351 | return; | ||
2352 | } | ||
2353 | spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags); | ||
2354 | pRxd = pRxPort->pRxdRingHead; | ||
2355 | do { | ||
2356 | if (pRxd->pMBuf != NULL) { | ||
2357 | |||
2358 | PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32; | ||
2359 | PhysAddr |= (SK_U64) pRxd->VDataLow; | ||
2360 | pci_unmap_page(pAC->PciDev, | ||
2361 | PhysAddr, | ||
2362 | pAC->RxBufSize - 2, | ||
2363 | PCI_DMA_FROMDEVICE); | ||
2364 | DEV_KFREE_SKB(pRxd->pMBuf); | ||
2365 | pRxd->pMBuf = NULL; | ||
2366 | } | ||
2367 | pRxd->RBControl &= BMU_OWN; | ||
2368 | pRxd = pRxd->pNextRxd; | ||
2369 | pRxPort->RxdRingFree++; | ||
2370 | } while (pRxd != pRxPort->pRxdRingTail); | ||
2371 | pRxPort->pRxdRingTail = pRxPort->pRxdRingHead; | ||
2372 | spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags); | ||
2373 | } /* ClearRxRing */ | ||
2374 | |||
2375 | /***************************************************************************** | ||
2376 | * | ||
2377 | * ClearTxRing - remove all buffers from the transmit ring | ||
2378 | * | ||
2379 | * Description: | ||
2380 | * This function removes all transmit buffers from the ring. | ||
2381 | * The transmit BMU must be stopped before calling this function | ||
2382 | * and transmitting at the upper level must be disabled. | ||
2383 | * The BMU own bit of all descriptors is cleared, the rest is | ||
2384 | * done by calling FreeTxDescriptors. | ||
2385 | * | ||
2386 | * Returns: N/A | ||
2387 | */ | ||
2388 | static void ClearTxRing( | ||
2389 | SK_AC *pAC, /* pointer to adapter context */ | ||
2390 | TX_PORT *pTxPort) /* pointer to tx prt struct */ | ||
2391 | { | ||
2392 | TXD *pTxd; /* pointer to the current descriptor */ | ||
2393 | int i; | ||
2394 | unsigned long Flags; | ||
2395 | |||
2396 | spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags); | ||
2397 | pTxd = pTxPort->pTxdRingHead; | ||
2398 | for (i=0; i<pAC->TxDescrPerRing; i++) { | ||
2399 | pTxd->TBControl &= ~BMU_OWN; | ||
2400 | pTxd = pTxd->pNextTxd; | ||
2401 | } | ||
2402 | FreeTxDescriptors(pAC, pTxPort); | ||
2403 | spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); | ||
2404 | } /* ClearTxRing */ | ||
2405 | |||
2406 | /***************************************************************************** | ||
2407 | * | ||
2408 | * SkGeSetMacAddr - Set the hardware MAC address | ||
2409 | * | ||
2410 | * Description: | ||
2411 | * This function sets the MAC address used by the adapter. | ||
2412 | * | ||
2413 | * Returns: | ||
2414 | * 0, if everything is ok | ||
2415 | * !=0, on error | ||
2416 | */ | ||
2417 | static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p) | ||
2418 | { | ||
2419 | |||
2420 | DEV_NET *pNet = netdev_priv(dev); | ||
2421 | SK_AC *pAC = pNet->pAC; | ||
2422 | |||
2423 | struct sockaddr *addr = p; | ||
2424 | unsigned long Flags; | ||
2425 | |||
2426 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, | ||
2427 | ("SkGeSetMacAddr starts now...\n")); | ||
2428 | if(netif_running(dev)) | ||
2429 | return -EBUSY; | ||
2430 | |||
2431 | memcpy(dev->dev_addr, addr->sa_data,dev->addr_len); | ||
2432 | |||
2433 | spin_lock_irqsave(&pAC->SlowPathLock, Flags); | ||
2434 | |||
2435 | if (pAC->RlmtNets == 2) | ||
2436 | SkAddrOverride(pAC, pAC->IoBase, pNet->NetNr, | ||
2437 | (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS); | ||
2438 | else | ||
2439 | SkAddrOverride(pAC, pAC->IoBase, pAC->ActivePort, | ||
2440 | (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS); | ||
2441 | |||
2442 | |||
2443 | |||
2444 | spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); | ||
2445 | return 0; | ||
2446 | } /* SkGeSetMacAddr */ | ||
2447 | |||
2448 | |||
2449 | /***************************************************************************** | ||
2450 | * | ||
2451 | * SkGeSetRxMode - set receive mode | ||
2452 | * | ||
2453 | * Description: | ||
2454 | * This function sets the receive mode of an adapter. The adapter | ||
2455 | * supports promiscuous mode, allmulticast mode and a number of | ||
2456 | * multicast addresses. If more multicast addresses the available | ||
2457 | * are selected, a hash function in the hardware is used. | ||
2458 | * | ||
2459 | * Returns: | ||
2460 | * 0, if everything is ok | ||
2461 | * !=0, on error | ||
2462 | */ | ||
2463 | static void SkGeSetRxMode(struct SK_NET_DEVICE *dev) | ||
2464 | { | ||
2465 | |||
2466 | DEV_NET *pNet; | ||
2467 | SK_AC *pAC; | ||
2468 | |||
2469 | struct dev_mc_list *pMcList; | ||
2470 | int i; | ||
2471 | int PortIdx; | ||
2472 | unsigned long Flags; | ||
2473 | |||
2474 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, | ||
2475 | ("SkGeSetRxMode starts now... ")); | ||
2476 | |||
2477 | pNet = netdev_priv(dev); | ||
2478 | pAC = pNet->pAC; | ||
2479 | if (pAC->RlmtNets == 1) | ||
2480 | PortIdx = pAC->ActivePort; | ||
2481 | else | ||
2482 | PortIdx = pNet->NetNr; | ||
2483 | |||
2484 | spin_lock_irqsave(&pAC->SlowPathLock, Flags); | ||
2485 | if (dev->flags & IFF_PROMISC) { | ||
2486 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, | ||
2487 | ("PROMISCUOUS mode\n")); | ||
2488 | SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx, | ||
2489 | SK_PROM_MODE_LLC); | ||
2490 | } else if (dev->flags & IFF_ALLMULTI) { | ||
2491 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, | ||
2492 | ("ALLMULTI mode\n")); | ||
2493 | SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx, | ||
2494 | SK_PROM_MODE_ALL_MC); | ||
2495 | } else { | ||
2496 | SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx, | ||
2497 | SK_PROM_MODE_NONE); | ||
2498 | SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0); | ||
2499 | |||
2500 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, | ||
2501 | ("Number of MC entries: %d ", dev->mc_count)); | ||
2502 | |||
2503 | pMcList = dev->mc_list; | ||
2504 | for (i=0; i<dev->mc_count; i++, pMcList = pMcList->next) { | ||
2505 | SkAddrMcAdd(pAC, pAC->IoBase, PortIdx, | ||
2506 | (SK_MAC_ADDR*)pMcList->dmi_addr, 0); | ||
2507 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MCA, | ||
2508 | ("%02x:%02x:%02x:%02x:%02x:%02x\n", | ||
2509 | pMcList->dmi_addr[0], | ||
2510 | pMcList->dmi_addr[1], | ||
2511 | pMcList->dmi_addr[2], | ||
2512 | pMcList->dmi_addr[3], | ||
2513 | pMcList->dmi_addr[4], | ||
2514 | pMcList->dmi_addr[5])); | ||
2515 | } | ||
2516 | SkAddrMcUpdate(pAC, pAC->IoBase, PortIdx); | ||
2517 | } | ||
2518 | spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); | ||
2519 | |||
2520 | return; | ||
2521 | } /* SkGeSetRxMode */ | ||
2522 | |||
2523 | |||
2524 | /***************************************************************************** | ||
2525 | * | ||
2526 | * SkGeChangeMtu - set the MTU to another value | ||
2527 | * | ||
2528 | * Description: | ||
2529 | * This function sets is called whenever the MTU size is changed | ||
2530 | * (ifconfig mtu xxx dev ethX). If the MTU is bigger than standard | ||
2531 | * ethernet MTU size, long frame support is activated. | ||
2532 | * | ||
2533 | * Returns: | ||
2534 | * 0, if everything is ok | ||
2535 | * !=0, on error | ||
2536 | */ | ||
2537 | static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int NewMtu) | ||
2538 | { | ||
2539 | DEV_NET *pNet; | ||
2540 | struct net_device *pOtherDev; | ||
2541 | SK_AC *pAC; | ||
2542 | unsigned long Flags; | ||
2543 | int i; | ||
2544 | SK_EVPARA EvPara; | ||
2545 | |||
2546 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, | ||
2547 | ("SkGeChangeMtu starts now...\n")); | ||
2548 | |||
2549 | pNet = netdev_priv(dev); | ||
2550 | pAC = pNet->pAC; | ||
2551 | |||
2552 | if ((NewMtu < 68) || (NewMtu > SK_JUMBO_MTU)) { | ||
2553 | return -EINVAL; | ||
2554 | } | ||
2555 | |||
2556 | if(pAC->BoardLevel != SK_INIT_RUN) { | ||
2557 | return -EINVAL; | ||
2558 | } | ||
2559 | |||
2560 | #ifdef SK_DIAG_SUPPORT | ||
2561 | if (pAC->DiagModeActive == DIAG_ACTIVE) { | ||
2562 | if (pAC->DiagFlowCtrl == SK_FALSE) { | ||
2563 | return -1; /* still in use, deny any actions of MTU */ | ||
2564 | } else { | ||
2565 | pAC->DiagFlowCtrl = SK_FALSE; | ||
2566 | } | ||
2567 | } | ||
2568 | #endif | ||
2569 | |||
2570 | pOtherDev = pAC->dev[1 - pNet->NetNr]; | ||
2571 | |||
2572 | if ( netif_running(pOtherDev) && (pOtherDev->mtu > 1500) | ||
2573 | && (NewMtu <= 1500)) | ||
2574 | return 0; | ||
2575 | |||
2576 | pAC->RxBufSize = NewMtu + 32; | ||
2577 | dev->mtu = NewMtu; | ||
2578 | |||
2579 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, | ||
2580 | ("New MTU: %d\n", NewMtu)); | ||
2581 | |||
2582 | /* | ||
2583 | ** Prevent any reconfiguration while changing the MTU | ||
2584 | ** by disabling any interrupts | ||
2585 | */ | ||
2586 | SK_OUT32(pAC->IoBase, B0_IMSK, 0); | ||
2587 | spin_lock_irqsave(&pAC->SlowPathLock, Flags); | ||
2588 | |||
2589 | /* | ||
2590 | ** Notify RLMT that any ports are to be stopped | ||
2591 | */ | ||
2592 | EvPara.Para32[0] = 0; | ||
2593 | EvPara.Para32[1] = -1; | ||
2594 | if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { | ||
2595 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); | ||
2596 | EvPara.Para32[0] = 1; | ||
2597 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); | ||
2598 | } else { | ||
2599 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); | ||
2600 | } | ||
2601 | |||
2602 | /* | ||
2603 | ** After calling the SkEventDispatcher(), RLMT is aware about | ||
2604 | ** the stopped ports -> configuration can take place! | ||
2605 | */ | ||
2606 | SkEventDispatcher(pAC, pAC->IoBase); | ||
2607 | |||
2608 | for (i=0; i<pAC->GIni.GIMacsFound; i++) { | ||
2609 | spin_lock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock); | ||
2610 | netif_stop_queue(pAC->dev[i]); | ||
2611 | |||
2612 | } | ||
2613 | |||
2614 | /* | ||
2615 | ** Depending on the desired MTU size change, a different number of | ||
2616 | ** RX buffers need to be allocated | ||
2617 | */ | ||
2618 | if (NewMtu > 1500) { | ||
2619 | /* | ||
2620 | ** Use less rx buffers | ||
2621 | */ | ||
2622 | for (i=0; i<pAC->GIni.GIMacsFound; i++) { | ||
2623 | if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { | ||
2624 | pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - | ||
2625 | (pAC->RxDescrPerRing / 4); | ||
2626 | } else { | ||
2627 | if (i == pAC->ActivePort) { | ||
2628 | pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - | ||
2629 | (pAC->RxDescrPerRing / 4); | ||
2630 | } else { | ||
2631 | pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - | ||
2632 | (pAC->RxDescrPerRing / 10); | ||
2633 | } | ||
2634 | } | ||
2635 | } | ||
2636 | } else { | ||
2637 | /* | ||
2638 | ** Use the normal amount of rx buffers | ||
2639 | */ | ||
2640 | for (i=0; i<pAC->GIni.GIMacsFound; i++) { | ||
2641 | if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { | ||
2642 | pAC->RxPort[i].RxFillLimit = 1; | ||
2643 | } else { | ||
2644 | if (i == pAC->ActivePort) { | ||
2645 | pAC->RxPort[i].RxFillLimit = 1; | ||
2646 | } else { | ||
2647 | pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - | ||
2648 | (pAC->RxDescrPerRing / 4); | ||
2649 | } | ||
2650 | } | ||
2651 | } | ||
2652 | } | ||
2653 | |||
2654 | SkGeDeInit(pAC, pAC->IoBase); | ||
2655 | |||
2656 | /* | ||
2657 | ** enable/disable hardware support for long frames | ||
2658 | */ | ||
2659 | if (NewMtu > 1500) { | ||
2660 | // pAC->JumboActivated = SK_TRUE; /* is never set back !!! */ | ||
2661 | pAC->GIni.GIPortUsage = SK_JUMBO_LINK; | ||
2662 | } else { | ||
2663 | if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { | ||
2664 | pAC->GIni.GIPortUsage = SK_MUL_LINK; | ||
2665 | } else { | ||
2666 | pAC->GIni.GIPortUsage = SK_RED_LINK; | ||
2667 | } | ||
2668 | } | ||
2669 | |||
2670 | SkGeInit( pAC, pAC->IoBase, SK_INIT_IO); | ||
2671 | SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO); | ||
2672 | SkEventInit(pAC, pAC->IoBase, SK_INIT_IO); | ||
2673 | SkPnmiInit( pAC, pAC->IoBase, SK_INIT_IO); | ||
2674 | SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO); | ||
2675 | SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO); | ||
2676 | SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO); | ||
2677 | |||
2678 | /* | ||
2679 | ** tschilling: | ||
2680 | ** Speed and others are set back to default in level 1 init! | ||
2681 | */ | ||
2682 | GetConfiguration(pAC); | ||
2683 | |||
2684 | SkGeInit( pAC, pAC->IoBase, SK_INIT_RUN); | ||
2685 | SkI2cInit( pAC, pAC->IoBase, SK_INIT_RUN); | ||
2686 | SkEventInit(pAC, pAC->IoBase, SK_INIT_RUN); | ||
2687 | SkPnmiInit( pAC, pAC->IoBase, SK_INIT_RUN); | ||
2688 | SkAddrInit( pAC, pAC->IoBase, SK_INIT_RUN); | ||
2689 | SkRlmtInit( pAC, pAC->IoBase, SK_INIT_RUN); | ||
2690 | SkTimerInit(pAC, pAC->IoBase, SK_INIT_RUN); | ||
2691 | |||
2692 | /* | ||
2693 | ** clear and reinit the rx rings here | ||
2694 | */ | ||
2695 | for (i=0; i<pAC->GIni.GIMacsFound; i++) { | ||
2696 | ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE); | ||
2697 | ClearRxRing(pAC, &pAC->RxPort[i]); | ||
2698 | FillRxRing(pAC, &pAC->RxPort[i]); | ||
2699 | |||
2700 | /* | ||
2701 | ** Enable transmit descriptor polling | ||
2702 | */ | ||
2703 | SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE); | ||
2704 | FillRxRing(pAC, &pAC->RxPort[i]); | ||
2705 | }; | ||
2706 | |||
2707 | SkGeYellowLED(pAC, pAC->IoBase, 1); | ||
2708 | SkDimEnableModerationIfNeeded(pAC); | ||
2709 | SkDimDisplayModerationSettings(pAC); | ||
2710 | |||
2711 | netif_start_queue(pAC->dev[pNet->PortNr]); | ||
2712 | for (i=pAC->GIni.GIMacsFound-1; i>=0; i--) { | ||
2713 | spin_unlock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock); | ||
2714 | } | ||
2715 | |||
2716 | /* | ||
2717 | ** Enable Interrupts again | ||
2718 | */ | ||
2719 | SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); | ||
2720 | SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK); | ||
2721 | |||
2722 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara); | ||
2723 | SkEventDispatcher(pAC, pAC->IoBase); | ||
2724 | |||
2725 | /* | ||
2726 | ** Notify RLMT about the changing and restarting one (or more) ports | ||
2727 | */ | ||
2728 | if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { | ||
2729 | EvPara.Para32[0] = pAC->RlmtNets; | ||
2730 | EvPara.Para32[1] = -1; | ||
2731 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS, EvPara); | ||
2732 | EvPara.Para32[0] = pNet->PortNr; | ||
2733 | EvPara.Para32[1] = -1; | ||
2734 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara); | ||
2735 | |||
2736 | if (netif_running(pOtherDev)) { | ||
2737 | DEV_NET *pOtherNet = netdev_priv(pOtherDev); | ||
2738 | EvPara.Para32[0] = pOtherNet->PortNr; | ||
2739 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara); | ||
2740 | } | ||
2741 | } else { | ||
2742 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara); | ||
2743 | } | ||
2744 | |||
2745 | SkEventDispatcher(pAC, pAC->IoBase); | ||
2746 | spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); | ||
2747 | |||
2748 | /* | ||
2749 | ** While testing this driver with latest kernel 2.5 (2.5.70), it | ||
2750 | ** seems as if upper layers have a problem to handle a successful | ||
2751 | ** return value of '0'. If such a zero is returned, the complete | ||
2752 | ** system hangs for several minutes (!), which is in acceptable. | ||
2753 | ** | ||
2754 | ** Currently it is not clear, what the exact reason for this problem | ||
2755 | ** is. The implemented workaround for 2.5 is to return the desired | ||
2756 | ** new MTU size if all needed changes for the new MTU size where | ||
2757 | ** performed. In kernels 2.2 and 2.4, a zero value is returned, | ||
2758 | ** which indicates the successful change of the mtu-size. | ||
2759 | */ | ||
2760 | return NewMtu; | ||
2761 | |||
2762 | } /* SkGeChangeMtu */ | ||
2763 | |||
2764 | |||
2765 | /***************************************************************************** | ||
2766 | * | ||
2767 | * SkGeStats - return ethernet device statistics | ||
2768 | * | ||
2769 | * Description: | ||
2770 | * This function return statistic data about the ethernet device | ||
2771 | * to the operating system. | ||
2772 | * | ||
2773 | * Returns: | ||
2774 | * pointer to the statistic structure. | ||
2775 | */ | ||
2776 | static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev) | ||
2777 | { | ||
2778 | DEV_NET *pNet = netdev_priv(dev); | ||
2779 | SK_AC *pAC = pNet->pAC; | ||
2780 | SK_PNMI_STRUCT_DATA *pPnmiStruct; /* structure for all Pnmi-Data */ | ||
2781 | SK_PNMI_STAT *pPnmiStat; /* pointer to virtual XMAC stat. data */ | ||
2782 | SK_PNMI_CONF *pPnmiConf; /* pointer to virtual link config. */ | ||
2783 | unsigned int Size; /* size of pnmi struct */ | ||
2784 | unsigned long Flags; /* for spin lock */ | ||
2785 | |||
2786 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, | ||
2787 | ("SkGeStats starts now...\n")); | ||
2788 | pPnmiStruct = &pAC->PnmiStruct; | ||
2789 | |||
2790 | #ifdef SK_DIAG_SUPPORT | ||
2791 | if ((pAC->DiagModeActive == DIAG_NOTACTIVE) && | ||
2792 | (pAC->BoardLevel == SK_INIT_RUN)) { | ||
2793 | #endif | ||
2794 | SK_MEMSET(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA)); | ||
2795 | spin_lock_irqsave(&pAC->SlowPathLock, Flags); | ||
2796 | Size = SK_PNMI_STRUCT_SIZE; | ||
2797 | SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, pNet->NetNr); | ||
2798 | spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); | ||
2799 | #ifdef SK_DIAG_SUPPORT | ||
2800 | } | ||
2801 | #endif | ||
2802 | |||
2803 | pPnmiStat = &pPnmiStruct->Stat[0]; | ||
2804 | pPnmiConf = &pPnmiStruct->Conf[0]; | ||
2805 | |||
2806 | pAC->stats.rx_packets = (SK_U32) pPnmiStruct->RxDeliveredCts & 0xFFFFFFFF; | ||
2807 | pAC->stats.tx_packets = (SK_U32) pPnmiStat->StatTxOkCts & 0xFFFFFFFF; | ||
2808 | pAC->stats.rx_bytes = (SK_U32) pPnmiStruct->RxOctetsDeliveredCts; | ||
2809 | pAC->stats.tx_bytes = (SK_U32) pPnmiStat->StatTxOctetsOkCts; | ||
2810 | |||
2811 | if (dev->mtu <= 1500) { | ||
2812 | pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF; | ||
2813 | } else { | ||
2814 | pAC->stats.rx_errors = (SK_U32) ((pPnmiStruct->InErrorsCts - | ||
2815 | pPnmiStat->StatRxTooLongCts) & 0xFFFFFFFF); | ||
2816 | } | ||
2817 | |||
2818 | |||
2819 | if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && pAC->HWRevision < 12) | ||
2820 | pAC->stats.rx_errors = pAC->stats.rx_errors - pPnmiStat->StatRxShortsCts; | ||
2821 | |||
2822 | pAC->stats.tx_errors = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF; | ||
2823 | pAC->stats.rx_dropped = (SK_U32) pPnmiStruct->RxNoBufCts & 0xFFFFFFFF; | ||
2824 | pAC->stats.tx_dropped = (SK_U32) pPnmiStruct->TxNoBufCts & 0xFFFFFFFF; | ||
2825 | pAC->stats.multicast = (SK_U32) pPnmiStat->StatRxMulticastOkCts & 0xFFFFFFFF; | ||
2826 | pAC->stats.collisions = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF; | ||
2827 | |||
2828 | /* detailed rx_errors: */ | ||
2829 | pAC->stats.rx_length_errors = (SK_U32) pPnmiStat->StatRxRuntCts & 0xFFFFFFFF; | ||
2830 | pAC->stats.rx_over_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF; | ||
2831 | pAC->stats.rx_crc_errors = (SK_U32) pPnmiStat->StatRxFcsCts & 0xFFFFFFFF; | ||
2832 | pAC->stats.rx_frame_errors = (SK_U32) pPnmiStat->StatRxFramingCts & 0xFFFFFFFF; | ||
2833 | pAC->stats.rx_fifo_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF; | ||
2834 | pAC->stats.rx_missed_errors = (SK_U32) pPnmiStat->StatRxMissedCts & 0xFFFFFFFF; | ||
2835 | |||
2836 | /* detailed tx_errors */ | ||
2837 | pAC->stats.tx_aborted_errors = (SK_U32) 0; | ||
2838 | pAC->stats.tx_carrier_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF; | ||
2839 | pAC->stats.tx_fifo_errors = (SK_U32) pPnmiStat->StatTxFifoUnderrunCts & 0xFFFFFFFF; | ||
2840 | pAC->stats.tx_heartbeat_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF; | ||
2841 | pAC->stats.tx_window_errors = (SK_U32) 0; | ||
2842 | |||
2843 | return(&pAC->stats); | ||
2844 | } /* SkGeStats */ | ||
2845 | |||
2846 | /* | ||
2847 | * Basic MII register access | ||
2848 | */ | ||
2849 | static int SkGeMiiIoctl(struct net_device *dev, | ||
2850 | struct mii_ioctl_data *data, int cmd) | ||
2851 | { | ||
2852 | DEV_NET *pNet = netdev_priv(dev); | ||
2853 | SK_AC *pAC = pNet->pAC; | ||
2854 | SK_IOC IoC = pAC->IoBase; | ||
2855 | int Port = pNet->PortNr; | ||
2856 | SK_GEPORT *pPrt = &pAC->GIni.GP[Port]; | ||
2857 | unsigned long Flags; | ||
2858 | int err = 0; | ||
2859 | int reg = data->reg_num & 0x1f; | ||
2860 | SK_U16 val = data->val_in; | ||
2861 | |||
2862 | if (!netif_running(dev)) | ||
2863 | return -ENODEV; /* Phy still in reset */ | ||
2864 | |||
2865 | spin_lock_irqsave(&pAC->SlowPathLock, Flags); | ||
2866 | switch(cmd) { | ||
2867 | case SIOCGMIIPHY: | ||
2868 | data->phy_id = pPrt->PhyAddr; | ||
2869 | |||
2870 | /* fallthru */ | ||
2871 | case SIOCGMIIREG: | ||
2872 | if (pAC->GIni.GIGenesis) | ||
2873 | SkXmPhyRead(pAC, IoC, Port, reg, &val); | ||
2874 | else | ||
2875 | SkGmPhyRead(pAC, IoC, Port, reg, &val); | ||
2876 | |||
2877 | data->val_out = val; | ||
2878 | break; | ||
2879 | |||
2880 | case SIOCSMIIREG: | ||
2881 | if (!capable(CAP_NET_ADMIN)) | ||
2882 | err = -EPERM; | ||
2883 | |||
2884 | else if (pAC->GIni.GIGenesis) | ||
2885 | SkXmPhyWrite(pAC, IoC, Port, reg, val); | ||
2886 | else | ||
2887 | SkGmPhyWrite(pAC, IoC, Port, reg, val); | ||
2888 | break; | ||
2889 | default: | ||
2890 | err = -EOPNOTSUPP; | ||
2891 | } | ||
2892 | spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); | ||
2893 | return err; | ||
2894 | } | ||
2895 | |||
2896 | |||
2897 | /***************************************************************************** | ||
2898 | * | ||
2899 | * SkGeIoctl - IO-control function | ||
2900 | * | ||
2901 | * Description: | ||
2902 | * This function is called if an ioctl is issued on the device. | ||
2903 | * There are three subfunction for reading, writing and test-writing | ||
2904 | * the private MIB data structure (useful for SysKonnect-internal tools). | ||
2905 | * | ||
2906 | * Returns: | ||
2907 | * 0, if everything is ok | ||
2908 | * !=0, on error | ||
2909 | */ | ||
2910 | static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd) | ||
2911 | { | ||
2912 | DEV_NET *pNet; | ||
2913 | SK_AC *pAC; | ||
2914 | void *pMemBuf; | ||
2915 | struct pci_dev *pdev = NULL; | ||
2916 | SK_GE_IOCTL Ioctl; | ||
2917 | unsigned int Err = 0; | ||
2918 | int Size = 0; | ||
2919 | int Ret = 0; | ||
2920 | unsigned int Length = 0; | ||
2921 | int HeaderLength = sizeof(SK_U32) + sizeof(SK_U32); | ||
2922 | |||
2923 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, | ||
2924 | ("SkGeIoctl starts now...\n")); | ||
2925 | |||
2926 | pNet = netdev_priv(dev); | ||
2927 | pAC = pNet->pAC; | ||
2928 | |||
2929 | if (cmd == SIOCGMIIPHY || cmd == SIOCSMIIREG || cmd == SIOCGMIIREG) | ||
2930 | return SkGeMiiIoctl(dev, if_mii(rq), cmd); | ||
2931 | |||
2932 | if(copy_from_user(&Ioctl, rq->ifr_data, sizeof(SK_GE_IOCTL))) { | ||
2933 | return -EFAULT; | ||
2934 | } | ||
2935 | |||
2936 | switch(cmd) { | ||
2937 | case SK_IOCTL_SETMIB: | ||
2938 | case SK_IOCTL_PRESETMIB: | ||
2939 | if (!capable(CAP_NET_ADMIN)) return -EPERM; | ||
2940 | case SK_IOCTL_GETMIB: | ||
2941 | if(copy_from_user(&pAC->PnmiStruct, Ioctl.pData, | ||
2942 | Ioctl.Len<sizeof(pAC->PnmiStruct)? | ||
2943 | Ioctl.Len : sizeof(pAC->PnmiStruct))) { | ||
2944 | return -EFAULT; | ||
2945 | } | ||
2946 | Size = SkGeIocMib(pNet, Ioctl.Len, cmd); | ||
2947 | if(copy_to_user(Ioctl.pData, &pAC->PnmiStruct, | ||
2948 | Ioctl.Len<Size? Ioctl.Len : Size)) { | ||
2949 | return -EFAULT; | ||
2950 | } | ||
2951 | Ioctl.Len = Size; | ||
2952 | if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) { | ||
2953 | return -EFAULT; | ||
2954 | } | ||
2955 | break; | ||
2956 | case SK_IOCTL_GEN: | ||
2957 | if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) { | ||
2958 | Length = Ioctl.Len; | ||
2959 | } else { | ||
2960 | Length = sizeof(pAC->PnmiStruct) + HeaderLength; | ||
2961 | } | ||
2962 | if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) { | ||
2963 | return -ENOMEM; | ||
2964 | } | ||
2965 | if(copy_from_user(pMemBuf, Ioctl.pData, Length)) { | ||
2966 | Err = -EFAULT; | ||
2967 | goto fault_gen; | ||
2968 | } | ||
2969 | if ((Ret = SkPnmiGenIoctl(pAC, pAC->IoBase, pMemBuf, &Length, 0)) < 0) { | ||
2970 | Err = -EFAULT; | ||
2971 | goto fault_gen; | ||
2972 | } | ||
2973 | if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) { | ||
2974 | Err = -EFAULT; | ||
2975 | goto fault_gen; | ||
2976 | } | ||
2977 | Ioctl.Len = Length; | ||
2978 | if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) { | ||
2979 | Err = -EFAULT; | ||
2980 | goto fault_gen; | ||
2981 | } | ||
2982 | fault_gen: | ||
2983 | kfree(pMemBuf); /* cleanup everything */ | ||
2984 | break; | ||
2985 | #ifdef SK_DIAG_SUPPORT | ||
2986 | case SK_IOCTL_DIAG: | ||
2987 | if (!capable(CAP_NET_ADMIN)) return -EPERM; | ||
2988 | if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) { | ||
2989 | Length = Ioctl.Len; | ||
2990 | } else { | ||
2991 | Length = sizeof(pAC->PnmiStruct) + HeaderLength; | ||
2992 | } | ||
2993 | if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) { | ||
2994 | return -ENOMEM; | ||
2995 | } | ||
2996 | if(copy_from_user(pMemBuf, Ioctl.pData, Length)) { | ||
2997 | Err = -EFAULT; | ||
2998 | goto fault_diag; | ||
2999 | } | ||
3000 | pdev = pAC->PciDev; | ||
3001 | Length = 3 * sizeof(SK_U32); /* Error, Bus and Device */ | ||
3002 | /* | ||
3003 | ** While coding this new IOCTL interface, only a few lines of code | ||
3004 | ** are to to be added. Therefore no dedicated function has been | ||
3005 | ** added. If more functionality is added, a separate function | ||
3006 | ** should be used... | ||
3007 | */ | ||
3008 | * ((SK_U32 *)pMemBuf) = 0; | ||
3009 | * ((SK_U32 *)pMemBuf + 1) = pdev->bus->number; | ||
3010 | * ((SK_U32 *)pMemBuf + 2) = ParseDeviceNbrFromSlotName(pci_name(pdev)); | ||
3011 | if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) { | ||
3012 | Err = -EFAULT; | ||
3013 | goto fault_diag; | ||
3014 | } | ||
3015 | Ioctl.Len = Length; | ||
3016 | if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) { | ||
3017 | Err = -EFAULT; | ||
3018 | goto fault_diag; | ||
3019 | } | ||
3020 | fault_diag: | ||
3021 | kfree(pMemBuf); /* cleanup everything */ | ||
3022 | break; | ||
3023 | #endif | ||
3024 | default: | ||
3025 | Err = -EOPNOTSUPP; | ||
3026 | } | ||
3027 | |||
3028 | return(Err); | ||
3029 | |||
3030 | } /* SkGeIoctl */ | ||
3031 | |||
3032 | |||
3033 | /***************************************************************************** | ||
3034 | * | ||
3035 | * SkGeIocMib - handle a GetMib, SetMib- or PresetMib-ioctl message | ||
3036 | * | ||
3037 | * Description: | ||
3038 | * This function reads/writes the MIB data using PNMI (Private Network | ||
3039 | * Management Interface). | ||
3040 | * The destination for the data must be provided with the | ||
3041 | * ioctl call and is given to the driver in the form of | ||
3042 | * a user space address. | ||
3043 | * Copying from the user-provided data area into kernel messages | ||
3044 | * and back is done by copy_from_user and copy_to_user calls in | ||
3045 | * SkGeIoctl. | ||
3046 | * | ||
3047 | * Returns: | ||
3048 | * returned size from PNMI call | ||
3049 | */ | ||
3050 | static int SkGeIocMib( | ||
3051 | DEV_NET *pNet, /* pointer to the adapter context */ | ||
3052 | unsigned int Size, /* length of ioctl data */ | ||
3053 | int mode) /* flag for set/preset */ | ||
3054 | { | ||
3055 | unsigned long Flags; /* for spin lock */ | ||
3056 | SK_AC *pAC; | ||
3057 | |||
3058 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, | ||
3059 | ("SkGeIocMib starts now...\n")); | ||
3060 | pAC = pNet->pAC; | ||
3061 | /* access MIB */ | ||
3062 | spin_lock_irqsave(&pAC->SlowPathLock, Flags); | ||
3063 | switch(mode) { | ||
3064 | case SK_IOCTL_GETMIB: | ||
3065 | SkPnmiGetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size, | ||
3066 | pNet->NetNr); | ||
3067 | break; | ||
3068 | case SK_IOCTL_PRESETMIB: | ||
3069 | SkPnmiPreSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size, | ||
3070 | pNet->NetNr); | ||
3071 | break; | ||
3072 | case SK_IOCTL_SETMIB: | ||
3073 | SkPnmiSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size, | ||
3074 | pNet->NetNr); | ||
3075 | break; | ||
3076 | default: | ||
3077 | break; | ||
3078 | } | ||
3079 | spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); | ||
3080 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, | ||
3081 | ("MIB data access succeeded\n")); | ||
3082 | return (Size); | ||
3083 | } /* SkGeIocMib */ | ||
3084 | |||
3085 | |||
3086 | /***************************************************************************** | ||
3087 | * | ||
3088 | * GetConfiguration - read configuration information | ||
3089 | * | ||
3090 | * Description: | ||
3091 | * This function reads per-adapter configuration information from | ||
3092 | * the options provided on the command line. | ||
3093 | * | ||
3094 | * Returns: | ||
3095 | * none | ||
3096 | */ | ||
3097 | static void GetConfiguration( | ||
3098 | SK_AC *pAC) /* pointer to the adapter context structure */ | ||
3099 | { | ||
3100 | SK_I32 Port; /* preferred port */ | ||
3101 | SK_BOOL AutoSet; | ||
3102 | SK_BOOL DupSet; | ||
3103 | int LinkSpeed = SK_LSPEED_AUTO; /* Link speed */ | ||
3104 | int AutoNeg = 1; /* autoneg off (0) or on (1) */ | ||
3105 | int DuplexCap = 0; /* 0=both,1=full,2=half */ | ||
3106 | int FlowCtrl = SK_FLOW_MODE_SYM_OR_REM; /* FlowControl */ | ||
3107 | int MSMode = SK_MS_MODE_AUTO; /* master/slave mode */ | ||
3108 | |||
3109 | SK_BOOL IsConTypeDefined = SK_TRUE; | ||
3110 | SK_BOOL IsLinkSpeedDefined = SK_TRUE; | ||
3111 | SK_BOOL IsFlowCtrlDefined = SK_TRUE; | ||
3112 | SK_BOOL IsRoleDefined = SK_TRUE; | ||
3113 | SK_BOOL IsModeDefined = SK_TRUE; | ||
3114 | /* | ||
3115 | * The two parameters AutoNeg. and DuplexCap. map to one configuration | ||
3116 | * parameter. The mapping is described by this table: | ||
3117 | * DuplexCap -> | both | full | half | | ||
3118 | * AutoNeg | | | | | ||
3119 | * ----------------------------------------------------------------- | ||
3120 | * Off | illegal | Full | Half | | ||
3121 | * ----------------------------------------------------------------- | ||
3122 | * On | AutoBoth | AutoFull | AutoHalf | | ||
3123 | * ----------------------------------------------------------------- | ||
3124 | * Sense | AutoSense | AutoSense | AutoSense | | ||
3125 | */ | ||
3126 | int Capabilities[3][3] = | ||
3127 | { { -1, SK_LMODE_FULL , SK_LMODE_HALF }, | ||
3128 | {SK_LMODE_AUTOBOTH , SK_LMODE_AUTOFULL , SK_LMODE_AUTOHALF }, | ||
3129 | {SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE} }; | ||
3130 | |||
3131 | #define DC_BOTH 0 | ||
3132 | #define DC_FULL 1 | ||
3133 | #define DC_HALF 2 | ||
3134 | #define AN_OFF 0 | ||
3135 | #define AN_ON 1 | ||
3136 | #define AN_SENS 2 | ||
3137 | #define M_CurrPort pAC->GIni.GP[Port] | ||
3138 | |||
3139 | |||
3140 | /* | ||
3141 | ** Set the default values first for both ports! | ||
3142 | */ | ||
3143 | for (Port = 0; Port < SK_MAX_MACS; Port++) { | ||
3144 | M_CurrPort.PLinkModeConf = Capabilities[AN_ON][DC_BOTH]; | ||
3145 | M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM; | ||
3146 | M_CurrPort.PMSMode = SK_MS_MODE_AUTO; | ||
3147 | M_CurrPort.PLinkSpeed = SK_LSPEED_AUTO; | ||
3148 | } | ||
3149 | |||
3150 | /* | ||
3151 | ** Check merged parameter ConType. If it has not been used, | ||
3152 | ** verify any other parameter (e.g. AutoNeg) and use default values. | ||
3153 | ** | ||
3154 | ** Stating both ConType and other lowlevel link parameters is also | ||
3155 | ** possible. If this is the case, the passed ConType-parameter is | ||
3156 | ** overwritten by the lowlevel link parameter. | ||
3157 | ** | ||
3158 | ** The following settings are used for a merged ConType-parameter: | ||
3159 | ** | ||
3160 | ** ConType DupCap AutoNeg FlowCtrl Role Speed | ||
3161 | ** ------- ------ ------- -------- ---------- ----- | ||
3162 | ** Auto Both On SymOrRem Auto Auto | ||
3163 | ** 100FD Full Off None <ignored> 100 | ||
3164 | ** 100HD Half Off None <ignored> 100 | ||
3165 | ** 10FD Full Off None <ignored> 10 | ||
3166 | ** 10HD Half Off None <ignored> 10 | ||
3167 | ** | ||
3168 | ** This ConType parameter is used for all ports of the adapter! | ||
3169 | */ | ||
3170 | if ( (ConType != NULL) && | ||
3171 | (pAC->Index < SK_MAX_CARD_PARAM) && | ||
3172 | (ConType[pAC->Index] != NULL) ) { | ||
3173 | |||
3174 | /* Check chipset family */ | ||
3175 | if ((!pAC->ChipsetType) && | ||
3176 | (strcmp(ConType[pAC->Index],"Auto")!=0) && | ||
3177 | (strcmp(ConType[pAC->Index],"")!=0)) { | ||
3178 | /* Set the speed parameter back */ | ||
3179 | printk("sk98lin: Illegal value \"%s\" " | ||
3180 | "for ConType." | ||
3181 | " Using Auto.\n", | ||
3182 | ConType[pAC->Index]); | ||
3183 | |||
3184 | sprintf(ConType[pAC->Index], "Auto"); | ||
3185 | } | ||
3186 | |||
3187 | if (strcmp(ConType[pAC->Index],"")==0) { | ||
3188 | IsConTypeDefined = SK_FALSE; /* No ConType defined */ | ||
3189 | } else if (strcmp(ConType[pAC->Index],"Auto")==0) { | ||
3190 | for (Port = 0; Port < SK_MAX_MACS; Port++) { | ||
3191 | M_CurrPort.PLinkModeConf = Capabilities[AN_ON][DC_BOTH]; | ||
3192 | M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM; | ||
3193 | M_CurrPort.PMSMode = SK_MS_MODE_AUTO; | ||
3194 | M_CurrPort.PLinkSpeed = SK_LSPEED_AUTO; | ||
3195 | } | ||
3196 | } else if (strcmp(ConType[pAC->Index],"100FD")==0) { | ||
3197 | for (Port = 0; Port < SK_MAX_MACS; Port++) { | ||
3198 | M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL]; | ||
3199 | M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE; | ||
3200 | M_CurrPort.PMSMode = SK_MS_MODE_AUTO; | ||
3201 | M_CurrPort.PLinkSpeed = SK_LSPEED_100MBPS; | ||
3202 | } | ||
3203 | } else if (strcmp(ConType[pAC->Index],"100HD")==0) { | ||
3204 | for (Port = 0; Port < SK_MAX_MACS; Port++) { | ||
3205 | M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF]; | ||
3206 | M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE; | ||
3207 | M_CurrPort.PMSMode = SK_MS_MODE_AUTO; | ||
3208 | M_CurrPort.PLinkSpeed = SK_LSPEED_100MBPS; | ||
3209 | } | ||
3210 | } else if (strcmp(ConType[pAC->Index],"10FD")==0) { | ||
3211 | for (Port = 0; Port < SK_MAX_MACS; Port++) { | ||
3212 | M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL]; | ||
3213 | M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE; | ||
3214 | M_CurrPort.PMSMode = SK_MS_MODE_AUTO; | ||
3215 | M_CurrPort.PLinkSpeed = SK_LSPEED_10MBPS; | ||
3216 | } | ||
3217 | } else if (strcmp(ConType[pAC->Index],"10HD")==0) { | ||
3218 | for (Port = 0; Port < SK_MAX_MACS; Port++) { | ||
3219 | M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF]; | ||
3220 | M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE; | ||
3221 | M_CurrPort.PMSMode = SK_MS_MODE_AUTO; | ||
3222 | M_CurrPort.PLinkSpeed = SK_LSPEED_10MBPS; | ||
3223 | } | ||
3224 | } else { | ||
3225 | printk("sk98lin: Illegal value \"%s\" for ConType\n", | ||
3226 | ConType[pAC->Index]); | ||
3227 | IsConTypeDefined = SK_FALSE; /* Wrong ConType defined */ | ||
3228 | } | ||
3229 | } else { | ||
3230 | IsConTypeDefined = SK_FALSE; /* No ConType defined */ | ||
3231 | } | ||
3232 | |||
3233 | /* | ||
3234 | ** Parse any parameter settings for port A: | ||
3235 | ** a) any LinkSpeed stated? | ||
3236 | */ | ||
3237 | if (Speed_A != NULL && pAC->Index<SK_MAX_CARD_PARAM && | ||
3238 | Speed_A[pAC->Index] != NULL) { | ||
3239 | if (strcmp(Speed_A[pAC->Index],"")==0) { | ||
3240 | IsLinkSpeedDefined = SK_FALSE; | ||
3241 | } else if (strcmp(Speed_A[pAC->Index],"Auto")==0) { | ||
3242 | LinkSpeed = SK_LSPEED_AUTO; | ||
3243 | } else if (strcmp(Speed_A[pAC->Index],"10")==0) { | ||
3244 | LinkSpeed = SK_LSPEED_10MBPS; | ||
3245 | } else if (strcmp(Speed_A[pAC->Index],"100")==0) { | ||
3246 | LinkSpeed = SK_LSPEED_100MBPS; | ||
3247 | } else if (strcmp(Speed_A[pAC->Index],"1000")==0) { | ||
3248 | LinkSpeed = SK_LSPEED_1000MBPS; | ||
3249 | } else { | ||
3250 | printk("sk98lin: Illegal value \"%s\" for Speed_A\n", | ||
3251 | Speed_A[pAC->Index]); | ||
3252 | IsLinkSpeedDefined = SK_FALSE; | ||
3253 | } | ||
3254 | } else { | ||
3255 | IsLinkSpeedDefined = SK_FALSE; | ||
3256 | } | ||
3257 | |||
3258 | /* | ||
3259 | ** Check speed parameter: | ||
3260 | ** Only copper type adapter and GE V2 cards | ||
3261 | */ | ||
3262 | if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) && | ||
3263 | ((LinkSpeed != SK_LSPEED_AUTO) && | ||
3264 | (LinkSpeed != SK_LSPEED_1000MBPS))) { | ||
3265 | printk("sk98lin: Illegal value for Speed_A. " | ||
3266 | "Not a copper card or GE V2 card\n Using " | ||
3267 | "speed 1000\n"); | ||
3268 | LinkSpeed = SK_LSPEED_1000MBPS; | ||
3269 | } | ||
3270 | |||
3271 | /* | ||
3272 | ** Decide whether to set new config value if somethig valid has | ||
3273 | ** been received. | ||
3274 | */ | ||
3275 | if (IsLinkSpeedDefined) { | ||
3276 | pAC->GIni.GP[0].PLinkSpeed = LinkSpeed; | ||
3277 | } | ||
3278 | |||
3279 | /* | ||
3280 | ** b) Any Autonegotiation and DuplexCapabilities set? | ||
3281 | ** Please note that both belong together... | ||
3282 | */ | ||
3283 | AutoNeg = AN_ON; /* tschilling: Default: Autonegotiation on! */ | ||
3284 | AutoSet = SK_FALSE; | ||
3285 | if (AutoNeg_A != NULL && pAC->Index<SK_MAX_CARD_PARAM && | ||
3286 | AutoNeg_A[pAC->Index] != NULL) { | ||
3287 | AutoSet = SK_TRUE; | ||
3288 | if (strcmp(AutoNeg_A[pAC->Index],"")==0) { | ||
3289 | AutoSet = SK_FALSE; | ||
3290 | } else if (strcmp(AutoNeg_A[pAC->Index],"On")==0) { | ||
3291 | AutoNeg = AN_ON; | ||
3292 | } else if (strcmp(AutoNeg_A[pAC->Index],"Off")==0) { | ||
3293 | AutoNeg = AN_OFF; | ||
3294 | } else if (strcmp(AutoNeg_A[pAC->Index],"Sense")==0) { | ||
3295 | AutoNeg = AN_SENS; | ||
3296 | } else { | ||
3297 | printk("sk98lin: Illegal value \"%s\" for AutoNeg_A\n", | ||
3298 | AutoNeg_A[pAC->Index]); | ||
3299 | } | ||
3300 | } | ||
3301 | |||
3302 | DuplexCap = DC_BOTH; | ||
3303 | DupSet = SK_FALSE; | ||
3304 | if (DupCap_A != NULL && pAC->Index<SK_MAX_CARD_PARAM && | ||
3305 | DupCap_A[pAC->Index] != NULL) { | ||
3306 | DupSet = SK_TRUE; | ||
3307 | if (strcmp(DupCap_A[pAC->Index],"")==0) { | ||
3308 | DupSet = SK_FALSE; | ||
3309 | } else if (strcmp(DupCap_A[pAC->Index],"Both")==0) { | ||
3310 | DuplexCap = DC_BOTH; | ||
3311 | } else if (strcmp(DupCap_A[pAC->Index],"Full")==0) { | ||
3312 | DuplexCap = DC_FULL; | ||
3313 | } else if (strcmp(DupCap_A[pAC->Index],"Half")==0) { | ||
3314 | DuplexCap = DC_HALF; | ||
3315 | } else { | ||
3316 | printk("sk98lin: Illegal value \"%s\" for DupCap_A\n", | ||
3317 | DupCap_A[pAC->Index]); | ||
3318 | } | ||
3319 | } | ||
3320 | |||
3321 | /* | ||
3322 | ** Check for illegal combinations | ||
3323 | */ | ||
3324 | if ((LinkSpeed == SK_LSPEED_1000MBPS) && | ||
3325 | ((DuplexCap == SK_LMODE_STAT_AUTOHALF) || | ||
3326 | (DuplexCap == SK_LMODE_STAT_HALF)) && | ||
3327 | (pAC->ChipsetType)) { | ||
3328 | printk("sk98lin: Half Duplex not possible with Gigabit speed!\n" | ||
3329 | " Using Full Duplex.\n"); | ||
3330 | DuplexCap = DC_FULL; | ||
3331 | } | ||
3332 | |||
3333 | if ( AutoSet && AutoNeg==AN_SENS && DupSet) { | ||
3334 | printk("sk98lin, Port A: DuplexCapabilities" | ||
3335 | " ignored using Sense mode\n"); | ||
3336 | } | ||
3337 | |||
3338 | if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){ | ||
3339 | printk("sk98lin: Port A: Illegal combination" | ||
3340 | " of values AutoNeg. and DuplexCap.\n Using " | ||
3341 | "Full Duplex\n"); | ||
3342 | DuplexCap = DC_FULL; | ||
3343 | } | ||
3344 | |||
3345 | if (AutoSet && AutoNeg==AN_OFF && !DupSet) { | ||
3346 | DuplexCap = DC_FULL; | ||
3347 | } | ||
3348 | |||
3349 | if (!AutoSet && DupSet) { | ||
3350 | printk("sk98lin: Port A: Duplex setting not" | ||
3351 | " possible in\n default AutoNegotiation mode" | ||
3352 | " (Sense).\n Using AutoNegotiation On\n"); | ||
3353 | AutoNeg = AN_ON; | ||
3354 | } | ||
3355 | |||
3356 | /* | ||
3357 | ** set the desired mode | ||
3358 | */ | ||
3359 | if (AutoSet || DupSet) { | ||
3360 | pAC->GIni.GP[0].PLinkModeConf = Capabilities[AutoNeg][DuplexCap]; | ||
3361 | } | ||
3362 | |||
3363 | /* | ||
3364 | ** c) Any Flowcontrol-parameter set? | ||
3365 | */ | ||
3366 | if (FlowCtrl_A != NULL && pAC->Index<SK_MAX_CARD_PARAM && | ||
3367 | FlowCtrl_A[pAC->Index] != NULL) { | ||
3368 | if (strcmp(FlowCtrl_A[pAC->Index],"") == 0) { | ||
3369 | IsFlowCtrlDefined = SK_FALSE; | ||
3370 | } else if (strcmp(FlowCtrl_A[pAC->Index],"SymOrRem") == 0) { | ||
3371 | FlowCtrl = SK_FLOW_MODE_SYM_OR_REM; | ||
3372 | } else if (strcmp(FlowCtrl_A[pAC->Index],"Sym")==0) { | ||
3373 | FlowCtrl = SK_FLOW_MODE_SYMMETRIC; | ||
3374 | } else if (strcmp(FlowCtrl_A[pAC->Index],"LocSend")==0) { | ||
3375 | FlowCtrl = SK_FLOW_MODE_LOC_SEND; | ||
3376 | } else if (strcmp(FlowCtrl_A[pAC->Index],"None")==0) { | ||
3377 | FlowCtrl = SK_FLOW_MODE_NONE; | ||
3378 | } else { | ||
3379 | printk("sk98lin: Illegal value \"%s\" for FlowCtrl_A\n", | ||
3380 | FlowCtrl_A[pAC->Index]); | ||
3381 | IsFlowCtrlDefined = SK_FALSE; | ||
3382 | } | ||
3383 | } else { | ||
3384 | IsFlowCtrlDefined = SK_FALSE; | ||
3385 | } | ||
3386 | |||
3387 | if (IsFlowCtrlDefined) { | ||
3388 | if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) { | ||
3389 | printk("sk98lin: Port A: FlowControl" | ||
3390 | " impossible without AutoNegotiation," | ||
3391 | " disabled\n"); | ||
3392 | FlowCtrl = SK_FLOW_MODE_NONE; | ||
3393 | } | ||
3394 | pAC->GIni.GP[0].PFlowCtrlMode = FlowCtrl; | ||
3395 | } | ||
3396 | |||
3397 | /* | ||
3398 | ** d) What is with the RoleParameter? | ||
3399 | */ | ||
3400 | if (Role_A != NULL && pAC->Index<SK_MAX_CARD_PARAM && | ||
3401 | Role_A[pAC->Index] != NULL) { | ||
3402 | if (strcmp(Role_A[pAC->Index],"")==0) { | ||
3403 | IsRoleDefined = SK_FALSE; | ||
3404 | } else if (strcmp(Role_A[pAC->Index],"Auto")==0) { | ||
3405 | MSMode = SK_MS_MODE_AUTO; | ||
3406 | } else if (strcmp(Role_A[pAC->Index],"Master")==0) { | ||
3407 | MSMode = SK_MS_MODE_MASTER; | ||
3408 | } else if (strcmp(Role_A[pAC->Index],"Slave")==0) { | ||
3409 | MSMode = SK_MS_MODE_SLAVE; | ||
3410 | } else { | ||
3411 | printk("sk98lin: Illegal value \"%s\" for Role_A\n", | ||
3412 | Role_A[pAC->Index]); | ||
3413 | IsRoleDefined = SK_FALSE; | ||
3414 | } | ||
3415 | } else { | ||
3416 | IsRoleDefined = SK_FALSE; | ||
3417 | } | ||
3418 | |||
3419 | if (IsRoleDefined == SK_TRUE) { | ||
3420 | pAC->GIni.GP[0].PMSMode = MSMode; | ||
3421 | } | ||
3422 | |||
3423 | |||
3424 | |||
3425 | /* | ||
3426 | ** Parse any parameter settings for port B: | ||
3427 | ** a) any LinkSpeed stated? | ||
3428 | */ | ||
3429 | IsConTypeDefined = SK_TRUE; | ||
3430 | IsLinkSpeedDefined = SK_TRUE; | ||
3431 | IsFlowCtrlDefined = SK_TRUE; | ||
3432 | IsModeDefined = SK_TRUE; | ||
3433 | |||
3434 | if (Speed_B != NULL && pAC->Index<SK_MAX_CARD_PARAM && | ||
3435 | Speed_B[pAC->Index] != NULL) { | ||
3436 | if (strcmp(Speed_B[pAC->Index],"")==0) { | ||
3437 | IsLinkSpeedDefined = SK_FALSE; | ||
3438 | } else if (strcmp(Speed_B[pAC->Index],"Auto")==0) { | ||
3439 | LinkSpeed = SK_LSPEED_AUTO; | ||
3440 | } else if (strcmp(Speed_B[pAC->Index],"10")==0) { | ||
3441 | LinkSpeed = SK_LSPEED_10MBPS; | ||
3442 | } else if (strcmp(Speed_B[pAC->Index],"100")==0) { | ||
3443 | LinkSpeed = SK_LSPEED_100MBPS; | ||
3444 | } else if (strcmp(Speed_B[pAC->Index],"1000")==0) { | ||
3445 | LinkSpeed = SK_LSPEED_1000MBPS; | ||
3446 | } else { | ||
3447 | printk("sk98lin: Illegal value \"%s\" for Speed_B\n", | ||
3448 | Speed_B[pAC->Index]); | ||
3449 | IsLinkSpeedDefined = SK_FALSE; | ||
3450 | } | ||
3451 | } else { | ||
3452 | IsLinkSpeedDefined = SK_FALSE; | ||
3453 | } | ||
3454 | |||
3455 | /* | ||
3456 | ** Check speed parameter: | ||
3457 | ** Only copper type adapter and GE V2 cards | ||
3458 | */ | ||
3459 | if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) && | ||
3460 | ((LinkSpeed != SK_LSPEED_AUTO) && | ||
3461 | (LinkSpeed != SK_LSPEED_1000MBPS))) { | ||
3462 | printk("sk98lin: Illegal value for Speed_B. " | ||
3463 | "Not a copper card or GE V2 card\n Using " | ||
3464 | "speed 1000\n"); | ||
3465 | LinkSpeed = SK_LSPEED_1000MBPS; | ||
3466 | } | ||
3467 | |||
3468 | /* | ||
3469 | ** Decide whether to set new config value if somethig valid has | ||
3470 | ** been received. | ||
3471 | */ | ||
3472 | if (IsLinkSpeedDefined) { | ||
3473 | pAC->GIni.GP[1].PLinkSpeed = LinkSpeed; | ||
3474 | } | ||
3475 | |||
3476 | /* | ||
3477 | ** b) Any Autonegotiation and DuplexCapabilities set? | ||
3478 | ** Please note that both belong together... | ||
3479 | */ | ||
3480 | AutoNeg = AN_SENS; /* default: do auto Sense */ | ||
3481 | AutoSet = SK_FALSE; | ||
3482 | if (AutoNeg_B != NULL && pAC->Index<SK_MAX_CARD_PARAM && | ||
3483 | AutoNeg_B[pAC->Index] != NULL) { | ||
3484 | AutoSet = SK_TRUE; | ||
3485 | if (strcmp(AutoNeg_B[pAC->Index],"")==0) { | ||
3486 | AutoSet = SK_FALSE; | ||
3487 | } else if (strcmp(AutoNeg_B[pAC->Index],"On")==0) { | ||
3488 | AutoNeg = AN_ON; | ||
3489 | } else if (strcmp(AutoNeg_B[pAC->Index],"Off")==0) { | ||
3490 | AutoNeg = AN_OFF; | ||
3491 | } else if (strcmp(AutoNeg_B[pAC->Index],"Sense")==0) { | ||
3492 | AutoNeg = AN_SENS; | ||
3493 | } else { | ||
3494 | printk("sk98lin: Illegal value \"%s\" for AutoNeg_B\n", | ||
3495 | AutoNeg_B[pAC->Index]); | ||
3496 | } | ||
3497 | } | ||
3498 | |||
3499 | DuplexCap = DC_BOTH; | ||
3500 | DupSet = SK_FALSE; | ||
3501 | if (DupCap_B != NULL && pAC->Index<SK_MAX_CARD_PARAM && | ||
3502 | DupCap_B[pAC->Index] != NULL) { | ||
3503 | DupSet = SK_TRUE; | ||
3504 | if (strcmp(DupCap_B[pAC->Index],"")==0) { | ||
3505 | DupSet = SK_FALSE; | ||
3506 | } else if (strcmp(DupCap_B[pAC->Index],"Both")==0) { | ||
3507 | DuplexCap = DC_BOTH; | ||
3508 | } else if (strcmp(DupCap_B[pAC->Index],"Full")==0) { | ||
3509 | DuplexCap = DC_FULL; | ||
3510 | } else if (strcmp(DupCap_B[pAC->Index],"Half")==0) { | ||
3511 | DuplexCap = DC_HALF; | ||
3512 | } else { | ||
3513 | printk("sk98lin: Illegal value \"%s\" for DupCap_B\n", | ||
3514 | DupCap_B[pAC->Index]); | ||
3515 | } | ||
3516 | } | ||
3517 | |||
3518 | |||
3519 | /* | ||
3520 | ** Check for illegal combinations | ||
3521 | */ | ||
3522 | if ((LinkSpeed == SK_LSPEED_1000MBPS) && | ||
3523 | ((DuplexCap == SK_LMODE_STAT_AUTOHALF) || | ||
3524 | (DuplexCap == SK_LMODE_STAT_HALF)) && | ||
3525 | (pAC->ChipsetType)) { | ||
3526 | printk("sk98lin: Half Duplex not possible with Gigabit speed!\n" | ||
3527 | " Using Full Duplex.\n"); | ||
3528 | DuplexCap = DC_FULL; | ||
3529 | } | ||
3530 | |||
3531 | if (AutoSet && AutoNeg==AN_SENS && DupSet) { | ||
3532 | printk("sk98lin, Port B: DuplexCapabilities" | ||
3533 | " ignored using Sense mode\n"); | ||
3534 | } | ||
3535 | |||
3536 | if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){ | ||
3537 | printk("sk98lin: Port B: Illegal combination" | ||
3538 | " of values AutoNeg. and DuplexCap.\n Using " | ||
3539 | "Full Duplex\n"); | ||
3540 | DuplexCap = DC_FULL; | ||
3541 | } | ||
3542 | |||
3543 | if (AutoSet && AutoNeg==AN_OFF && !DupSet) { | ||
3544 | DuplexCap = DC_FULL; | ||
3545 | } | ||
3546 | |||
3547 | if (!AutoSet && DupSet) { | ||
3548 | printk("sk98lin: Port B: Duplex setting not" | ||
3549 | " possible in\n default AutoNegotiation mode" | ||
3550 | " (Sense).\n Using AutoNegotiation On\n"); | ||
3551 | AutoNeg = AN_ON; | ||
3552 | } | ||
3553 | |||
3554 | /* | ||
3555 | ** set the desired mode | ||
3556 | */ | ||
3557 | if (AutoSet || DupSet) { | ||
3558 | pAC->GIni.GP[1].PLinkModeConf = Capabilities[AutoNeg][DuplexCap]; | ||
3559 | } | ||
3560 | |||
3561 | /* | ||
3562 | ** c) Any FlowCtrl parameter set? | ||
3563 | */ | ||
3564 | if (FlowCtrl_B != NULL && pAC->Index<SK_MAX_CARD_PARAM && | ||
3565 | FlowCtrl_B[pAC->Index] != NULL) { | ||
3566 | if (strcmp(FlowCtrl_B[pAC->Index],"") == 0) { | ||
3567 | IsFlowCtrlDefined = SK_FALSE; | ||
3568 | } else if (strcmp(FlowCtrl_B[pAC->Index],"SymOrRem") == 0) { | ||
3569 | FlowCtrl = SK_FLOW_MODE_SYM_OR_REM; | ||
3570 | } else if (strcmp(FlowCtrl_B[pAC->Index],"Sym")==0) { | ||
3571 | FlowCtrl = SK_FLOW_MODE_SYMMETRIC; | ||
3572 | } else if (strcmp(FlowCtrl_B[pAC->Index],"LocSend")==0) { | ||
3573 | FlowCtrl = SK_FLOW_MODE_LOC_SEND; | ||
3574 | } else if (strcmp(FlowCtrl_B[pAC->Index],"None")==0) { | ||
3575 | FlowCtrl = SK_FLOW_MODE_NONE; | ||
3576 | } else { | ||
3577 | printk("sk98lin: Illegal value \"%s\" for FlowCtrl_B\n", | ||
3578 | FlowCtrl_B[pAC->Index]); | ||
3579 | IsFlowCtrlDefined = SK_FALSE; | ||
3580 | } | ||
3581 | } else { | ||
3582 | IsFlowCtrlDefined = SK_FALSE; | ||
3583 | } | ||
3584 | |||
3585 | if (IsFlowCtrlDefined) { | ||
3586 | if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) { | ||
3587 | printk("sk98lin: Port B: FlowControl" | ||
3588 | " impossible without AutoNegotiation," | ||
3589 | " disabled\n"); | ||
3590 | FlowCtrl = SK_FLOW_MODE_NONE; | ||
3591 | } | ||
3592 | pAC->GIni.GP[1].PFlowCtrlMode = FlowCtrl; | ||
3593 | } | ||
3594 | |||
3595 | /* | ||
3596 | ** d) What is the RoleParameter? | ||
3597 | */ | ||
3598 | if (Role_B != NULL && pAC->Index<SK_MAX_CARD_PARAM && | ||
3599 | Role_B[pAC->Index] != NULL) { | ||
3600 | if (strcmp(Role_B[pAC->Index],"")==0) { | ||
3601 | IsRoleDefined = SK_FALSE; | ||
3602 | } else if (strcmp(Role_B[pAC->Index],"Auto")==0) { | ||
3603 | MSMode = SK_MS_MODE_AUTO; | ||
3604 | } else if (strcmp(Role_B[pAC->Index],"Master")==0) { | ||
3605 | MSMode = SK_MS_MODE_MASTER; | ||
3606 | } else if (strcmp(Role_B[pAC->Index],"Slave")==0) { | ||
3607 | MSMode = SK_MS_MODE_SLAVE; | ||
3608 | } else { | ||
3609 | printk("sk98lin: Illegal value \"%s\" for Role_B\n", | ||
3610 | Role_B[pAC->Index]); | ||
3611 | IsRoleDefined = SK_FALSE; | ||
3612 | } | ||
3613 | } else { | ||
3614 | IsRoleDefined = SK_FALSE; | ||
3615 | } | ||
3616 | |||
3617 | if (IsRoleDefined) { | ||
3618 | pAC->GIni.GP[1].PMSMode = MSMode; | ||
3619 | } | ||
3620 | |||
3621 | /* | ||
3622 | ** Evaluate settings for both ports | ||
3623 | */ | ||
3624 | pAC->ActivePort = 0; | ||
3625 | if (PrefPort != NULL && pAC->Index<SK_MAX_CARD_PARAM && | ||
3626 | PrefPort[pAC->Index] != NULL) { | ||
3627 | if (strcmp(PrefPort[pAC->Index],"") == 0) { /* Auto */ | ||
3628 | pAC->ActivePort = 0; | ||
3629 | pAC->Rlmt.Net[0].Preference = -1; /* auto */ | ||
3630 | pAC->Rlmt.Net[0].PrefPort = 0; | ||
3631 | } else if (strcmp(PrefPort[pAC->Index],"A") == 0) { | ||
3632 | /* | ||
3633 | ** do not set ActivePort here, thus a port | ||
3634 | ** switch is issued after net up. | ||
3635 | */ | ||
3636 | Port = 0; | ||
3637 | pAC->Rlmt.Net[0].Preference = Port; | ||
3638 | pAC->Rlmt.Net[0].PrefPort = Port; | ||
3639 | } else if (strcmp(PrefPort[pAC->Index],"B") == 0) { | ||
3640 | /* | ||
3641 | ** do not set ActivePort here, thus a port | ||
3642 | ** switch is issued after net up. | ||
3643 | */ | ||
3644 | if (pAC->GIni.GIMacsFound == 1) { | ||
3645 | printk("sk98lin: Illegal value \"B\" for PrefPort.\n" | ||
3646 | " Port B not available on single port adapters.\n"); | ||
3647 | |||
3648 | pAC->ActivePort = 0; | ||
3649 | pAC->Rlmt.Net[0].Preference = -1; /* auto */ | ||
3650 | pAC->Rlmt.Net[0].PrefPort = 0; | ||
3651 | } else { | ||
3652 | Port = 1; | ||
3653 | pAC->Rlmt.Net[0].Preference = Port; | ||
3654 | pAC->Rlmt.Net[0].PrefPort = Port; | ||
3655 | } | ||
3656 | } else { | ||
3657 | printk("sk98lin: Illegal value \"%s\" for PrefPort\n", | ||
3658 | PrefPort[pAC->Index]); | ||
3659 | } | ||
3660 | } | ||
3661 | |||
3662 | pAC->RlmtNets = 1; | ||
3663 | |||
3664 | if (RlmtMode != NULL && pAC->Index<SK_MAX_CARD_PARAM && | ||
3665 | RlmtMode[pAC->Index] != NULL) { | ||
3666 | if (strcmp(RlmtMode[pAC->Index], "") == 0) { | ||
3667 | pAC->RlmtMode = 0; | ||
3668 | } else if (strcmp(RlmtMode[pAC->Index], "CheckLinkState") == 0) { | ||
3669 | pAC->RlmtMode = SK_RLMT_CHECK_LINK; | ||
3670 | } else if (strcmp(RlmtMode[pAC->Index], "CheckLocalPort") == 0) { | ||
3671 | pAC->RlmtMode = SK_RLMT_CHECK_LINK | | ||
3672 | SK_RLMT_CHECK_LOC_LINK; | ||
3673 | } else if (strcmp(RlmtMode[pAC->Index], "CheckSeg") == 0) { | ||
3674 | pAC->RlmtMode = SK_RLMT_CHECK_LINK | | ||
3675 | SK_RLMT_CHECK_LOC_LINK | | ||
3676 | SK_RLMT_CHECK_SEG; | ||
3677 | } else if ((strcmp(RlmtMode[pAC->Index], "DualNet") == 0) && | ||
3678 | (pAC->GIni.GIMacsFound == 2)) { | ||
3679 | pAC->RlmtMode = SK_RLMT_CHECK_LINK; | ||
3680 | pAC->RlmtNets = 2; | ||
3681 | } else { | ||
3682 | printk("sk98lin: Illegal value \"%s\" for" | ||
3683 | " RlmtMode, using default\n", | ||
3684 | RlmtMode[pAC->Index]); | ||
3685 | pAC->RlmtMode = 0; | ||
3686 | } | ||
3687 | } else { | ||
3688 | pAC->RlmtMode = 0; | ||
3689 | } | ||
3690 | |||
3691 | /* | ||
3692 | ** Check the interrupt moderation parameters | ||
3693 | */ | ||
3694 | if (Moderation[pAC->Index] != NULL) { | ||
3695 | if (strcmp(Moderation[pAC->Index], "") == 0) { | ||
3696 | pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; | ||
3697 | } else if (strcmp(Moderation[pAC->Index], "Static") == 0) { | ||
3698 | pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_STATIC; | ||
3699 | } else if (strcmp(Moderation[pAC->Index], "Dynamic") == 0) { | ||
3700 | pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_DYNAMIC; | ||
3701 | } else if (strcmp(Moderation[pAC->Index], "None") == 0) { | ||
3702 | pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; | ||
3703 | } else { | ||
3704 | printk("sk98lin: Illegal value \"%s\" for Moderation.\n" | ||
3705 | " Disable interrupt moderation.\n", | ||
3706 | Moderation[pAC->Index]); | ||
3707 | pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; | ||
3708 | } | ||
3709 | } else { | ||
3710 | pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; | ||
3711 | } | ||
3712 | |||
3713 | if (Stats[pAC->Index] != NULL) { | ||
3714 | if (strcmp(Stats[pAC->Index], "Yes") == 0) { | ||
3715 | pAC->DynIrqModInfo.DisplayStats = SK_TRUE; | ||
3716 | } else { | ||
3717 | pAC->DynIrqModInfo.DisplayStats = SK_FALSE; | ||
3718 | } | ||
3719 | } else { | ||
3720 | pAC->DynIrqModInfo.DisplayStats = SK_FALSE; | ||
3721 | } | ||
3722 | |||
3723 | if (ModerationMask[pAC->Index] != NULL) { | ||
3724 | if (strcmp(ModerationMask[pAC->Index], "Rx") == 0) { | ||
3725 | pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY; | ||
3726 | } else if (strcmp(ModerationMask[pAC->Index], "Tx") == 0) { | ||
3727 | pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_ONLY; | ||
3728 | } else if (strcmp(ModerationMask[pAC->Index], "Sp") == 0) { | ||
3729 | pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_ONLY; | ||
3730 | } else if (strcmp(ModerationMask[pAC->Index], "RxSp") == 0) { | ||
3731 | pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX; | ||
3732 | } else if (strcmp(ModerationMask[pAC->Index], "SpRx") == 0) { | ||
3733 | pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX; | ||
3734 | } else if (strcmp(ModerationMask[pAC->Index], "RxTx") == 0) { | ||
3735 | pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX; | ||
3736 | } else if (strcmp(ModerationMask[pAC->Index], "TxRx") == 0) { | ||
3737 | pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX; | ||
3738 | } else if (strcmp(ModerationMask[pAC->Index], "TxSp") == 0) { | ||
3739 | pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX; | ||
3740 | } else if (strcmp(ModerationMask[pAC->Index], "SpTx") == 0) { | ||
3741 | pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX; | ||
3742 | } else if (strcmp(ModerationMask[pAC->Index], "RxTxSp") == 0) { | ||
3743 | pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; | ||
3744 | } else if (strcmp(ModerationMask[pAC->Index], "RxSpTx") == 0) { | ||
3745 | pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; | ||
3746 | } else if (strcmp(ModerationMask[pAC->Index], "TxRxSp") == 0) { | ||
3747 | pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; | ||
3748 | } else if (strcmp(ModerationMask[pAC->Index], "TxSpRx") == 0) { | ||
3749 | pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; | ||
3750 | } else if (strcmp(ModerationMask[pAC->Index], "SpTxRx") == 0) { | ||
3751 | pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; | ||
3752 | } else if (strcmp(ModerationMask[pAC->Index], "SpRxTx") == 0) { | ||
3753 | pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; | ||
3754 | } else { /* some rubbish */ | ||
3755 | pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY; | ||
3756 | } | ||
3757 | } else { /* operator has stated nothing */ | ||
3758 | pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX; | ||
3759 | } | ||
3760 | |||
3761 | if (AutoSizing[pAC->Index] != NULL) { | ||
3762 | if (strcmp(AutoSizing[pAC->Index], "On") == 0) { | ||
3763 | pAC->DynIrqModInfo.AutoSizing = SK_FALSE; | ||
3764 | } else { | ||
3765 | pAC->DynIrqModInfo.AutoSizing = SK_FALSE; | ||
3766 | } | ||
3767 | } else { /* operator has stated nothing */ | ||
3768 | pAC->DynIrqModInfo.AutoSizing = SK_FALSE; | ||
3769 | } | ||
3770 | |||
3771 | if (IntsPerSec[pAC->Index] != 0) { | ||
3772 | if ((IntsPerSec[pAC->Index]< C_INT_MOD_IPS_LOWER_RANGE) || | ||
3773 | (IntsPerSec[pAC->Index] > C_INT_MOD_IPS_UPPER_RANGE)) { | ||
3774 | printk("sk98lin: Illegal value \"%d\" for IntsPerSec. (Range: %d - %d)\n" | ||
3775 | " Using default value of %i.\n", | ||
3776 | IntsPerSec[pAC->Index], | ||
3777 | C_INT_MOD_IPS_LOWER_RANGE, | ||
3778 | C_INT_MOD_IPS_UPPER_RANGE, | ||
3779 | C_INTS_PER_SEC_DEFAULT); | ||
3780 | pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT; | ||
3781 | } else { | ||
3782 | pAC->DynIrqModInfo.MaxModIntsPerSec = IntsPerSec[pAC->Index]; | ||
3783 | } | ||
3784 | } else { | ||
3785 | pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT; | ||
3786 | } | ||
3787 | |||
3788 | /* | ||
3789 | ** Evaluate upper and lower moderation threshold | ||
3790 | */ | ||
3791 | pAC->DynIrqModInfo.MaxModIntsPerSecUpperLimit = | ||
3792 | pAC->DynIrqModInfo.MaxModIntsPerSec + | ||
3793 | (pAC->DynIrqModInfo.MaxModIntsPerSec / 2); | ||
3794 | |||
3795 | pAC->DynIrqModInfo.MaxModIntsPerSecLowerLimit = | ||
3796 | pAC->DynIrqModInfo.MaxModIntsPerSec - | ||
3797 | (pAC->DynIrqModInfo.MaxModIntsPerSec / 2); | ||
3798 | |||
3799 | pAC->DynIrqModInfo.PrevTimeVal = jiffies; /* initial value */ | ||
3800 | |||
3801 | |||
3802 | } /* GetConfiguration */ | ||
3803 | |||
3804 | |||
3805 | /***************************************************************************** | ||
3806 | * | ||
3807 | * ProductStr - return a adapter identification string from vpd | ||
3808 | * | ||
3809 | * Description: | ||
3810 | * This function reads the product name string from the vpd area | ||
3811 | * and puts it the field pAC->DeviceString. | ||
3812 | * | ||
3813 | * Returns: N/A | ||
3814 | */ | ||
3815 | static inline int ProductStr( | ||
3816 | SK_AC *pAC, /* pointer to adapter context */ | ||
3817 | char *DeviceStr, /* result string */ | ||
3818 | int StrLen /* length of the string */ | ||
3819 | ) | ||
3820 | { | ||
3821 | char Keyword[] = VPD_NAME; /* vpd productname identifier */ | ||
3822 | int ReturnCode; /* return code from vpd_read */ | ||
3823 | unsigned long Flags; | ||
3824 | |||
3825 | spin_lock_irqsave(&pAC->SlowPathLock, Flags); | ||
3826 | ReturnCode = VpdRead(pAC, pAC->IoBase, Keyword, DeviceStr, &StrLen); | ||
3827 | spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); | ||
3828 | |||
3829 | return ReturnCode; | ||
3830 | } /* ProductStr */ | ||
3831 | |||
3832 | /***************************************************************************** | ||
3833 | * | ||
3834 | * StartDrvCleanupTimer - Start timer to check for descriptors which | ||
3835 | * might be placed in descriptor ring, but | ||
3836 | * havent been handled up to now | ||
3837 | * | ||
3838 | * Description: | ||
3839 | * This function requests a HW-timer fo the Yukon card. The actions to | ||
3840 | * perform when this timer expires, are located in the SkDrvEvent(). | ||
3841 | * | ||
3842 | * Returns: N/A | ||
3843 | */ | ||
3844 | static void | ||
3845 | StartDrvCleanupTimer(SK_AC *pAC) { | ||
3846 | SK_EVPARA EventParam; /* Event struct for timer event */ | ||
3847 | |||
3848 | SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam)); | ||
3849 | EventParam.Para32[0] = SK_DRV_RX_CLEANUP_TIMER; | ||
3850 | SkTimerStart(pAC, pAC->IoBase, &pAC->DrvCleanupTimer, | ||
3851 | SK_DRV_RX_CLEANUP_TIMER_LENGTH, | ||
3852 | SKGE_DRV, SK_DRV_TIMER, EventParam); | ||
3853 | } | ||
3854 | |||
3855 | /***************************************************************************** | ||
3856 | * | ||
3857 | * StopDrvCleanupTimer - Stop timer to check for descriptors | ||
3858 | * | ||
3859 | * Description: | ||
3860 | * This function requests a HW-timer fo the Yukon card. The actions to | ||
3861 | * perform when this timer expires, are located in the SkDrvEvent(). | ||
3862 | * | ||
3863 | * Returns: N/A | ||
3864 | */ | ||
3865 | static void | ||
3866 | StopDrvCleanupTimer(SK_AC *pAC) { | ||
3867 | SkTimerStop(pAC, pAC->IoBase, &pAC->DrvCleanupTimer); | ||
3868 | SK_MEMSET((char *) &pAC->DrvCleanupTimer, 0, sizeof(SK_TIMER)); | ||
3869 | } | ||
3870 | |||
3871 | /****************************************************************************/ | ||
3872 | /* functions for common modules *********************************************/ | ||
3873 | /****************************************************************************/ | ||
3874 | |||
3875 | |||
3876 | /***************************************************************************** | ||
3877 | * | ||
3878 | * SkDrvAllocRlmtMbuf - allocate an RLMT mbuf | ||
3879 | * | ||
3880 | * Description: | ||
3881 | * This routine returns an RLMT mbuf or NULL. The RLMT Mbuf structure | ||
3882 | * is embedded into a socket buff data area. | ||
3883 | * | ||
3884 | * Context: | ||
3885 | * runtime | ||
3886 | * | ||
3887 | * Returns: | ||
3888 | * NULL or pointer to Mbuf. | ||
3889 | */ | ||
3890 | SK_MBUF *SkDrvAllocRlmtMbuf( | ||
3891 | SK_AC *pAC, /* pointer to adapter context */ | ||
3892 | SK_IOC IoC, /* the IO-context */ | ||
3893 | unsigned BufferSize) /* size of the requested buffer */ | ||
3894 | { | ||
3895 | SK_MBUF *pRlmtMbuf; /* pointer to a new rlmt-mbuf structure */ | ||
3896 | struct sk_buff *pMsgBlock; /* pointer to a new message block */ | ||
3897 | |||
3898 | pMsgBlock = alloc_skb(BufferSize + sizeof(SK_MBUF), GFP_ATOMIC); | ||
3899 | if (pMsgBlock == NULL) { | ||
3900 | return (NULL); | ||
3901 | } | ||
3902 | pRlmtMbuf = (SK_MBUF*) pMsgBlock->data; | ||
3903 | skb_reserve(pMsgBlock, sizeof(SK_MBUF)); | ||
3904 | pRlmtMbuf->pNext = NULL; | ||
3905 | pRlmtMbuf->pOs = pMsgBlock; | ||
3906 | pRlmtMbuf->pData = pMsgBlock->data; /* Data buffer. */ | ||
3907 | pRlmtMbuf->Size = BufferSize; /* Data buffer size. */ | ||
3908 | pRlmtMbuf->Length = 0; /* Length of packet (<= Size). */ | ||
3909 | return (pRlmtMbuf); | ||
3910 | |||
3911 | } /* SkDrvAllocRlmtMbuf */ | ||
3912 | |||
3913 | |||
3914 | /***************************************************************************** | ||
3915 | * | ||
3916 | * SkDrvFreeRlmtMbuf - free an RLMT mbuf | ||
3917 | * | ||
3918 | * Description: | ||
3919 | * This routine frees one or more RLMT mbuf(s). | ||
3920 | * | ||
3921 | * Context: | ||
3922 | * runtime | ||
3923 | * | ||
3924 | * Returns: | ||
3925 | * Nothing | ||
3926 | */ | ||
3927 | void SkDrvFreeRlmtMbuf( | ||
3928 | SK_AC *pAC, /* pointer to adapter context */ | ||
3929 | SK_IOC IoC, /* the IO-context */ | ||
3930 | SK_MBUF *pMbuf) /* size of the requested buffer */ | ||
3931 | { | ||
3932 | SK_MBUF *pFreeMbuf; | ||
3933 | SK_MBUF *pNextMbuf; | ||
3934 | |||
3935 | pFreeMbuf = pMbuf; | ||
3936 | do { | ||
3937 | pNextMbuf = pFreeMbuf->pNext; | ||
3938 | DEV_KFREE_SKB_ANY(pFreeMbuf->pOs); | ||
3939 | pFreeMbuf = pNextMbuf; | ||
3940 | } while ( pFreeMbuf != NULL ); | ||
3941 | } /* SkDrvFreeRlmtMbuf */ | ||
3942 | |||
3943 | |||
3944 | /***************************************************************************** | ||
3945 | * | ||
3946 | * SkOsGetTime - provide a time value | ||
3947 | * | ||
3948 | * Description: | ||
3949 | * This routine provides a time value. The unit is 1/HZ (defined by Linux). | ||
3950 | * It is not used for absolute time, but only for time differences. | ||
3951 | * | ||
3952 | * | ||
3953 | * Returns: | ||
3954 | * Time value | ||
3955 | */ | ||
3956 | SK_U64 SkOsGetTime(SK_AC *pAC) | ||
3957 | { | ||
3958 | SK_U64 PrivateJiffies; | ||
3959 | SkOsGetTimeCurrent(pAC, &PrivateJiffies); | ||
3960 | return PrivateJiffies; | ||
3961 | } /* SkOsGetTime */ | ||
3962 | |||
3963 | |||
3964 | /***************************************************************************** | ||
3965 | * | ||
3966 | * SkPciReadCfgDWord - read a 32 bit value from pci config space | ||
3967 | * | ||
3968 | * Description: | ||
3969 | * This routine reads a 32 bit value from the pci configuration | ||
3970 | * space. | ||
3971 | * | ||
3972 | * Returns: | ||
3973 | * 0 - indicate everything worked ok. | ||
3974 | * != 0 - error indication | ||
3975 | */ | ||
3976 | int SkPciReadCfgDWord( | ||
3977 | SK_AC *pAC, /* Adapter Control structure pointer */ | ||
3978 | int PciAddr, /* PCI register address */ | ||
3979 | SK_U32 *pVal) /* pointer to store the read value */ | ||
3980 | { | ||
3981 | pci_read_config_dword(pAC->PciDev, PciAddr, pVal); | ||
3982 | return(0); | ||
3983 | } /* SkPciReadCfgDWord */ | ||
3984 | |||
3985 | |||
3986 | /***************************************************************************** | ||
3987 | * | ||
3988 | * SkPciReadCfgWord - read a 16 bit value from pci config space | ||
3989 | * | ||
3990 | * Description: | ||
3991 | * This routine reads a 16 bit value from the pci configuration | ||
3992 | * space. | ||
3993 | * | ||
3994 | * Returns: | ||
3995 | * 0 - indicate everything worked ok. | ||
3996 | * != 0 - error indication | ||
3997 | */ | ||
3998 | int SkPciReadCfgWord( | ||
3999 | SK_AC *pAC, /* Adapter Control structure pointer */ | ||
4000 | int PciAddr, /* PCI register address */ | ||
4001 | SK_U16 *pVal) /* pointer to store the read value */ | ||
4002 | { | ||
4003 | pci_read_config_word(pAC->PciDev, PciAddr, pVal); | ||
4004 | return(0); | ||
4005 | } /* SkPciReadCfgWord */ | ||
4006 | |||
4007 | |||
4008 | /***************************************************************************** | ||
4009 | * | ||
4010 | * SkPciReadCfgByte - read a 8 bit value from pci config space | ||
4011 | * | ||
4012 | * Description: | ||
4013 | * This routine reads a 8 bit value from the pci configuration | ||
4014 | * space. | ||
4015 | * | ||
4016 | * Returns: | ||
4017 | * 0 - indicate everything worked ok. | ||
4018 | * != 0 - error indication | ||
4019 | */ | ||
4020 | int SkPciReadCfgByte( | ||
4021 | SK_AC *pAC, /* Adapter Control structure pointer */ | ||
4022 | int PciAddr, /* PCI register address */ | ||
4023 | SK_U8 *pVal) /* pointer to store the read value */ | ||
4024 | { | ||
4025 | pci_read_config_byte(pAC->PciDev, PciAddr, pVal); | ||
4026 | return(0); | ||
4027 | } /* SkPciReadCfgByte */ | ||
4028 | |||
4029 | |||
4030 | /***************************************************************************** | ||
4031 | * | ||
4032 | * SkPciWriteCfgWord - write a 16 bit value to pci config space | ||
4033 | * | ||
4034 | * Description: | ||
4035 | * This routine writes a 16 bit value to the pci configuration | ||
4036 | * space. The flag PciConfigUp indicates whether the config space | ||
4037 | * is accesible or must be set up first. | ||
4038 | * | ||
4039 | * Returns: | ||
4040 | * 0 - indicate everything worked ok. | ||
4041 | * != 0 - error indication | ||
4042 | */ | ||
4043 | int SkPciWriteCfgWord( | ||
4044 | SK_AC *pAC, /* Adapter Control structure pointer */ | ||
4045 | int PciAddr, /* PCI register address */ | ||
4046 | SK_U16 Val) /* pointer to store the read value */ | ||
4047 | { | ||
4048 | pci_write_config_word(pAC->PciDev, PciAddr, Val); | ||
4049 | return(0); | ||
4050 | } /* SkPciWriteCfgWord */ | ||
4051 | |||
4052 | |||
4053 | /***************************************************************************** | ||
4054 | * | ||
4055 | * SkPciWriteCfgWord - write a 8 bit value to pci config space | ||
4056 | * | ||
4057 | * Description: | ||
4058 | * This routine writes a 8 bit value to the pci configuration | ||
4059 | * space. The flag PciConfigUp indicates whether the config space | ||
4060 | * is accesible or must be set up first. | ||
4061 | * | ||
4062 | * Returns: | ||
4063 | * 0 - indicate everything worked ok. | ||
4064 | * != 0 - error indication | ||
4065 | */ | ||
4066 | int SkPciWriteCfgByte( | ||
4067 | SK_AC *pAC, /* Adapter Control structure pointer */ | ||
4068 | int PciAddr, /* PCI register address */ | ||
4069 | SK_U8 Val) /* pointer to store the read value */ | ||
4070 | { | ||
4071 | pci_write_config_byte(pAC->PciDev, PciAddr, Val); | ||
4072 | return(0); | ||
4073 | } /* SkPciWriteCfgByte */ | ||
4074 | |||
4075 | |||
4076 | /***************************************************************************** | ||
4077 | * | ||
4078 | * SkDrvEvent - handle driver events | ||
4079 | * | ||
4080 | * Description: | ||
4081 | * This function handles events from all modules directed to the driver | ||
4082 | * | ||
4083 | * Context: | ||
4084 | * Is called under protection of slow path lock. | ||
4085 | * | ||
4086 | * Returns: | ||
4087 | * 0 if everything ok | ||
4088 | * < 0 on error | ||
4089 | * | ||
4090 | */ | ||
4091 | int SkDrvEvent( | ||
4092 | SK_AC *pAC, /* pointer to adapter context */ | ||
4093 | SK_IOC IoC, /* io-context */ | ||
4094 | SK_U32 Event, /* event-id */ | ||
4095 | SK_EVPARA Param) /* event-parameter */ | ||
4096 | { | ||
4097 | SK_MBUF *pRlmtMbuf; /* pointer to a rlmt-mbuf structure */ | ||
4098 | struct sk_buff *pMsg; /* pointer to a message block */ | ||
4099 | int FromPort; /* the port from which we switch away */ | ||
4100 | int ToPort; /* the port we switch to */ | ||
4101 | SK_EVPARA NewPara; /* parameter for further events */ | ||
4102 | int Stat; | ||
4103 | unsigned long Flags; | ||
4104 | SK_BOOL DualNet; | ||
4105 | |||
4106 | switch (Event) { | ||
4107 | case SK_DRV_ADAP_FAIL: | ||
4108 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, | ||
4109 | ("ADAPTER FAIL EVENT\n")); | ||
4110 | printk("%s: Adapter failed.\n", pAC->dev[0]->name); | ||
4111 | /* disable interrupts */ | ||
4112 | SK_OUT32(pAC->IoBase, B0_IMSK, 0); | ||
4113 | /* cgoos */ | ||
4114 | break; | ||
4115 | case SK_DRV_PORT_FAIL: | ||
4116 | FromPort = Param.Para32[0]; | ||
4117 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, | ||
4118 | ("PORT FAIL EVENT, Port: %d\n", FromPort)); | ||
4119 | if (FromPort == 0) { | ||
4120 | printk("%s: Port A failed.\n", pAC->dev[0]->name); | ||
4121 | } else { | ||
4122 | printk("%s: Port B failed.\n", pAC->dev[1]->name); | ||
4123 | } | ||
4124 | /* cgoos */ | ||
4125 | break; | ||
4126 | case SK_DRV_PORT_RESET: /* SK_U32 PortIdx */ | ||
4127 | /* action list 4 */ | ||
4128 | FromPort = Param.Para32[0]; | ||
4129 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, | ||
4130 | ("PORT RESET EVENT, Port: %d ", FromPort)); | ||
4131 | NewPara.Para64 = FromPort; | ||
4132 | SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara); | ||
4133 | spin_lock_irqsave( | ||
4134 | &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, | ||
4135 | Flags); | ||
4136 | |||
4137 | SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST); | ||
4138 | netif_carrier_off(pAC->dev[Param.Para32[0]]); | ||
4139 | spin_unlock_irqrestore( | ||
4140 | &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, | ||
4141 | Flags); | ||
4142 | |||
4143 | /* clear rx ring from received frames */ | ||
4144 | ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); | ||
4145 | |||
4146 | ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]); | ||
4147 | spin_lock_irqsave( | ||
4148 | &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, | ||
4149 | Flags); | ||
4150 | |||
4151 | /* tschilling: Handling of return value inserted. */ | ||
4152 | if (SkGeInitPort(pAC, IoC, FromPort)) { | ||
4153 | if (FromPort == 0) { | ||
4154 | printk("%s: SkGeInitPort A failed.\n", pAC->dev[0]->name); | ||
4155 | } else { | ||
4156 | printk("%s: SkGeInitPort B failed.\n", pAC->dev[1]->name); | ||
4157 | } | ||
4158 | } | ||
4159 | SkAddrMcUpdate(pAC,IoC, FromPort); | ||
4160 | PortReInitBmu(pAC, FromPort); | ||
4161 | SkGePollTxD(pAC, IoC, FromPort, SK_TRUE); | ||
4162 | ClearAndStartRx(pAC, FromPort); | ||
4163 | spin_unlock_irqrestore( | ||
4164 | &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, | ||
4165 | Flags); | ||
4166 | break; | ||
4167 | case SK_DRV_NET_UP: /* SK_U32 PortIdx */ | ||
4168 | { struct net_device *dev = pAC->dev[Param.Para32[0]]; | ||
4169 | /* action list 5 */ | ||
4170 | FromPort = Param.Para32[0]; | ||
4171 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, | ||
4172 | ("NET UP EVENT, Port: %d ", Param.Para32[0])); | ||
4173 | /* Mac update */ | ||
4174 | SkAddrMcUpdate(pAC,IoC, FromPort); | ||
4175 | |||
4176 | if (DoPrintInterfaceChange) { | ||
4177 | printk("%s: network connection up using" | ||
4178 | " port %c\n", pAC->dev[Param.Para32[0]]->name, 'A'+Param.Para32[0]); | ||
4179 | |||
4180 | /* tschilling: Values changed according to LinkSpeedUsed. */ | ||
4181 | Stat = pAC->GIni.GP[FromPort].PLinkSpeedUsed; | ||
4182 | if (Stat == SK_LSPEED_STAT_10MBPS) { | ||
4183 | printk(" speed: 10\n"); | ||
4184 | } else if (Stat == SK_LSPEED_STAT_100MBPS) { | ||
4185 | printk(" speed: 100\n"); | ||
4186 | } else if (Stat == SK_LSPEED_STAT_1000MBPS) { | ||
4187 | printk(" speed: 1000\n"); | ||
4188 | } else { | ||
4189 | printk(" speed: unknown\n"); | ||
4190 | } | ||
4191 | |||
4192 | |||
4193 | Stat = pAC->GIni.GP[FromPort].PLinkModeStatus; | ||
4194 | if (Stat == SK_LMODE_STAT_AUTOHALF || | ||
4195 | Stat == SK_LMODE_STAT_AUTOFULL) { | ||
4196 | printk(" autonegotiation: yes\n"); | ||
4197 | } | ||
4198 | else { | ||
4199 | printk(" autonegotiation: no\n"); | ||
4200 | } | ||
4201 | if (Stat == SK_LMODE_STAT_AUTOHALF || | ||
4202 | Stat == SK_LMODE_STAT_HALF) { | ||
4203 | printk(" duplex mode: half\n"); | ||
4204 | } | ||
4205 | else { | ||
4206 | printk(" duplex mode: full\n"); | ||
4207 | } | ||
4208 | Stat = pAC->GIni.GP[FromPort].PFlowCtrlStatus; | ||
4209 | if (Stat == SK_FLOW_STAT_REM_SEND ) { | ||
4210 | printk(" flowctrl: remote send\n"); | ||
4211 | } | ||
4212 | else if (Stat == SK_FLOW_STAT_LOC_SEND ){ | ||
4213 | printk(" flowctrl: local send\n"); | ||
4214 | } | ||
4215 | else if (Stat == SK_FLOW_STAT_SYMMETRIC ){ | ||
4216 | printk(" flowctrl: symmetric\n"); | ||
4217 | } | ||
4218 | else { | ||
4219 | printk(" flowctrl: none\n"); | ||
4220 | } | ||
4221 | |||
4222 | /* tschilling: Check against CopperType now. */ | ||
4223 | if ((pAC->GIni.GICopperType == SK_TRUE) && | ||
4224 | (pAC->GIni.GP[FromPort].PLinkSpeedUsed == | ||
4225 | SK_LSPEED_STAT_1000MBPS)) { | ||
4226 | Stat = pAC->GIni.GP[FromPort].PMSStatus; | ||
4227 | if (Stat == SK_MS_STAT_MASTER ) { | ||
4228 | printk(" role: master\n"); | ||
4229 | } | ||
4230 | else if (Stat == SK_MS_STAT_SLAVE ) { | ||
4231 | printk(" role: slave\n"); | ||
4232 | } | ||
4233 | else { | ||
4234 | printk(" role: ???\n"); | ||
4235 | } | ||
4236 | } | ||
4237 | |||
4238 | /* | ||
4239 | Display dim (dynamic interrupt moderation) | ||
4240 | informations | ||
4241 | */ | ||
4242 | if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC) | ||
4243 | printk(" irq moderation: static (%d ints/sec)\n", | ||
4244 | pAC->DynIrqModInfo.MaxModIntsPerSec); | ||
4245 | else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC) | ||
4246 | printk(" irq moderation: dynamic (%d ints/sec)\n", | ||
4247 | pAC->DynIrqModInfo.MaxModIntsPerSec); | ||
4248 | else | ||
4249 | printk(" irq moderation: disabled\n"); | ||
4250 | |||
4251 | |||
4252 | printk(" scatter-gather: %s\n", | ||
4253 | (dev->features & NETIF_F_SG) ? "enabled" : "disabled"); | ||
4254 | printk(" tx-checksum: %s\n", | ||
4255 | (dev->features & NETIF_F_IP_CSUM) ? "enabled" : "disabled"); | ||
4256 | printk(" rx-checksum: %s\n", | ||
4257 | pAC->RxPort[Param.Para32[0]].RxCsum ? "enabled" : "disabled"); | ||
4258 | |||
4259 | } else { | ||
4260 | DoPrintInterfaceChange = SK_TRUE; | ||
4261 | } | ||
4262 | |||
4263 | if ((Param.Para32[0] != pAC->ActivePort) && | ||
4264 | (pAC->RlmtNets == 1)) { | ||
4265 | NewPara.Para32[0] = pAC->ActivePort; | ||
4266 | NewPara.Para32[1] = Param.Para32[0]; | ||
4267 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_INTERN, | ||
4268 | NewPara); | ||
4269 | } | ||
4270 | |||
4271 | /* Inform the world that link protocol is up. */ | ||
4272 | netif_carrier_on(dev); | ||
4273 | break; | ||
4274 | } | ||
4275 | case SK_DRV_NET_DOWN: /* SK_U32 Reason */ | ||
4276 | /* action list 7 */ | ||
4277 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, | ||
4278 | ("NET DOWN EVENT ")); | ||
4279 | if (DoPrintInterfaceChange) { | ||
4280 | printk("%s: network connection down\n", | ||
4281 | pAC->dev[Param.Para32[1]]->name); | ||
4282 | } else { | ||
4283 | DoPrintInterfaceChange = SK_TRUE; | ||
4284 | } | ||
4285 | netif_carrier_off(pAC->dev[Param.Para32[1]]); | ||
4286 | break; | ||
4287 | case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */ | ||
4288 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, | ||
4289 | ("PORT SWITCH HARD ")); | ||
4290 | case SK_DRV_SWITCH_SOFT: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */ | ||
4291 | /* action list 6 */ | ||
4292 | printk("%s: switching to port %c\n", pAC->dev[0]->name, | ||
4293 | 'A'+Param.Para32[1]); | ||
4294 | case SK_DRV_SWITCH_INTERN: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */ | ||
4295 | FromPort = Param.Para32[0]; | ||
4296 | ToPort = Param.Para32[1]; | ||
4297 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, | ||
4298 | ("PORT SWITCH EVENT, From: %d To: %d (Pref %d) ", | ||
4299 | FromPort, ToPort, pAC->Rlmt.Net[0].PrefPort)); | ||
4300 | NewPara.Para64 = FromPort; | ||
4301 | SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara); | ||
4302 | NewPara.Para64 = ToPort; | ||
4303 | SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara); | ||
4304 | spin_lock_irqsave( | ||
4305 | &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, | ||
4306 | Flags); | ||
4307 | spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock); | ||
4308 | SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST); | ||
4309 | SkGeStopPort(pAC, IoC, ToPort, SK_STOP_ALL, SK_SOFT_RST); | ||
4310 | spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock); | ||
4311 | spin_unlock_irqrestore( | ||
4312 | &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, | ||
4313 | Flags); | ||
4314 | |||
4315 | ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); /* clears rx ring */ | ||
4316 | ReceiveIrq(pAC, &pAC->RxPort[ToPort], SK_FALSE); /* clears rx ring */ | ||
4317 | |||
4318 | ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]); | ||
4319 | ClearTxRing(pAC, &pAC->TxPort[ToPort][TX_PRIO_LOW]); | ||
4320 | spin_lock_irqsave( | ||
4321 | &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, | ||
4322 | Flags); | ||
4323 | spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock); | ||
4324 | pAC->ActivePort = ToPort; | ||
4325 | #if 0 | ||
4326 | SetQueueSizes(pAC); | ||
4327 | #else | ||
4328 | /* tschilling: New common function with minimum size check. */ | ||
4329 | DualNet = SK_FALSE; | ||
4330 | if (pAC->RlmtNets == 2) { | ||
4331 | DualNet = SK_TRUE; | ||
4332 | } | ||
4333 | |||
4334 | if (SkGeInitAssignRamToQueues( | ||
4335 | pAC, | ||
4336 | pAC->ActivePort, | ||
4337 | DualNet)) { | ||
4338 | spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock); | ||
4339 | spin_unlock_irqrestore( | ||
4340 | &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, | ||
4341 | Flags); | ||
4342 | printk("SkGeInitAssignRamToQueues failed.\n"); | ||
4343 | break; | ||
4344 | } | ||
4345 | #endif | ||
4346 | /* tschilling: Handling of return values inserted. */ | ||
4347 | if (SkGeInitPort(pAC, IoC, FromPort) || | ||
4348 | SkGeInitPort(pAC, IoC, ToPort)) { | ||
4349 | printk("%s: SkGeInitPort failed.\n", pAC->dev[0]->name); | ||
4350 | } | ||
4351 | if (Event == SK_DRV_SWITCH_SOFT) { | ||
4352 | SkMacRxTxEnable(pAC, IoC, FromPort); | ||
4353 | } | ||
4354 | SkMacRxTxEnable(pAC, IoC, ToPort); | ||
4355 | SkAddrSwap(pAC, IoC, FromPort, ToPort); | ||
4356 | SkAddrMcUpdate(pAC, IoC, FromPort); | ||
4357 | SkAddrMcUpdate(pAC, IoC, ToPort); | ||
4358 | PortReInitBmu(pAC, FromPort); | ||
4359 | PortReInitBmu(pAC, ToPort); | ||
4360 | SkGePollTxD(pAC, IoC, FromPort, SK_TRUE); | ||
4361 | SkGePollTxD(pAC, IoC, ToPort, SK_TRUE); | ||
4362 | ClearAndStartRx(pAC, FromPort); | ||
4363 | ClearAndStartRx(pAC, ToPort); | ||
4364 | spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock); | ||
4365 | spin_unlock_irqrestore( | ||
4366 | &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, | ||
4367 | Flags); | ||
4368 | break; | ||
4369 | case SK_DRV_RLMT_SEND: /* SK_MBUF *pMb */ | ||
4370 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, | ||
4371 | ("RLS ")); | ||
4372 | pRlmtMbuf = (SK_MBUF*) Param.pParaPtr; | ||
4373 | pMsg = (struct sk_buff*) pRlmtMbuf->pOs; | ||
4374 | skb_put(pMsg, pRlmtMbuf->Length); | ||
4375 | if (XmitFrame(pAC, &pAC->TxPort[pRlmtMbuf->PortIdx][TX_PRIO_LOW], | ||
4376 | pMsg) < 0) | ||
4377 | |||
4378 | DEV_KFREE_SKB_ANY(pMsg); | ||
4379 | break; | ||
4380 | case SK_DRV_TIMER: | ||
4381 | if (Param.Para32[0] == SK_DRV_MODERATION_TIMER) { | ||
4382 | /* | ||
4383 | ** expiration of the moderation timer implies that | ||
4384 | ** dynamic moderation is to be applied | ||
4385 | */ | ||
4386 | SkDimStartModerationTimer(pAC); | ||
4387 | SkDimModerate(pAC); | ||
4388 | if (pAC->DynIrqModInfo.DisplayStats) { | ||
4389 | SkDimDisplayModerationSettings(pAC); | ||
4390 | } | ||
4391 | } else if (Param.Para32[0] == SK_DRV_RX_CLEANUP_TIMER) { | ||
4392 | /* | ||
4393 | ** check if we need to check for descriptors which | ||
4394 | ** haven't been handled the last millisecs | ||
4395 | */ | ||
4396 | StartDrvCleanupTimer(pAC); | ||
4397 | if (pAC->GIni.GIMacsFound == 2) { | ||
4398 | ReceiveIrq(pAC, &pAC->RxPort[1], SK_FALSE); | ||
4399 | } | ||
4400 | ReceiveIrq(pAC, &pAC->RxPort[0], SK_FALSE); | ||
4401 | } else { | ||
4402 | printk("Expiration of unknown timer\n"); | ||
4403 | } | ||
4404 | break; | ||
4405 | default: | ||
4406 | break; | ||
4407 | } | ||
4408 | SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, | ||
4409 | ("END EVENT ")); | ||
4410 | |||
4411 | return (0); | ||
4412 | } /* SkDrvEvent */ | ||
4413 | |||
4414 | |||
4415 | /***************************************************************************** | ||
4416 | * | ||
4417 | * SkErrorLog - log errors | ||
4418 | * | ||
4419 | * Description: | ||
4420 | * This function logs errors to the system buffer and to the console | ||
4421 | * | ||
4422 | * Returns: | ||
4423 | * 0 if everything ok | ||
4424 | * < 0 on error | ||
4425 | * | ||
4426 | */ | ||
4427 | void SkErrorLog( | ||
4428 | SK_AC *pAC, | ||
4429 | int ErrClass, | ||
4430 | int ErrNum, | ||
4431 | char *pErrorMsg) | ||
4432 | { | ||
4433 | char ClassStr[80]; | ||
4434 | |||
4435 | switch (ErrClass) { | ||
4436 | case SK_ERRCL_OTHER: | ||
4437 | strcpy(ClassStr, "Other error"); | ||
4438 | break; | ||
4439 | case SK_ERRCL_CONFIG: | ||
4440 | strcpy(ClassStr, "Configuration error"); | ||
4441 | break; | ||
4442 | case SK_ERRCL_INIT: | ||
4443 | strcpy(ClassStr, "Initialization error"); | ||
4444 | break; | ||
4445 | case SK_ERRCL_NORES: | ||
4446 | strcpy(ClassStr, "Out of resources error"); | ||
4447 | break; | ||
4448 | case SK_ERRCL_SW: | ||
4449 | strcpy(ClassStr, "internal Software error"); | ||
4450 | break; | ||
4451 | case SK_ERRCL_HW: | ||
4452 | strcpy(ClassStr, "Hardware failure"); | ||
4453 | break; | ||
4454 | case SK_ERRCL_COMM: | ||
4455 | strcpy(ClassStr, "Communication error"); | ||
4456 | break; | ||
4457 | } | ||
4458 | printk(KERN_INFO "%s: -- ERROR --\n Class: %s\n" | ||
4459 | " Nr: 0x%x\n Msg: %s\n", pAC->dev[0]->name, | ||
4460 | ClassStr, ErrNum, pErrorMsg); | ||
4461 | |||
4462 | } /* SkErrorLog */ | ||
4463 | |||
4464 | #ifdef SK_DIAG_SUPPORT | ||
4465 | |||
4466 | /***************************************************************************** | ||
4467 | * | ||
4468 | * SkDrvEnterDiagMode - handles DIAG attach request | ||
4469 | * | ||
4470 | * Description: | ||
4471 | * Notify the kernel to NOT access the card any longer due to DIAG | ||
4472 | * Deinitialize the Card | ||
4473 | * | ||
4474 | * Returns: | ||
4475 | * int | ||
4476 | */ | ||
4477 | int SkDrvEnterDiagMode( | ||
4478 | SK_AC *pAc) /* pointer to adapter context */ | ||
4479 | { | ||
4480 | DEV_NET *pNet = netdev_priv(pAc->dev[0]); | ||
4481 | SK_AC *pAC = pNet->pAC; | ||
4482 | |||
4483 | SK_MEMCPY(&(pAc->PnmiBackup), &(pAc->PnmiStruct), | ||
4484 | sizeof(SK_PNMI_STRUCT_DATA)); | ||
4485 | |||
4486 | pAC->DiagModeActive = DIAG_ACTIVE; | ||
4487 | if (pAC->BoardLevel > SK_INIT_DATA) { | ||
4488 | if (netif_running(pAC->dev[0])) { | ||
4489 | pAC->WasIfUp[0] = SK_TRUE; | ||
4490 | pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ | ||
4491 | DoPrintInterfaceChange = SK_FALSE; | ||
4492 | SkDrvDeInitAdapter(pAC, 0); /* performs SkGeClose */ | ||
4493 | } else { | ||
4494 | pAC->WasIfUp[0] = SK_FALSE; | ||
4495 | } | ||
4496 | if (pNet != netdev_priv(pAC->dev[1])) { | ||
4497 | pNet = netdev_priv(pAC->dev[1]); | ||
4498 | if (netif_running(pAC->dev[1])) { | ||
4499 | pAC->WasIfUp[1] = SK_TRUE; | ||
4500 | pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ | ||
4501 | DoPrintInterfaceChange = SK_FALSE; | ||
4502 | SkDrvDeInitAdapter(pAC, 1); /* do SkGeClose */ | ||
4503 | } else { | ||
4504 | pAC->WasIfUp[1] = SK_FALSE; | ||
4505 | } | ||
4506 | } | ||
4507 | pAC->BoardLevel = SK_INIT_DATA; | ||
4508 | } | ||
4509 | return(0); | ||
4510 | } | ||
4511 | |||
4512 | /***************************************************************************** | ||
4513 | * | ||
4514 | * SkDrvLeaveDiagMode - handles DIAG detach request | ||
4515 | * | ||
4516 | * Description: | ||
4517 | * Notify the kernel to may access the card again after use by DIAG | ||
4518 | * Initialize the Card | ||
4519 | * | ||
4520 | * Returns: | ||
4521 | * int | ||
4522 | */ | ||
4523 | int SkDrvLeaveDiagMode( | ||
4524 | SK_AC *pAc) /* pointer to adapter control context */ | ||
4525 | { | ||
4526 | SK_MEMCPY(&(pAc->PnmiStruct), &(pAc->PnmiBackup), | ||
4527 | sizeof(SK_PNMI_STRUCT_DATA)); | ||
4528 | pAc->DiagModeActive = DIAG_NOTACTIVE; | ||
4529 | pAc->Pnmi.DiagAttached = SK_DIAG_IDLE; | ||
4530 | if (pAc->WasIfUp[0] == SK_TRUE) { | ||
4531 | pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ | ||
4532 | DoPrintInterfaceChange = SK_FALSE; | ||
4533 | SkDrvInitAdapter(pAc, 0); /* first device */ | ||
4534 | } | ||
4535 | if (pAc->WasIfUp[1] == SK_TRUE) { | ||
4536 | pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ | ||
4537 | DoPrintInterfaceChange = SK_FALSE; | ||
4538 | SkDrvInitAdapter(pAc, 1); /* second device */ | ||
4539 | } | ||
4540 | return(0); | ||
4541 | } | ||
4542 | |||
4543 | /***************************************************************************** | ||
4544 | * | ||
4545 | * ParseDeviceNbrFromSlotName - Evaluate PCI device number | ||
4546 | * | ||
4547 | * Description: | ||
4548 | * This function parses the PCI slot name information string and will | ||
4549 | * retrieve the devcie number out of it. The slot_name maintianed by | ||
4550 | * linux is in the form of '02:0a.0', whereas the first two characters | ||
4551 | * represent the bus number in hex (in the sample above this is | ||
4552 | * pci bus 0x02) and the next two characters the device number (0x0a). | ||
4553 | * | ||
4554 | * Returns: | ||
4555 | * SK_U32: The device number from the PCI slot name | ||
4556 | */ | ||
4557 | |||
4558 | static SK_U32 ParseDeviceNbrFromSlotName( | ||
4559 | const char *SlotName) /* pointer to pci slot name eg. '02:0a.0' */ | ||
4560 | { | ||
4561 | char *CurrCharPos = (char *) SlotName; | ||
4562 | int FirstNibble = -1; | ||
4563 | int SecondNibble = -1; | ||
4564 | SK_U32 Result = 0; | ||
4565 | |||
4566 | while (*CurrCharPos != '\0') { | ||
4567 | if (*CurrCharPos == ':') { | ||
4568 | while (*CurrCharPos != '.') { | ||
4569 | CurrCharPos++; | ||
4570 | if ( (*CurrCharPos >= '0') && | ||
4571 | (*CurrCharPos <= '9')) { | ||
4572 | if (FirstNibble == -1) { | ||
4573 | /* dec. value for '0' */ | ||
4574 | FirstNibble = *CurrCharPos - 48; | ||
4575 | } else { | ||
4576 | SecondNibble = *CurrCharPos - 48; | ||
4577 | } | ||
4578 | } else if ( (*CurrCharPos >= 'a') && | ||
4579 | (*CurrCharPos <= 'f') ) { | ||
4580 | if (FirstNibble == -1) { | ||
4581 | FirstNibble = *CurrCharPos - 87; | ||
4582 | } else { | ||
4583 | SecondNibble = *CurrCharPos - 87; | ||
4584 | } | ||
4585 | } else { | ||
4586 | Result = 0; | ||
4587 | } | ||
4588 | } | ||
4589 | |||
4590 | Result = FirstNibble; | ||
4591 | Result = Result << 4; /* first nibble is higher one */ | ||
4592 | Result = Result | SecondNibble; | ||
4593 | } | ||
4594 | CurrCharPos++; /* next character */ | ||
4595 | } | ||
4596 | return (Result); | ||
4597 | } | ||
4598 | |||
4599 | /**************************************************************************** | ||
4600 | * | ||
4601 | * SkDrvDeInitAdapter - deinitialize adapter (this function is only | ||
4602 | * called if Diag attaches to that card) | ||
4603 | * | ||
4604 | * Description: | ||
4605 | * Close initialized adapter. | ||
4606 | * | ||
4607 | * Returns: | ||
4608 | * 0 - on success | ||
4609 | * error code - on error | ||
4610 | */ | ||
4611 | static int SkDrvDeInitAdapter( | ||
4612 | SK_AC *pAC, /* pointer to adapter context */ | ||
4613 | int devNbr) /* what device is to be handled */ | ||
4614 | { | ||
4615 | struct SK_NET_DEVICE *dev; | ||
4616 | |||
4617 | dev = pAC->dev[devNbr]; | ||
4618 | |||
4619 | /* On Linux 2.6 the network driver does NOT mess with reference | ||
4620 | ** counts. The driver MUST be able to be unloaded at any time | ||
4621 | ** due to the possibility of hotplug. | ||
4622 | */ | ||
4623 | if (SkGeClose(dev) != 0) { | ||
4624 | return (-1); | ||
4625 | } | ||
4626 | return (0); | ||
4627 | |||
4628 | } /* SkDrvDeInitAdapter() */ | ||
4629 | |||
4630 | /**************************************************************************** | ||
4631 | * | ||
4632 | * SkDrvInitAdapter - Initialize adapter (this function is only | ||
4633 | * called if Diag deattaches from that card) | ||
4634 | * | ||
4635 | * Description: | ||
4636 | * Close initialized adapter. | ||
4637 | * | ||
4638 | * Returns: | ||
4639 | * 0 - on success | ||
4640 | * error code - on error | ||
4641 | */ | ||
4642 | static int SkDrvInitAdapter( | ||
4643 | SK_AC *pAC, /* pointer to adapter context */ | ||
4644 | int devNbr) /* what device is to be handled */ | ||
4645 | { | ||
4646 | struct SK_NET_DEVICE *dev; | ||
4647 | |||
4648 | dev = pAC->dev[devNbr]; | ||
4649 | |||
4650 | if (SkGeOpen(dev) != 0) { | ||
4651 | return (-1); | ||
4652 | } | ||
4653 | |||
4654 | /* | ||
4655 | ** Use correct MTU size and indicate to kernel TX queue can be started | ||
4656 | */ | ||
4657 | if (SkGeChangeMtu(dev, dev->mtu) != 0) { | ||
4658 | return (-1); | ||
4659 | } | ||
4660 | return (0); | ||
4661 | |||
4662 | } /* SkDrvInitAdapter */ | ||
4663 | |||
4664 | #endif | ||
4665 | |||
4666 | #ifdef DEBUG | ||
4667 | /****************************************************************************/ | ||
4668 | /* "debug only" section *****************************************************/ | ||
4669 | /****************************************************************************/ | ||
4670 | |||
4671 | |||
4672 | /***************************************************************************** | ||
4673 | * | ||
4674 | * DumpMsg - print a frame | ||
4675 | * | ||
4676 | * Description: | ||
4677 | * This function prints frames to the system logfile/to the console. | ||
4678 | * | ||
4679 | * Returns: N/A | ||
4680 | * | ||
4681 | */ | ||
4682 | static void DumpMsg(struct sk_buff *skb, char *str) | ||
4683 | { | ||
4684 | int msglen; | ||
4685 | |||
4686 | if (skb == NULL) { | ||
4687 | printk("DumpMsg(): NULL-Message\n"); | ||
4688 | return; | ||
4689 | } | ||
4690 | |||
4691 | if (skb->data == NULL) { | ||
4692 | printk("DumpMsg(): Message empty\n"); | ||
4693 | return; | ||
4694 | } | ||
4695 | |||
4696 | msglen = skb->len; | ||
4697 | if (msglen > 64) | ||
4698 | msglen = 64; | ||
4699 | |||
4700 | printk("--- Begin of message from %s , len %d (from %d) ----\n", str, msglen, skb->len); | ||
4701 | |||
4702 | DumpData((char *)skb->data, msglen); | ||
4703 | |||
4704 | printk("------- End of message ---------\n"); | ||
4705 | } /* DumpMsg */ | ||
4706 | |||
4707 | |||
4708 | |||
4709 | /***************************************************************************** | ||
4710 | * | ||
4711 | * DumpData - print a data area | ||
4712 | * | ||
4713 | * Description: | ||
4714 | * This function prints a area of data to the system logfile/to the | ||
4715 | * console. | ||
4716 | * | ||
4717 | * Returns: N/A | ||
4718 | * | ||
4719 | */ | ||
4720 | static void DumpData(char *p, int size) | ||
4721 | { | ||
4722 | register int i; | ||
4723 | int haddr, addr; | ||
4724 | char hex_buffer[180]; | ||
4725 | char asc_buffer[180]; | ||
4726 | char HEXCHAR[] = "0123456789ABCDEF"; | ||
4727 | |||
4728 | addr = 0; | ||
4729 | haddr = 0; | ||
4730 | hex_buffer[0] = 0; | ||
4731 | asc_buffer[0] = 0; | ||
4732 | for (i=0; i < size; ) { | ||
4733 | if (*p >= '0' && *p <='z') | ||
4734 | asc_buffer[addr] = *p; | ||
4735 | else | ||
4736 | asc_buffer[addr] = '.'; | ||
4737 | addr++; | ||
4738 | asc_buffer[addr] = 0; | ||
4739 | hex_buffer[haddr] = HEXCHAR[(*p & 0xf0) >> 4]; | ||
4740 | haddr++; | ||
4741 | hex_buffer[haddr] = HEXCHAR[*p & 0x0f]; | ||
4742 | haddr++; | ||
4743 | hex_buffer[haddr] = ' '; | ||
4744 | haddr++; | ||
4745 | hex_buffer[haddr] = 0; | ||
4746 | p++; | ||
4747 | i++; | ||
4748 | if (i%16 == 0) { | ||
4749 | printk("%s %s\n", hex_buffer, asc_buffer); | ||
4750 | addr = 0; | ||
4751 | haddr = 0; | ||
4752 | } | ||
4753 | } | ||
4754 | } /* DumpData */ | ||
4755 | |||
4756 | |||
4757 | /***************************************************************************** | ||
4758 | * | ||
4759 | * DumpLong - print a data area as long values | ||
4760 | * | ||
4761 | * Description: | ||
4762 | * This function prints a area of data to the system logfile/to the | ||
4763 | * console. | ||
4764 | * | ||
4765 | * Returns: N/A | ||
4766 | * | ||
4767 | */ | ||
4768 | static void DumpLong(char *pc, int size) | ||
4769 | { | ||
4770 | register int i; | ||
4771 | int haddr, addr; | ||
4772 | char hex_buffer[180]; | ||
4773 | char asc_buffer[180]; | ||
4774 | char HEXCHAR[] = "0123456789ABCDEF"; | ||
4775 | long *p; | ||
4776 | int l; | ||
4777 | |||
4778 | addr = 0; | ||
4779 | haddr = 0; | ||
4780 | hex_buffer[0] = 0; | ||
4781 | asc_buffer[0] = 0; | ||
4782 | p = (long*) pc; | ||
4783 | for (i=0; i < size; ) { | ||
4784 | l = (long) *p; | ||
4785 | hex_buffer[haddr] = HEXCHAR[(l >> 28) & 0xf]; | ||
4786 | haddr++; | ||
4787 | hex_buffer[haddr] = HEXCHAR[(l >> 24) & 0xf]; | ||
4788 | haddr++; | ||
4789 | hex_buffer[haddr] = HEXCHAR[(l >> 20) & 0xf]; | ||
4790 | haddr++; | ||
4791 | hex_buffer[haddr] = HEXCHAR[(l >> 16) & 0xf]; | ||
4792 | haddr++; | ||
4793 | hex_buffer[haddr] = HEXCHAR[(l >> 12) & 0xf]; | ||
4794 | haddr++; | ||
4795 | hex_buffer[haddr] = HEXCHAR[(l >> 8) & 0xf]; | ||
4796 | haddr++; | ||
4797 | hex_buffer[haddr] = HEXCHAR[(l >> 4) & 0xf]; | ||
4798 | haddr++; | ||
4799 | hex_buffer[haddr] = HEXCHAR[l & 0x0f]; | ||
4800 | haddr++; | ||
4801 | hex_buffer[haddr] = ' '; | ||
4802 | haddr++; | ||
4803 | hex_buffer[haddr] = 0; | ||
4804 | p++; | ||
4805 | i++; | ||
4806 | if (i%8 == 0) { | ||
4807 | printk("%4x %s\n", (i-8)*4, hex_buffer); | ||
4808 | haddr = 0; | ||
4809 | } | ||
4810 | } | ||
4811 | printk("------------------------\n"); | ||
4812 | } /* DumpLong */ | ||
4813 | |||
4814 | #endif | ||
4815 | |||
4816 | static int __devinit skge_probe_one(struct pci_dev *pdev, | ||
4817 | const struct pci_device_id *ent) | ||
4818 | { | ||
4819 | SK_AC *pAC; | ||
4820 | DEV_NET *pNet = NULL; | ||
4821 | struct net_device *dev = NULL; | ||
4822 | static int boards_found = 0; | ||
4823 | int error = -ENODEV; | ||
4824 | int using_dac = 0; | ||
4825 | char DeviceStr[80]; | ||
4826 | |||
4827 | if (pci_enable_device(pdev)) | ||
4828 | goto out; | ||
4829 | |||
4830 | /* Configure DMA attributes. */ | ||
4831 | if (sizeof(dma_addr_t) > sizeof(u32) && | ||
4832 | !(error = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) { | ||
4833 | using_dac = 1; | ||
4834 | error = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); | ||
4835 | if (error < 0) { | ||
4836 | printk(KERN_ERR "sk98lin %s unable to obtain 64 bit DMA " | ||
4837 | "for consistent allocations\n", pci_name(pdev)); | ||
4838 | goto out_disable_device; | ||
4839 | } | ||
4840 | } else { | ||
4841 | error = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
4842 | if (error) { | ||
4843 | printk(KERN_ERR "sk98lin %s no usable DMA configuration\n", | ||
4844 | pci_name(pdev)); | ||
4845 | goto out_disable_device; | ||
4846 | } | ||
4847 | } | ||
4848 | |||
4849 | error = -ENOMEM; | ||
4850 | dev = alloc_etherdev(sizeof(DEV_NET)); | ||
4851 | if (!dev) { | ||
4852 | printk(KERN_ERR "sk98lin: unable to allocate etherdev " | ||
4853 | "structure!\n"); | ||
4854 | goto out_disable_device; | ||
4855 | } | ||
4856 | |||
4857 | pNet = netdev_priv(dev); | ||
4858 | pNet->pAC = kzalloc(sizeof(SK_AC), GFP_KERNEL); | ||
4859 | if (!pNet->pAC) { | ||
4860 | printk(KERN_ERR "sk98lin: unable to allocate adapter " | ||
4861 | "structure!\n"); | ||
4862 | goto out_free_netdev; | ||
4863 | } | ||
4864 | |||
4865 | pAC = pNet->pAC; | ||
4866 | pAC->PciDev = pdev; | ||
4867 | |||
4868 | pAC->dev[0] = dev; | ||
4869 | pAC->dev[1] = dev; | ||
4870 | pAC->CheckQueue = SK_FALSE; | ||
4871 | |||
4872 | dev->irq = pdev->irq; | ||
4873 | |||
4874 | error = SkGeInitPCI(pAC); | ||
4875 | if (error) { | ||
4876 | printk(KERN_ERR "sk98lin: PCI setup failed: %i\n", error); | ||
4877 | goto out_free_netdev; | ||
4878 | } | ||
4879 | |||
4880 | SET_MODULE_OWNER(dev); | ||
4881 | dev->open = &SkGeOpen; | ||
4882 | dev->stop = &SkGeClose; | ||
4883 | dev->hard_start_xmit = &SkGeXmit; | ||
4884 | dev->get_stats = &SkGeStats; | ||
4885 | dev->set_multicast_list = &SkGeSetRxMode; | ||
4886 | dev->set_mac_address = &SkGeSetMacAddr; | ||
4887 | dev->do_ioctl = &SkGeIoctl; | ||
4888 | dev->change_mtu = &SkGeChangeMtu; | ||
4889 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
4890 | dev->poll_controller = &SkGePollController; | ||
4891 | #endif | ||
4892 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
4893 | SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps); | ||
4894 | |||
4895 | /* Use only if yukon hardware */ | ||
4896 | if (pAC->ChipsetType) { | ||
4897 | #ifdef USE_SK_TX_CHECKSUM | ||
4898 | dev->features |= NETIF_F_IP_CSUM; | ||
4899 | #endif | ||
4900 | #ifdef SK_ZEROCOPY | ||
4901 | dev->features |= NETIF_F_SG; | ||
4902 | #endif | ||
4903 | #ifdef USE_SK_RX_CHECKSUM | ||
4904 | pAC->RxPort[0].RxCsum = 1; | ||
4905 | #endif | ||
4906 | } | ||
4907 | |||
4908 | if (using_dac) | ||
4909 | dev->features |= NETIF_F_HIGHDMA; | ||
4910 | |||
4911 | pAC->Index = boards_found++; | ||
4912 | |||
4913 | error = SkGeBoardInit(dev, pAC); | ||
4914 | if (error) | ||
4915 | goto out_free_netdev; | ||
4916 | |||
4917 | /* Read Adapter name from VPD */ | ||
4918 | if (ProductStr(pAC, DeviceStr, sizeof(DeviceStr)) != 0) { | ||
4919 | error = -EIO; | ||
4920 | printk(KERN_ERR "sk98lin: Could not read VPD data.\n"); | ||
4921 | goto out_free_resources; | ||
4922 | } | ||
4923 | |||
4924 | /* Register net device */ | ||
4925 | error = register_netdev(dev); | ||
4926 | if (error) { | ||
4927 | printk(KERN_ERR "sk98lin: Could not register device.\n"); | ||
4928 | goto out_free_resources; | ||
4929 | } | ||
4930 | |||
4931 | /* Print adapter specific string from vpd */ | ||
4932 | printk("%s: %s\n", dev->name, DeviceStr); | ||
4933 | |||
4934 | /* Print configuration settings */ | ||
4935 | printk(" PrefPort:%c RlmtMode:%s\n", | ||
4936 | 'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber, | ||
4937 | (pAC->RlmtMode==0) ? "Check Link State" : | ||
4938 | ((pAC->RlmtMode==1) ? "Check Link State" : | ||
4939 | ((pAC->RlmtMode==3) ? "Check Local Port" : | ||
4940 | ((pAC->RlmtMode==7) ? "Check Segmentation" : | ||
4941 | ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error"))))); | ||
4942 | |||
4943 | SkGeYellowLED(pAC, pAC->IoBase, 1); | ||
4944 | |||
4945 | memcpy(&dev->dev_addr, &pAC->Addr.Net[0].CurrentMacAddress, 6); | ||
4946 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); | ||
4947 | |||
4948 | pNet->PortNr = 0; | ||
4949 | pNet->NetNr = 0; | ||
4950 | |||
4951 | boards_found++; | ||
4952 | |||
4953 | pci_set_drvdata(pdev, dev); | ||
4954 | |||
4955 | /* More then one port found */ | ||
4956 | if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { | ||
4957 | dev = alloc_etherdev(sizeof(DEV_NET)); | ||
4958 | if (!dev) { | ||
4959 | printk(KERN_ERR "sk98lin: unable to allocate etherdev " | ||
4960 | "structure!\n"); | ||
4961 | goto single_port; | ||
4962 | } | ||
4963 | |||
4964 | pNet = netdev_priv(dev); | ||
4965 | pNet->PortNr = 1; | ||
4966 | pNet->NetNr = 1; | ||
4967 | pNet->pAC = pAC; | ||
4968 | |||
4969 | dev->open = &SkGeOpen; | ||
4970 | dev->stop = &SkGeClose; | ||
4971 | dev->hard_start_xmit = &SkGeXmit; | ||
4972 | dev->get_stats = &SkGeStats; | ||
4973 | dev->set_multicast_list = &SkGeSetRxMode; | ||
4974 | dev->set_mac_address = &SkGeSetMacAddr; | ||
4975 | dev->do_ioctl = &SkGeIoctl; | ||
4976 | dev->change_mtu = &SkGeChangeMtu; | ||
4977 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
4978 | SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps); | ||
4979 | |||
4980 | if (pAC->ChipsetType) { | ||
4981 | #ifdef USE_SK_TX_CHECKSUM | ||
4982 | dev->features |= NETIF_F_IP_CSUM; | ||
4983 | #endif | ||
4984 | #ifdef SK_ZEROCOPY | ||
4985 | dev->features |= NETIF_F_SG; | ||
4986 | #endif | ||
4987 | #ifdef USE_SK_RX_CHECKSUM | ||
4988 | pAC->RxPort[1].RxCsum = 1; | ||
4989 | #endif | ||
4990 | } | ||
4991 | |||
4992 | if (using_dac) | ||
4993 | dev->features |= NETIF_F_HIGHDMA; | ||
4994 | |||
4995 | error = register_netdev(dev); | ||
4996 | if (error) { | ||
4997 | printk(KERN_ERR "sk98lin: Could not register device" | ||
4998 | " for second port. (%d)\n", error); | ||
4999 | free_netdev(dev); | ||
5000 | goto single_port; | ||
5001 | } | ||
5002 | |||
5003 | pAC->dev[1] = dev; | ||
5004 | memcpy(&dev->dev_addr, | ||
5005 | &pAC->Addr.Net[1].CurrentMacAddress, 6); | ||
5006 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); | ||
5007 | |||
5008 | printk("%s: %s\n", dev->name, DeviceStr); | ||
5009 | printk(" PrefPort:B RlmtMode:Dual Check Link State\n"); | ||
5010 | } | ||
5011 | |||
5012 | single_port: | ||
5013 | |||
5014 | /* Save the hardware revision */ | ||
5015 | pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) + | ||
5016 | (pAC->GIni.GIPciHwRev & 0x0F); | ||
5017 | |||
5018 | /* Set driver globals */ | ||
5019 | pAC->Pnmi.pDriverFileName = DRIVER_FILE_NAME; | ||
5020 | pAC->Pnmi.pDriverReleaseDate = DRIVER_REL_DATE; | ||
5021 | |||
5022 | memset(&pAC->PnmiBackup, 0, sizeof(SK_PNMI_STRUCT_DATA)); | ||
5023 | memcpy(&pAC->PnmiBackup, &pAC->PnmiStruct, sizeof(SK_PNMI_STRUCT_DATA)); | ||
5024 | |||
5025 | return 0; | ||
5026 | |||
5027 | out_free_resources: | ||
5028 | FreeResources(dev); | ||
5029 | out_free_netdev: | ||
5030 | free_netdev(dev); | ||
5031 | out_disable_device: | ||
5032 | pci_disable_device(pdev); | ||
5033 | out: | ||
5034 | return error; | ||
5035 | } | ||
5036 | |||
5037 | static void __devexit skge_remove_one(struct pci_dev *pdev) | ||
5038 | { | ||
5039 | struct net_device *dev = pci_get_drvdata(pdev); | ||
5040 | DEV_NET *pNet = netdev_priv(dev); | ||
5041 | SK_AC *pAC = pNet->pAC; | ||
5042 | struct net_device *otherdev = pAC->dev[1]; | ||
5043 | |||
5044 | unregister_netdev(dev); | ||
5045 | |||
5046 | SkGeYellowLED(pAC, pAC->IoBase, 0); | ||
5047 | |||
5048 | if (pAC->BoardLevel == SK_INIT_RUN) { | ||
5049 | SK_EVPARA EvPara; | ||
5050 | unsigned long Flags; | ||
5051 | |||
5052 | /* board is still alive */ | ||
5053 | spin_lock_irqsave(&pAC->SlowPathLock, Flags); | ||
5054 | EvPara.Para32[0] = 0; | ||
5055 | EvPara.Para32[1] = -1; | ||
5056 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); | ||
5057 | EvPara.Para32[0] = 1; | ||
5058 | EvPara.Para32[1] = -1; | ||
5059 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); | ||
5060 | SkEventDispatcher(pAC, pAC->IoBase); | ||
5061 | /* disable interrupts */ | ||
5062 | SK_OUT32(pAC->IoBase, B0_IMSK, 0); | ||
5063 | SkGeDeInit(pAC, pAC->IoBase); | ||
5064 | spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); | ||
5065 | pAC->BoardLevel = SK_INIT_DATA; | ||
5066 | /* We do NOT check here, if IRQ was pending, of course*/ | ||
5067 | } | ||
5068 | |||
5069 | if (pAC->BoardLevel == SK_INIT_IO) { | ||
5070 | /* board is still alive */ | ||
5071 | SkGeDeInit(pAC, pAC->IoBase); | ||
5072 | pAC->BoardLevel = SK_INIT_DATA; | ||
5073 | } | ||
5074 | |||
5075 | FreeResources(dev); | ||
5076 | free_netdev(dev); | ||
5077 | if (otherdev != dev) | ||
5078 | free_netdev(otherdev); | ||
5079 | kfree(pAC); | ||
5080 | } | ||
5081 | |||
5082 | #ifdef CONFIG_PM | ||
5083 | static int skge_suspend(struct pci_dev *pdev, pm_message_t state) | ||
5084 | { | ||
5085 | struct net_device *dev = pci_get_drvdata(pdev); | ||
5086 | DEV_NET *pNet = netdev_priv(dev); | ||
5087 | SK_AC *pAC = pNet->pAC; | ||
5088 | struct net_device *otherdev = pAC->dev[1]; | ||
5089 | |||
5090 | if (netif_running(dev)) { | ||
5091 | netif_carrier_off(dev); | ||
5092 | DoPrintInterfaceChange = SK_FALSE; | ||
5093 | SkDrvDeInitAdapter(pAC, 0); /* performs SkGeClose */ | ||
5094 | netif_device_detach(dev); | ||
5095 | } | ||
5096 | if (otherdev != dev) { | ||
5097 | if (netif_running(otherdev)) { | ||
5098 | netif_carrier_off(otherdev); | ||
5099 | DoPrintInterfaceChange = SK_FALSE; | ||
5100 | SkDrvDeInitAdapter(pAC, 1); /* performs SkGeClose */ | ||
5101 | netif_device_detach(otherdev); | ||
5102 | } | ||
5103 | } | ||
5104 | |||
5105 | pci_save_state(pdev); | ||
5106 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); | ||
5107 | if (pAC->AllocFlag & SK_ALLOC_IRQ) { | ||
5108 | free_irq(dev->irq, dev); | ||
5109 | } | ||
5110 | pci_disable_device(pdev); | ||
5111 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
5112 | |||
5113 | return 0; | ||
5114 | } | ||
5115 | |||
5116 | static int skge_resume(struct pci_dev *pdev) | ||
5117 | { | ||
5118 | struct net_device *dev = pci_get_drvdata(pdev); | ||
5119 | DEV_NET *pNet = netdev_priv(dev); | ||
5120 | SK_AC *pAC = pNet->pAC; | ||
5121 | struct net_device *otherdev = pAC->dev[1]; | ||
5122 | int ret; | ||
5123 | |||
5124 | pci_set_power_state(pdev, PCI_D0); | ||
5125 | pci_restore_state(pdev); | ||
5126 | ret = pci_enable_device(pdev); | ||
5127 | if (ret) { | ||
5128 | printk(KERN_WARNING "sk98lin: unable to enable device %s " | ||
5129 | "in resume\n", dev->name); | ||
5130 | goto err_out; | ||
5131 | } | ||
5132 | pci_set_master(pdev); | ||
5133 | if (pAC->GIni.GIMacsFound == 2) | ||
5134 | ret = request_irq(dev->irq, SkGeIsr, IRQF_SHARED, "sk98lin", dev); | ||
5135 | else | ||
5136 | ret = request_irq(dev->irq, SkGeIsrOnePort, IRQF_SHARED, "sk98lin", dev); | ||
5137 | if (ret) { | ||
5138 | printk(KERN_WARNING "sk98lin: unable to acquire IRQ %d\n", dev->irq); | ||
5139 | ret = -EBUSY; | ||
5140 | goto err_out_disable_pdev; | ||
5141 | } | ||
5142 | |||
5143 | netif_device_attach(dev); | ||
5144 | if (netif_running(dev)) { | ||
5145 | DoPrintInterfaceChange = SK_FALSE; | ||
5146 | SkDrvInitAdapter(pAC, 0); /* first device */ | ||
5147 | } | ||
5148 | if (otherdev != dev) { | ||
5149 | netif_device_attach(otherdev); | ||
5150 | if (netif_running(otherdev)) { | ||
5151 | DoPrintInterfaceChange = SK_FALSE; | ||
5152 | SkDrvInitAdapter(pAC, 1); /* second device */ | ||
5153 | } | ||
5154 | } | ||
5155 | |||
5156 | return 0; | ||
5157 | |||
5158 | err_out_disable_pdev: | ||
5159 | pci_disable_device(pdev); | ||
5160 | err_out: | ||
5161 | pAC->AllocFlag &= ~SK_ALLOC_IRQ; | ||
5162 | dev->irq = 0; | ||
5163 | return ret; | ||
5164 | } | ||
5165 | #else | ||
5166 | #define skge_suspend NULL | ||
5167 | #define skge_resume NULL | ||
5168 | #endif | ||
5169 | |||
5170 | static struct pci_device_id skge_pci_tbl[] = { | ||
5171 | #ifdef SK98LIN_ALL_DEVICES | ||
5172 | { PCI_VENDOR_ID_3COM, 0x1700, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | ||
5173 | { PCI_VENDOR_ID_3COM, 0x80eb, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | ||
5174 | #endif | ||
5175 | #ifdef GENESIS | ||
5176 | /* Generic SysKonnect SK-98xx Gigabit Ethernet Server Adapter */ | ||
5177 | { PCI_VENDOR_ID_SYSKONNECT, 0x4300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | ||
5178 | #endif | ||
5179 | /* Generic SysKonnect SK-98xx V2.0 Gigabit Ethernet Adapter */ | ||
5180 | { PCI_VENDOR_ID_SYSKONNECT, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | ||
5181 | #ifdef SK98LIN_ALL_DEVICES | ||
5182 | /* DLink card does not have valid VPD so this driver gags | ||
5183 | * { PCI_VENDOR_ID_DLINK, 0x4c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | ||
5184 | */ | ||
5185 | { PCI_VENDOR_ID_MARVELL, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | ||
5186 | { PCI_VENDOR_ID_MARVELL, 0x5005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | ||
5187 | { PCI_VENDOR_ID_CNET, 0x434e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | ||
5188 | { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0015, }, | ||
5189 | { PCI_VENDOR_ID_LINKSYS, 0x1064, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | ||
5190 | #endif | ||
5191 | { 0 } | ||
5192 | }; | ||
5193 | |||
5194 | MODULE_DEVICE_TABLE(pci, skge_pci_tbl); | ||
5195 | |||
5196 | static struct pci_driver skge_driver = { | ||
5197 | .name = "sk98lin", | ||
5198 | .id_table = skge_pci_tbl, | ||
5199 | .probe = skge_probe_one, | ||
5200 | .remove = __devexit_p(skge_remove_one), | ||
5201 | .suspend = skge_suspend, | ||
5202 | .resume = skge_resume, | ||
5203 | }; | ||
5204 | |||
5205 | static int __init skge_init(void) | ||
5206 | { | ||
5207 | printk(KERN_NOTICE "sk98lin: driver has been replaced by the skge driver" | ||
5208 | " and is scheduled for removal\n"); | ||
5209 | |||
5210 | return pci_register_driver(&skge_driver); | ||
5211 | } | ||
5212 | |||
5213 | static void __exit skge_exit(void) | ||
5214 | { | ||
5215 | pci_unregister_driver(&skge_driver); | ||
5216 | } | ||
5217 | |||
5218 | module_init(skge_init); | ||
5219 | 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..67f1d6a5c15d --- /dev/null +++ b/drivers/net/sk98lin/skgeinit.c | |||
@@ -0,0 +1,2005 @@ | |||
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 | * SkGePollTxD() - Enable / Disable Descriptor Polling of TxD Rings | ||
63 | * | ||
64 | * Description: | ||
65 | * Enable or disable the descriptor polling of the transmit descriptor | ||
66 | * ring(s) (TxD) 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 SkGePollTxD( | ||
74 | SK_AC *pAC, /* adapter context */ | ||
75 | SK_IOC IoC, /* IO context */ | ||
76 | int Port, /* Port Index (MAC_1 + n) */ | ||
77 | SK_BOOL PollTxD) /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */ | ||
78 | { | ||
79 | SK_GEPORT *pPrt; | ||
80 | SK_U32 DWord; | ||
81 | |||
82 | pPrt = &pAC->GIni.GP[Port]; | ||
83 | |||
84 | DWord = (SK_U32)(PollTxD ? CSR_ENA_POL : CSR_DIS_POL); | ||
85 | |||
86 | if (pPrt->PXSQSize != 0) { | ||
87 | SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), DWord); | ||
88 | } | ||
89 | |||
90 | if (pPrt->PXAQSize != 0) { | ||
91 | SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), DWord); | ||
92 | } | ||
93 | } /* SkGePollTxD */ | ||
94 | |||
95 | |||
96 | /****************************************************************************** | ||
97 | * | ||
98 | * SkGeYellowLED() - Switch the yellow LED on or off. | ||
99 | * | ||
100 | * Description: | ||
101 | * Switch the yellow LED on or off. | ||
102 | * | ||
103 | * Note: | ||
104 | * This function may be called any time after SkGeInit(Level 1). | ||
105 | * | ||
106 | * Returns: | ||
107 | * nothing | ||
108 | */ | ||
109 | void SkGeYellowLED( | ||
110 | SK_AC *pAC, /* adapter context */ | ||
111 | SK_IOC IoC, /* IO context */ | ||
112 | int State) /* yellow LED state, 0 = OFF, 0 != ON */ | ||
113 | { | ||
114 | if (State == 0) { | ||
115 | /* Switch yellow LED OFF */ | ||
116 | SK_OUT8(IoC, B0_LED, LED_STAT_OFF); | ||
117 | } | ||
118 | else { | ||
119 | /* Switch yellow LED ON */ | ||
120 | SK_OUT8(IoC, B0_LED, LED_STAT_ON); | ||
121 | } | ||
122 | } /* SkGeYellowLED */ | ||
123 | |||
124 | |||
125 | #if (!defined(SK_SLIM) || defined(GENESIS)) | ||
126 | /****************************************************************************** | ||
127 | * | ||
128 | * SkGeXmitLED() - Modify the Operational Mode of a transmission LED. | ||
129 | * | ||
130 | * Description: | ||
131 | * The Rx or Tx LED which is specified by 'Led' will be | ||
132 | * enabled, disabled or switched on in test mode. | ||
133 | * | ||
134 | * Note: | ||
135 | * 'Led' must contain the address offset of the LEDs INI register. | ||
136 | * | ||
137 | * Usage: | ||
138 | * SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA); | ||
139 | * | ||
140 | * Returns: | ||
141 | * nothing | ||
142 | */ | ||
143 | void SkGeXmitLED( | ||
144 | SK_AC *pAC, /* adapter context */ | ||
145 | SK_IOC IoC, /* IO context */ | ||
146 | int Led, /* offset to the LED Init Value register */ | ||
147 | int Mode) /* Mode may be SK_LED_DIS, SK_LED_ENA, SK_LED_TST */ | ||
148 | { | ||
149 | SK_U32 LedIni; | ||
150 | |||
151 | switch (Mode) { | ||
152 | case SK_LED_ENA: | ||
153 | LedIni = SK_XMIT_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100; | ||
154 | SK_OUT32(IoC, Led + XMIT_LED_INI, LedIni); | ||
155 | SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START); | ||
156 | break; | ||
157 | case SK_LED_TST: | ||
158 | SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_ON); | ||
159 | SK_OUT32(IoC, Led + XMIT_LED_CNT, 100); | ||
160 | SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START); | ||
161 | break; | ||
162 | case SK_LED_DIS: | ||
163 | default: | ||
164 | /* | ||
165 | * Do NOT stop the LED Timer here. The LED might be | ||
166 | * in on state. But it needs to go off. | ||
167 | */ | ||
168 | SK_OUT32(IoC, Led + XMIT_LED_CNT, 0); | ||
169 | SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_OFF); | ||
170 | break; | ||
171 | } | ||
172 | |||
173 | /* | ||
174 | * 1000BT: The Transmit LED is driven by the PHY. | ||
175 | * But the default LED configuration is used for | ||
176 | * Level One and Broadcom PHYs. | ||
177 | * (Broadcom: It may be that PHY_B_PEC_EN_LTR has to be set.) | ||
178 | * (In this case it has to be added here. But we will see. XXX) | ||
179 | */ | ||
180 | } /* SkGeXmitLED */ | ||
181 | #endif /* !SK_SLIM || GENESIS */ | ||
182 | |||
183 | |||
184 | /****************************************************************************** | ||
185 | * | ||
186 | * DoCalcAddr() - Calculates the start and the end address of a queue. | ||
187 | * | ||
188 | * Description: | ||
189 | * This function calculates the start and the end address of a queue. | ||
190 | * Afterwards the 'StartVal' is incremented to the next start position. | ||
191 | * If the port is already initialized the calculated values | ||
192 | * will be checked against the configured values and an | ||
193 | * error will be returned, if they are not equal. | ||
194 | * If the port is not initialized the values will be written to | ||
195 | * *StartAdr and *EndAddr. | ||
196 | * | ||
197 | * Returns: | ||
198 | * 0: success | ||
199 | * 1: configuration error | ||
200 | */ | ||
201 | static int DoCalcAddr( | ||
202 | SK_AC *pAC, /* adapter context */ | ||
203 | SK_GEPORT SK_FAR *pPrt, /* port index */ | ||
204 | int QuSize, /* size of the queue to configure in kB */ | ||
205 | SK_U32 SK_FAR *StartVal, /* start value for address calculation */ | ||
206 | SK_U32 SK_FAR *QuStartAddr,/* start addr to calculate */ | ||
207 | SK_U32 SK_FAR *QuEndAddr) /* end address to calculate */ | ||
208 | { | ||
209 | SK_U32 EndVal; | ||
210 | SK_U32 NextStart; | ||
211 | int Rtv; | ||
212 | |||
213 | Rtv = 0; | ||
214 | if (QuSize == 0) { | ||
215 | EndVal = *StartVal; | ||
216 | NextStart = EndVal; | ||
217 | } | ||
218 | else { | ||
219 | EndVal = *StartVal + ((SK_U32)QuSize * 1024) - 1; | ||
220 | NextStart = EndVal + 1; | ||
221 | } | ||
222 | |||
223 | if (pPrt->PState >= SK_PRT_INIT) { | ||
224 | if (*StartVal != *QuStartAddr || EndVal != *QuEndAddr) { | ||
225 | Rtv = 1; | ||
226 | } | ||
227 | } | ||
228 | else { | ||
229 | *QuStartAddr = *StartVal; | ||
230 | *QuEndAddr = EndVal; | ||
231 | } | ||
232 | |||
233 | *StartVal = NextStart; | ||
234 | return(Rtv); | ||
235 | } /* DoCalcAddr */ | ||
236 | |||
237 | /****************************************************************************** | ||
238 | * | ||
239 | * SkGeInitAssignRamToQueues() - allocate default queue sizes | ||
240 | * | ||
241 | * Description: | ||
242 | * This function assigns the memory to the different queues and ports. | ||
243 | * When DualNet is set to SK_TRUE all ports get the same amount of memory. | ||
244 | * Otherwise the first port gets most of the memory and all the | ||
245 | * other ports just the required minimum. | ||
246 | * This function can only be called when pAC->GIni.GIRamSize and | ||
247 | * pAC->GIni.GIMacsFound have been initialized, usually this happens | ||
248 | * at init level 1 | ||
249 | * | ||
250 | * Returns: | ||
251 | * 0 - ok | ||
252 | * 1 - invalid input values | ||
253 | * 2 - not enough memory | ||
254 | */ | ||
255 | |||
256 | int SkGeInitAssignRamToQueues( | ||
257 | SK_AC *pAC, /* Adapter context */ | ||
258 | int ActivePort, /* Active Port in RLMT mode */ | ||
259 | SK_BOOL DualNet) /* adapter context */ | ||
260 | { | ||
261 | int i; | ||
262 | int UsedKilobytes; /* memory already assigned */ | ||
263 | int ActivePortKilobytes; /* memory available for active port */ | ||
264 | SK_GEPORT *pGePort; | ||
265 | |||
266 | UsedKilobytes = 0; | ||
267 | |||
268 | if (ActivePort >= pAC->GIni.GIMacsFound) { | ||
269 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, | ||
270 | ("SkGeInitAssignRamToQueues: ActivePort (%d) invalid\n", | ||
271 | ActivePort)); | ||
272 | return(1); | ||
273 | } | ||
274 | if (((pAC->GIni.GIMacsFound * (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE)) + | ||
275 | ((RAM_QUOTA_SYNC == 0) ? 0 : SK_MIN_TXQ_SIZE)) > pAC->GIni.GIRamSize) { | ||
276 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, | ||
277 | ("SkGeInitAssignRamToQueues: Not enough memory (%d)\n", | ||
278 | pAC->GIni.GIRamSize)); | ||
279 | return(2); | ||
280 | } | ||
281 | |||
282 | if (DualNet) { | ||
283 | /* every port gets the same amount of memory */ | ||
284 | ActivePortKilobytes = pAC->GIni.GIRamSize / pAC->GIni.GIMacsFound; | ||
285 | for (i = 0; i < pAC->GIni.GIMacsFound; i++) { | ||
286 | |||
287 | pGePort = &pAC->GIni.GP[i]; | ||
288 | |||
289 | /* take away the minimum memory for active queues */ | ||
290 | ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE); | ||
291 | |||
292 | /* receive queue gets the minimum + 80% of the rest */ | ||
293 | pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB(( | ||
294 | ActivePortKilobytes * (unsigned long) RAM_QUOTA_RX) / 100)) | ||
295 | + SK_MIN_RXQ_SIZE; | ||
296 | |||
297 | ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE); | ||
298 | |||
299 | /* synchronous transmit queue */ | ||
300 | pGePort->PXSQSize = 0; | ||
301 | |||
302 | /* asynchronous transmit queue */ | ||
303 | pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes + | ||
304 | SK_MIN_TXQ_SIZE); | ||
305 | } | ||
306 | } | ||
307 | else { | ||
308 | /* Rlmt Mode or single link adapter */ | ||
309 | |||
310 | /* Set standby queue size defaults for all standby ports */ | ||
311 | for (i = 0; i < pAC->GIni.GIMacsFound; i++) { | ||
312 | |||
313 | if (i != ActivePort) { | ||
314 | pGePort = &pAC->GIni.GP[i]; | ||
315 | |||
316 | pGePort->PRxQSize = SK_MIN_RXQ_SIZE; | ||
317 | pGePort->PXAQSize = SK_MIN_TXQ_SIZE; | ||
318 | pGePort->PXSQSize = 0; | ||
319 | |||
320 | /* Count used RAM */ | ||
321 | UsedKilobytes += pGePort->PRxQSize + pGePort->PXAQSize; | ||
322 | } | ||
323 | } | ||
324 | /* what's left? */ | ||
325 | ActivePortKilobytes = pAC->GIni.GIRamSize - UsedKilobytes; | ||
326 | |||
327 | /* assign it to the active port */ | ||
328 | /* first take away the minimum memory */ | ||
329 | ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE); | ||
330 | pGePort = &pAC->GIni.GP[ActivePort]; | ||
331 | |||
332 | /* receive queue get's the minimum + 80% of the rest */ | ||
333 | pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((ActivePortKilobytes * | ||
334 | (unsigned long) RAM_QUOTA_RX) / 100)) + SK_MIN_RXQ_SIZE; | ||
335 | |||
336 | ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE); | ||
337 | |||
338 | /* synchronous transmit queue */ | ||
339 | pGePort->PXSQSize = 0; | ||
340 | |||
341 | /* asynchronous transmit queue */ | ||
342 | pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes) + | ||
343 | SK_MIN_TXQ_SIZE; | ||
344 | } | ||
345 | #ifdef VCPU | ||
346 | VCPUprintf(0, "PRxQSize=%u, PXSQSize=%u, PXAQSize=%u\n", | ||
347 | pGePort->PRxQSize, pGePort->PXSQSize, pGePort->PXAQSize); | ||
348 | #endif /* VCPU */ | ||
349 | |||
350 | return(0); | ||
351 | } /* SkGeInitAssignRamToQueues */ | ||
352 | |||
353 | /****************************************************************************** | ||
354 | * | ||
355 | * SkGeCheckQSize() - Checks the Adapters Queue Size Configuration | ||
356 | * | ||
357 | * Description: | ||
358 | * This function verifies the Queue Size Configuration specified | ||
359 | * in the variables PRxQSize, PXSQSize, and PXAQSize of all | ||
360 | * used ports. | ||
361 | * This requirements must be fullfilled to have a valid configuration: | ||
362 | * - The size of all queues must not exceed GIRamSize. | ||
363 | * - The queue sizes must be specified in units of 8 kB. | ||
364 | * - The size of Rx queues of available ports must not be | ||
365 | * smaller than 16 kB. | ||
366 | * - The size of at least one Tx queue (synch. or asynch.) | ||
367 | * of available ports must not be smaller than 16 kB | ||
368 | * when Jumbo Frames are used. | ||
369 | * - The RAM start and end addresses must not be changed | ||
370 | * for ports which are already initialized. | ||
371 | * Furthermore SkGeCheckQSize() defines the Start and End Addresses | ||
372 | * of all ports and stores them into the HWAC port structure. | ||
373 | * | ||
374 | * Returns: | ||
375 | * 0: Queue Size Configuration valid | ||
376 | * 1: Queue Size Configuration invalid | ||
377 | */ | ||
378 | static int SkGeCheckQSize( | ||
379 | SK_AC *pAC, /* adapter context */ | ||
380 | int Port) /* port index */ | ||
381 | { | ||
382 | SK_GEPORT *pPrt; | ||
383 | int i; | ||
384 | int Rtv; | ||
385 | int Rtv2; | ||
386 | SK_U32 StartAddr; | ||
387 | #ifndef SK_SLIM | ||
388 | int UsedMem; /* total memory used (max. found ports) */ | ||
389 | #endif | ||
390 | |||
391 | Rtv = 0; | ||
392 | |||
393 | #ifndef SK_SLIM | ||
394 | |||
395 | UsedMem = 0; | ||
396 | for (i = 0; i < pAC->GIni.GIMacsFound; i++) { | ||
397 | pPrt = &pAC->GIni.GP[i]; | ||
398 | |||
399 | if ((pPrt->PRxQSize & QZ_UNITS) != 0 || | ||
400 | (pPrt->PXSQSize & QZ_UNITS) != 0 || | ||
401 | (pPrt->PXAQSize & QZ_UNITS) != 0) { | ||
402 | |||
403 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG); | ||
404 | return(1); | ||
405 | } | ||
406 | |||
407 | if (i == Port && pPrt->PRxQSize < SK_MIN_RXQ_SIZE) { | ||
408 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E011, SKERR_HWI_E011MSG); | ||
409 | return(1); | ||
410 | } | ||
411 | |||
412 | /* | ||
413 | * the size of at least one Tx queue (synch. or asynch.) has to be > 0. | ||
414 | * if Jumbo Frames are used, this size has to be >= 16 kB. | ||
415 | */ | ||
416 | if ((i == Port && pPrt->PXSQSize == 0 && pPrt->PXAQSize == 0) || | ||
417 | (pAC->GIni.GIPortUsage == SK_JUMBO_LINK && | ||
418 | ((pPrt->PXSQSize > 0 && pPrt->PXSQSize < SK_MIN_TXQ_SIZE) || | ||
419 | (pPrt->PXAQSize > 0 && pPrt->PXAQSize < SK_MIN_TXQ_SIZE)))) { | ||
420 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E023, SKERR_HWI_E023MSG); | ||
421 | return(1); | ||
422 | } | ||
423 | |||
424 | UsedMem += pPrt->PRxQSize + pPrt->PXSQSize + pPrt->PXAQSize; | ||
425 | } | ||
426 | |||
427 | if (UsedMem > pAC->GIni.GIRamSize) { | ||
428 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG); | ||
429 | return(1); | ||
430 | } | ||
431 | #endif /* !SK_SLIM */ | ||
432 | |||
433 | /* Now start address calculation */ | ||
434 | StartAddr = pAC->GIni.GIRamOffs; | ||
435 | for (i = 0; i < pAC->GIni.GIMacsFound; i++) { | ||
436 | pPrt = &pAC->GIni.GP[i]; | ||
437 | |||
438 | /* Calculate/Check values for the receive queue */ | ||
439 | Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PRxQSize, &StartAddr, | ||
440 | &pPrt->PRxQRamStart, &pPrt->PRxQRamEnd); | ||
441 | Rtv |= Rtv2; | ||
442 | |||
443 | /* Calculate/Check values for the synchronous Tx queue */ | ||
444 | Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXSQSize, &StartAddr, | ||
445 | &pPrt->PXsQRamStart, &pPrt->PXsQRamEnd); | ||
446 | Rtv |= Rtv2; | ||
447 | |||
448 | /* Calculate/Check values for the asynchronous Tx queue */ | ||
449 | Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXAQSize, &StartAddr, | ||
450 | &pPrt->PXaQRamStart, &pPrt->PXaQRamEnd); | ||
451 | Rtv |= Rtv2; | ||
452 | |||
453 | if (Rtv) { | ||
454 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E013, SKERR_HWI_E013MSG); | ||
455 | return(1); | ||
456 | } | ||
457 | } | ||
458 | |||
459 | return(0); | ||
460 | } /* SkGeCheckQSize */ | ||
461 | |||
462 | |||
463 | #ifdef GENESIS | ||
464 | /****************************************************************************** | ||
465 | * | ||
466 | * SkGeInitMacArb() - Initialize the MAC Arbiter | ||
467 | * | ||
468 | * Description: | ||
469 | * This function initializes the MAC Arbiter. | ||
470 | * It must not be called if there is still an | ||
471 | * initialized or active port. | ||
472 | * | ||
473 | * Returns: | ||
474 | * nothing | ||
475 | */ | ||
476 | static void SkGeInitMacArb( | ||
477 | SK_AC *pAC, /* adapter context */ | ||
478 | SK_IOC IoC) /* IO context */ | ||
479 | { | ||
480 | /* release local reset */ | ||
481 | SK_OUT16(IoC, B3_MA_TO_CTRL, MA_RST_CLR); | ||
482 | |||
483 | /* configure timeout values */ | ||
484 | SK_OUT8(IoC, B3_MA_TOINI_RX1, SK_MAC_TO_53); | ||
485 | SK_OUT8(IoC, B3_MA_TOINI_RX2, SK_MAC_TO_53); | ||
486 | SK_OUT8(IoC, B3_MA_TOINI_TX1, SK_MAC_TO_53); | ||
487 | SK_OUT8(IoC, B3_MA_TOINI_TX2, SK_MAC_TO_53); | ||
488 | |||
489 | SK_OUT8(IoC, B3_MA_RCINI_RX1, 0); | ||
490 | SK_OUT8(IoC, B3_MA_RCINI_RX2, 0); | ||
491 | SK_OUT8(IoC, B3_MA_RCINI_TX1, 0); | ||
492 | SK_OUT8(IoC, B3_MA_RCINI_TX2, 0); | ||
493 | |||
494 | /* recovery values are needed for XMAC II Rev. B2 only */ | ||
495 | /* Fast Output Enable Mode was intended to use with Rev. B2, but now? */ | ||
496 | |||
497 | /* | ||
498 | * There is no start or enable button to push, therefore | ||
499 | * the MAC arbiter is configured and enabled now. | ||
500 | */ | ||
501 | } /* SkGeInitMacArb */ | ||
502 | |||
503 | |||
504 | /****************************************************************************** | ||
505 | * | ||
506 | * SkGeInitPktArb() - Initialize the Packet Arbiter | ||
507 | * | ||
508 | * Description: | ||
509 | * This function initializes the Packet Arbiter. | ||
510 | * It must not be called if there is still an | ||
511 | * initialized or active port. | ||
512 | * | ||
513 | * Returns: | ||
514 | * nothing | ||
515 | */ | ||
516 | static void SkGeInitPktArb( | ||
517 | SK_AC *pAC, /* adapter context */ | ||
518 | SK_IOC IoC) /* IO context */ | ||
519 | { | ||
520 | /* release local reset */ | ||
521 | SK_OUT16(IoC, B3_PA_CTRL, PA_RST_CLR); | ||
522 | |||
523 | /* configure timeout values */ | ||
524 | SK_OUT16(IoC, B3_PA_TOINI_RX1, SK_PKT_TO_MAX); | ||
525 | SK_OUT16(IoC, B3_PA_TOINI_RX2, SK_PKT_TO_MAX); | ||
526 | SK_OUT16(IoC, B3_PA_TOINI_TX1, SK_PKT_TO_MAX); | ||
527 | SK_OUT16(IoC, B3_PA_TOINI_TX2, SK_PKT_TO_MAX); | ||
528 | |||
529 | /* | ||
530 | * enable timeout timers if jumbo frames not used | ||
531 | * NOTE: the packet arbiter timeout interrupt is needed for | ||
532 | * half duplex hangup workaround | ||
533 | */ | ||
534 | if (pAC->GIni.GIPortUsage != SK_JUMBO_LINK) { | ||
535 | if (pAC->GIni.GIMacsFound == 1) { | ||
536 | SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1); | ||
537 | } | ||
538 | else { | ||
539 | SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1 | PA_ENA_TO_TX2); | ||
540 | } | ||
541 | } | ||
542 | } /* SkGeInitPktArb */ | ||
543 | #endif /* GENESIS */ | ||
544 | |||
545 | |||
546 | /****************************************************************************** | ||
547 | * | ||
548 | * SkGeInitMacFifo() - Initialize the MAC FIFOs | ||
549 | * | ||
550 | * Description: | ||
551 | * Initialize all MAC FIFOs of the specified port | ||
552 | * | ||
553 | * Returns: | ||
554 | * nothing | ||
555 | */ | ||
556 | static void SkGeInitMacFifo( | ||
557 | SK_AC *pAC, /* adapter context */ | ||
558 | SK_IOC IoC, /* IO context */ | ||
559 | int Port) /* Port Index (MAC_1 + n) */ | ||
560 | { | ||
561 | SK_U16 Word; | ||
562 | #ifdef VCPU | ||
563 | SK_U32 DWord; | ||
564 | #endif /* VCPU */ | ||
565 | /* | ||
566 | * For each FIFO: | ||
567 | * - release local reset | ||
568 | * - use default value for MAC FIFO size | ||
569 | * - setup defaults for the control register | ||
570 | * - enable the FIFO | ||
571 | */ | ||
572 | |||
573 | #ifdef GENESIS | ||
574 | if (pAC->GIni.GIGenesis) { | ||
575 | /* Configure Rx MAC FIFO */ | ||
576 | SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_CLR); | ||
577 | SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_RX_CTRL_DEF); | ||
578 | SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_ENA_OP_MD); | ||
579 | |||
580 | /* Configure Tx MAC FIFO */ | ||
581 | SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_CLR); | ||
582 | SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF); | ||
583 | SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_ENA_OP_MD); | ||
584 | |||
585 | /* Enable frame flushing if jumbo frames used */ | ||
586 | if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { | ||
587 | SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_FLUSH); | ||
588 | } | ||
589 | } | ||
590 | #endif /* GENESIS */ | ||
591 | |||
592 | #ifdef YUKON | ||
593 | if (pAC->GIni.GIYukon) { | ||
594 | /* set Rx GMAC FIFO Flush Mask */ | ||
595 | SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), (SK_U16)RX_FF_FL_DEF_MSK); | ||
596 | |||
597 | Word = (SK_U16)GMF_RX_CTRL_DEF; | ||
598 | |||
599 | /* disable Rx GMAC FIFO Flush for YUKON-Lite Rev. A0 only */ | ||
600 | if (pAC->GIni.GIYukonLite && pAC->GIni.GIChipId == CHIP_ID_YUKON) { | ||
601 | |||
602 | Word &= ~GMF_RX_F_FL_ON; | ||
603 | } | ||
604 | |||
605 | /* Configure Rx MAC FIFO */ | ||
606 | SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR); | ||
607 | SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), Word); | ||
608 | |||
609 | /* set Rx GMAC FIFO Flush Threshold (default: 0x0a -> 56 bytes) */ | ||
610 | SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF); | ||
611 | |||
612 | /* Configure Tx MAC FIFO */ | ||
613 | SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR); | ||
614 | SK_OUT16(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U16)GMF_TX_CTRL_DEF); | ||
615 | |||
616 | #ifdef VCPU | ||
617 | SK_IN32(IoC, MR_ADDR(Port, RX_GMF_AF_THR), &DWord); | ||
618 | SK_IN32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), &DWord); | ||
619 | #endif /* VCPU */ | ||
620 | |||
621 | /* set Tx GMAC FIFO Almost Empty Threshold */ | ||
622 | /* SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), 0); */ | ||
623 | } | ||
624 | #endif /* YUKON */ | ||
625 | |||
626 | } /* SkGeInitMacFifo */ | ||
627 | |||
628 | #ifdef SK_LNK_SYNC_CNT | ||
629 | /****************************************************************************** | ||
630 | * | ||
631 | * SkGeLoadLnkSyncCnt() - Load the Link Sync Counter and starts counting | ||
632 | * | ||
633 | * Description: | ||
634 | * This function starts the Link Sync Counter of the specified | ||
635 | * port and enables the generation of an Link Sync IRQ. | ||
636 | * The Link Sync Counter may be used to detect an active link, | ||
637 | * if autonegotiation is not used. | ||
638 | * | ||
639 | * Note: | ||
640 | * o To ensure receiving the Link Sync Event the LinkSyncCounter | ||
641 | * should be initialized BEFORE clearing the XMAC's reset! | ||
642 | * o Enable IS_LNK_SYNC_M1 and IS_LNK_SYNC_M2 after calling this | ||
643 | * function. | ||
644 | * | ||
645 | * Returns: | ||
646 | * nothing | ||
647 | */ | ||
648 | void SkGeLoadLnkSyncCnt( | ||
649 | SK_AC *pAC, /* adapter context */ | ||
650 | SK_IOC IoC, /* IO context */ | ||
651 | int Port, /* Port Index (MAC_1 + n) */ | ||
652 | SK_U32 CntVal) /* Counter value */ | ||
653 | { | ||
654 | SK_U32 OrgIMsk; | ||
655 | SK_U32 NewIMsk; | ||
656 | SK_U32 ISrc; | ||
657 | SK_BOOL IrqPend; | ||
658 | |||
659 | /* stop counter */ | ||
660 | SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_STOP); | ||
661 | |||
662 | /* | ||
663 | * ASIC problem: | ||
664 | * Each time starting the Link Sync Counter an IRQ is generated | ||
665 | * by the adapter. See problem report entry from 21.07.98 | ||
666 | * | ||
667 | * Workaround: Disable Link Sync IRQ and clear the unexpeced IRQ | ||
668 | * if no IRQ is already pending. | ||
669 | */ | ||
670 | IrqPend = SK_FALSE; | ||
671 | SK_IN32(IoC, B0_ISRC, &ISrc); | ||
672 | SK_IN32(IoC, B0_IMSK, &OrgIMsk); | ||
673 | if (Port == MAC_1) { | ||
674 | NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M1; | ||
675 | if ((ISrc & IS_LNK_SYNC_M1) != 0) { | ||
676 | IrqPend = SK_TRUE; | ||
677 | } | ||
678 | } | ||
679 | else { | ||
680 | NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M2; | ||
681 | if ((ISrc & IS_LNK_SYNC_M2) != 0) { | ||
682 | IrqPend = SK_TRUE; | ||
683 | } | ||
684 | } | ||
685 | if (!IrqPend) { | ||
686 | SK_OUT32(IoC, B0_IMSK, NewIMsk); | ||
687 | } | ||
688 | |||
689 | /* load counter */ | ||
690 | SK_OUT32(IoC, MR_ADDR(Port, LNK_SYNC_INI), CntVal); | ||
691 | |||
692 | /* start counter */ | ||
693 | SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_START); | ||
694 | |||
695 | if (!IrqPend) { | ||
696 | /* clear the unexpected IRQ, and restore the interrupt mask */ | ||
697 | SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_CLR_IRQ); | ||
698 | SK_OUT32(IoC, B0_IMSK, OrgIMsk); | ||
699 | } | ||
700 | } /* SkGeLoadLnkSyncCnt*/ | ||
701 | #endif /* SK_LNK_SYNC_CNT */ | ||
702 | |||
703 | #if defined(SK_DIAG) || defined(SK_CFG_SYNC) | ||
704 | /****************************************************************************** | ||
705 | * | ||
706 | * SkGeCfgSync() - Configure synchronous bandwidth for this port. | ||
707 | * | ||
708 | * Description: | ||
709 | * This function may be used to configure synchronous bandwidth | ||
710 | * to the specified port. This may be done any time after | ||
711 | * initializing the port. The configuration values are NOT saved | ||
712 | * in the HWAC port structure and will be overwritten any | ||
713 | * time when stopping and starting the port. | ||
714 | * Any values for the synchronous configuration will be ignored | ||
715 | * if the size of the synchronous queue is zero! | ||
716 | * | ||
717 | * The default configuration for the synchronous service is | ||
718 | * TXA_ENA_FSYNC. This means if the size of | ||
719 | * the synchronous queue is unequal zero but no specific | ||
720 | * synchronous bandwidth is configured, the synchronous queue | ||
721 | * will always have the 'unlimited' transmit priority! | ||
722 | * | ||
723 | * This mode will be restored if the synchronous bandwidth is | ||
724 | * deallocated ('IntTime' = 0 and 'LimCount' = 0). | ||
725 | * | ||
726 | * Returns: | ||
727 | * 0: success | ||
728 | * 1: parameter configuration error | ||
729 | * 2: try to configure quality of service although no | ||
730 | * synchronous queue is configured | ||
731 | */ | ||
732 | int SkGeCfgSync( | ||
733 | SK_AC *pAC, /* adapter context */ | ||
734 | SK_IOC IoC, /* IO context */ | ||
735 | int Port, /* Port Index (MAC_1 + n) */ | ||
736 | SK_U32 IntTime, /* Interval Timer Value in units of 8ns */ | ||
737 | SK_U32 LimCount, /* Number of bytes to transfer during IntTime */ | ||
738 | int SyncMode) /* Sync Mode: TXA_ENA_ALLOC | TXA_DIS_ALLOC | 0 */ | ||
739 | { | ||
740 | int Rtv; | ||
741 | |||
742 | Rtv = 0; | ||
743 | |||
744 | /* check the parameters */ | ||
745 | if (LimCount > IntTime || | ||
746 | (LimCount == 0 && IntTime != 0) || | ||
747 | (LimCount != 0 && IntTime == 0)) { | ||
748 | |||
749 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG); | ||
750 | return(1); | ||
751 | } | ||
752 | |||
753 | if (pAC->GIni.GP[Port].PXSQSize == 0) { | ||
754 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E009, SKERR_HWI_E009MSG); | ||
755 | return(2); | ||
756 | } | ||
757 | |||
758 | /* calculate register values */ | ||
759 | IntTime = (IntTime / 2) * pAC->GIni.GIHstClkFact / 100; | ||
760 | LimCount = LimCount / 8; | ||
761 | |||
762 | if (IntTime > TXA_MAX_VAL || LimCount > TXA_MAX_VAL) { | ||
763 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG); | ||
764 | return(1); | ||
765 | } | ||
766 | |||
767 | /* | ||
768 | * - Enable 'Force Sync' to ensure the synchronous queue | ||
769 | * has the priority while configuring the new values. | ||
770 | * - Also 'disable alloc' to ensure the settings complies | ||
771 | * to the SyncMode parameter. | ||
772 | * - Disable 'Rate Control' to configure the new values. | ||
773 | * - write IntTime and LimCount | ||
774 | * - start 'Rate Control' and disable 'Force Sync' | ||
775 | * if Interval Timer or Limit Counter not zero. | ||
776 | */ | ||
777 | SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), | ||
778 | TXA_ENA_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC); | ||
779 | |||
780 | SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), IntTime); | ||
781 | SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), LimCount); | ||
782 | |||
783 | SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), | ||
784 | (SK_U8)(SyncMode & (TXA_ENA_ALLOC | TXA_DIS_ALLOC))); | ||
785 | |||
786 | if (IntTime != 0 || LimCount != 0) { | ||
787 | SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_DIS_FSYNC | TXA_START_RC); | ||
788 | } | ||
789 | |||
790 | return(0); | ||
791 | } /* SkGeCfgSync */ | ||
792 | #endif /* SK_DIAG || SK_CFG_SYNC*/ | ||
793 | |||
794 | |||
795 | /****************************************************************************** | ||
796 | * | ||
797 | * DoInitRamQueue() - Initialize the RAM Buffer Address of a single Queue | ||
798 | * | ||
799 | * Desccription: | ||
800 | * If the queue is used, enable and initialize it. | ||
801 | * Make sure the queue is still reset, if it is not used. | ||
802 | * | ||
803 | * Returns: | ||
804 | * nothing | ||
805 | */ | ||
806 | static void DoInitRamQueue( | ||
807 | SK_AC *pAC, /* adapter context */ | ||
808 | SK_IOC IoC, /* IO context */ | ||
809 | int QuIoOffs, /* Queue IO Address Offset */ | ||
810 | SK_U32 QuStartAddr, /* Queue Start Address */ | ||
811 | SK_U32 QuEndAddr, /* Queue End Address */ | ||
812 | int QuType) /* Queue Type (SK_RX_SRAM_Q|SK_RX_BRAM_Q|SK_TX_RAM_Q) */ | ||
813 | { | ||
814 | SK_U32 RxUpThresVal; | ||
815 | SK_U32 RxLoThresVal; | ||
816 | |||
817 | if (QuStartAddr != QuEndAddr) { | ||
818 | /* calculate thresholds, assume we have a big Rx queue */ | ||
819 | RxUpThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_ULPP) / 8; | ||
820 | RxLoThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_LLPP_B)/8; | ||
821 | |||
822 | /* build HW address format */ | ||
823 | QuStartAddr = QuStartAddr / 8; | ||
824 | QuEndAddr = QuEndAddr / 8; | ||
825 | |||
826 | /* release local reset */ | ||
827 | SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_CLR); | ||
828 | |||
829 | /* configure addresses */ | ||
830 | SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_START), QuStartAddr); | ||
831 | SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_END), QuEndAddr); | ||
832 | SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_WP), QuStartAddr); | ||
833 | SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RP), QuStartAddr); | ||
834 | |||
835 | switch (QuType) { | ||
836 | case SK_RX_SRAM_Q: | ||
837 | /* configure threshold for small Rx Queue */ | ||
838 | RxLoThresVal += (SK_RB_LLPP_B - SK_RB_LLPP_S) / 8; | ||
839 | |||
840 | /* continue with SK_RX_BRAM_Q */ | ||
841 | case SK_RX_BRAM_Q: | ||
842 | /* write threshold for Rx Queue */ | ||
843 | |||
844 | SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_UTPP), RxUpThresVal); | ||
845 | SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_LTPP), RxLoThresVal); | ||
846 | |||
847 | /* the high priority threshold not used */ | ||
848 | break; | ||
849 | case SK_TX_RAM_Q: | ||
850 | /* | ||
851 | * Do NOT use Store & Forward under normal operation due to | ||
852 | * performance optimization (GENESIS only). | ||
853 | * But if Jumbo Frames are configured (XMAC Tx FIFO is only 4 kB) | ||
854 | * or YUKON is used ((GMAC Tx FIFO is only 1 kB) | ||
855 | * we NEED Store & Forward of the RAM buffer. | ||
856 | */ | ||
857 | if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK || | ||
858 | pAC->GIni.GIYukon) { | ||
859 | /* enable Store & Forward Mode for the Tx Side */ | ||
860 | SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_STFWD); | ||
861 | } | ||
862 | break; | ||
863 | } | ||
864 | |||
865 | /* set queue operational */ | ||
866 | SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_OP_MD); | ||
867 | } | ||
868 | else { | ||
869 | /* ensure the queue is still disabled */ | ||
870 | SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_SET); | ||
871 | } | ||
872 | } /* DoInitRamQueue */ | ||
873 | |||
874 | |||
875 | /****************************************************************************** | ||
876 | * | ||
877 | * SkGeInitRamBufs() - Initialize the RAM Buffer Queues | ||
878 | * | ||
879 | * Description: | ||
880 | * Initialize all RAM Buffer Queues of the specified port | ||
881 | * | ||
882 | * Returns: | ||
883 | * nothing | ||
884 | */ | ||
885 | static void SkGeInitRamBufs( | ||
886 | SK_AC *pAC, /* adapter context */ | ||
887 | SK_IOC IoC, /* IO context */ | ||
888 | int Port) /* Port Index (MAC_1 + n) */ | ||
889 | { | ||
890 | SK_GEPORT *pPrt; | ||
891 | int RxQType; | ||
892 | |||
893 | pPrt = &pAC->GIni.GP[Port]; | ||
894 | |||
895 | if (pPrt->PRxQSize == SK_MIN_RXQ_SIZE) { | ||
896 | RxQType = SK_RX_SRAM_Q; /* small Rx Queue */ | ||
897 | } | ||
898 | else { | ||
899 | RxQType = SK_RX_BRAM_Q; /* big Rx Queue */ | ||
900 | } | ||
901 | |||
902 | DoInitRamQueue(pAC, IoC, pPrt->PRxQOff, pPrt->PRxQRamStart, | ||
903 | pPrt->PRxQRamEnd, RxQType); | ||
904 | |||
905 | DoInitRamQueue(pAC, IoC, pPrt->PXsQOff, pPrt->PXsQRamStart, | ||
906 | pPrt->PXsQRamEnd, SK_TX_RAM_Q); | ||
907 | |||
908 | DoInitRamQueue(pAC, IoC, pPrt->PXaQOff, pPrt->PXaQRamStart, | ||
909 | pPrt->PXaQRamEnd, SK_TX_RAM_Q); | ||
910 | |||
911 | } /* SkGeInitRamBufs */ | ||
912 | |||
913 | |||
914 | /****************************************************************************** | ||
915 | * | ||
916 | * SkGeInitRamIface() - Initialize the RAM Interface | ||
917 | * | ||
918 | * Description: | ||
919 | * This function initializes the Adapters RAM Interface. | ||
920 | * | ||
921 | * Note: | ||
922 | * This function is used in the diagnostics. | ||
923 | * | ||
924 | * Returns: | ||
925 | * nothing | ||
926 | */ | ||
927 | static void SkGeInitRamIface( | ||
928 | SK_AC *pAC, /* adapter context */ | ||
929 | SK_IOC IoC) /* IO context */ | ||
930 | { | ||
931 | /* release local reset */ | ||
932 | SK_OUT16(IoC, B3_RI_CTRL, RI_RST_CLR); | ||
933 | |||
934 | /* configure timeout values */ | ||
935 | SK_OUT8(IoC, B3_RI_WTO_R1, SK_RI_TO_53); | ||
936 | SK_OUT8(IoC, B3_RI_WTO_XA1, SK_RI_TO_53); | ||
937 | SK_OUT8(IoC, B3_RI_WTO_XS1, SK_RI_TO_53); | ||
938 | SK_OUT8(IoC, B3_RI_RTO_R1, SK_RI_TO_53); | ||
939 | SK_OUT8(IoC, B3_RI_RTO_XA1, SK_RI_TO_53); | ||
940 | SK_OUT8(IoC, B3_RI_RTO_XS1, SK_RI_TO_53); | ||
941 | SK_OUT8(IoC, B3_RI_WTO_R2, SK_RI_TO_53); | ||
942 | SK_OUT8(IoC, B3_RI_WTO_XA2, SK_RI_TO_53); | ||
943 | SK_OUT8(IoC, B3_RI_WTO_XS2, SK_RI_TO_53); | ||
944 | SK_OUT8(IoC, B3_RI_RTO_R2, SK_RI_TO_53); | ||
945 | SK_OUT8(IoC, B3_RI_RTO_XA2, SK_RI_TO_53); | ||
946 | SK_OUT8(IoC, B3_RI_RTO_XS2, SK_RI_TO_53); | ||
947 | |||
948 | } /* SkGeInitRamIface */ | ||
949 | |||
950 | |||
951 | /****************************************************************************** | ||
952 | * | ||
953 | * SkGeInitBmu() - Initialize the BMU state machines | ||
954 | * | ||
955 | * Description: | ||
956 | * Initialize all BMU state machines of the specified port | ||
957 | * | ||
958 | * Returns: | ||
959 | * nothing | ||
960 | */ | ||
961 | static void SkGeInitBmu( | ||
962 | SK_AC *pAC, /* adapter context */ | ||
963 | SK_IOC IoC, /* IO context */ | ||
964 | int Port) /* Port Index (MAC_1 + n) */ | ||
965 | { | ||
966 | SK_GEPORT *pPrt; | ||
967 | SK_U32 RxWm; | ||
968 | SK_U32 TxWm; | ||
969 | |||
970 | pPrt = &pAC->GIni.GP[Port]; | ||
971 | |||
972 | RxWm = SK_BMU_RX_WM; | ||
973 | TxWm = SK_BMU_TX_WM; | ||
974 | |||
975 | if (!pAC->GIni.GIPciSlot64 && !pAC->GIni.GIPciClock66) { | ||
976 | /* for better performance */ | ||
977 | RxWm /= 2; | ||
978 | TxWm /= 2; | ||
979 | } | ||
980 | |||
981 | /* Rx Queue: Release all local resets and set the watermark */ | ||
982 | SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_CLR_RESET); | ||
983 | SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), RxWm); | ||
984 | |||
985 | /* | ||
986 | * Tx Queue: Release all local resets if the queue is used ! | ||
987 | * set watermark | ||
988 | */ | ||
989 | if (pPrt->PXSQSize != 0) { | ||
990 | SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_CLR_RESET); | ||
991 | SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_F), TxWm); | ||
992 | } | ||
993 | |||
994 | if (pPrt->PXAQSize != 0) { | ||
995 | SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_CLR_RESET); | ||
996 | SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_F), TxWm); | ||
997 | } | ||
998 | /* | ||
999 | * Do NOT enable the descriptor poll timers here, because | ||
1000 | * the descriptor addresses are not specified yet. | ||
1001 | */ | ||
1002 | } /* SkGeInitBmu */ | ||
1003 | |||
1004 | |||
1005 | /****************************************************************************** | ||
1006 | * | ||
1007 | * TestStopBit() - Test the stop bit of the queue | ||
1008 | * | ||
1009 | * Description: | ||
1010 | * Stopping a queue is not as simple as it seems to be. | ||
1011 | * If descriptor polling is enabled, it may happen | ||
1012 | * that RX/TX stop is done and SV idle is NOT set. | ||
1013 | * In this case we have to issue another stop command. | ||
1014 | * | ||
1015 | * Returns: | ||
1016 | * The queues control status register | ||
1017 | */ | ||
1018 | static SK_U32 TestStopBit( | ||
1019 | SK_AC *pAC, /* Adapter Context */ | ||
1020 | SK_IOC IoC, /* IO Context */ | ||
1021 | int QuIoOffs) /* Queue IO Address Offset */ | ||
1022 | { | ||
1023 | SK_U32 QuCsr; /* CSR contents */ | ||
1024 | |||
1025 | SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr); | ||
1026 | |||
1027 | if ((QuCsr & (CSR_STOP | CSR_SV_IDLE)) == 0) { | ||
1028 | /* Stop Descriptor overridden by start command */ | ||
1029 | SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), CSR_STOP); | ||
1030 | |||
1031 | SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr); | ||
1032 | } | ||
1033 | |||
1034 | return(QuCsr); | ||
1035 | } /* TestStopBit */ | ||
1036 | |||
1037 | |||
1038 | /****************************************************************************** | ||
1039 | * | ||
1040 | * SkGeStopPort() - Stop the Rx/Tx activity of the port 'Port'. | ||
1041 | * | ||
1042 | * Description: | ||
1043 | * After calling this function the descriptor rings and Rx and Tx | ||
1044 | * queues of this port may be reconfigured. | ||
1045 | * | ||
1046 | * It is possible to stop the receive and transmit path separate or | ||
1047 | * both together. | ||
1048 | * | ||
1049 | * Dir = SK_STOP_TX Stops the transmit path only and resets the MAC. | ||
1050 | * The receive queue is still active and | ||
1051 | * the pending Rx frames may be still transferred | ||
1052 | * into the RxD. | ||
1053 | * SK_STOP_RX Stop the receive path. The tansmit path | ||
1054 | * has to be stopped once before. | ||
1055 | * SK_STOP_ALL SK_STOP_TX + SK_STOP_RX | ||
1056 | * | ||
1057 | * RstMode = SK_SOFT_RST Resets the MAC. The PHY is still alive. | ||
1058 | * SK_HARD_RST Resets the MAC and the PHY. | ||
1059 | * | ||
1060 | * Example: | ||
1061 | * 1) A Link Down event was signaled for a port. Therefore the activity | ||
1062 | * of this port should be stopped and a hardware reset should be issued | ||
1063 | * to enable the workaround of XMAC Errata #2. But the received frames | ||
1064 | * should not be discarded. | ||
1065 | * ... | ||
1066 | * SkGeStopPort(pAC, IoC, Port, SK_STOP_TX, SK_HARD_RST); | ||
1067 | * (transfer all pending Rx frames) | ||
1068 | * SkGeStopPort(pAC, IoC, Port, SK_STOP_RX, SK_HARD_RST); | ||
1069 | * ... | ||
1070 | * | ||
1071 | * 2) An event was issued which request the driver to switch | ||
1072 | * the 'virtual active' link to an other already active port | ||
1073 | * as soon as possible. The frames in the receive queue of this | ||
1074 | * port may be lost. But the PHY must not be reset during this | ||
1075 | * event. | ||
1076 | * ... | ||
1077 | * SkGeStopPort(pAC, IoC, Port, SK_STOP_ALL, SK_SOFT_RST); | ||
1078 | * ... | ||
1079 | * | ||
1080 | * Extended Description: | ||
1081 | * If SK_STOP_TX is set, | ||
1082 | * o disable the MAC's receive and transmitter to prevent | ||
1083 | * from sending incomplete frames | ||
1084 | * o stop the port's transmit queues before terminating the | ||
1085 | * BMUs to prevent from performing incomplete PCI cycles | ||
1086 | * on the PCI bus | ||
1087 | * - The network Rx and Tx activity and PCI Tx transfer is | ||
1088 | * disabled now. | ||
1089 | * o reset the MAC depending on the RstMode | ||
1090 | * o Stop Interval Timer and Limit Counter of Tx Arbiter, | ||
1091 | * also disable Force Sync bit and Enable Alloc bit. | ||
1092 | * o perform a local reset of the port's Tx path | ||
1093 | * - reset the PCI FIFO of the async Tx queue | ||
1094 | * - reset the PCI FIFO of the sync Tx queue | ||
1095 | * - reset the RAM Buffer async Tx queue | ||
1096 | * - reset the RAM Buffer sync Tx queue | ||
1097 | * - reset the MAC Tx FIFO | ||
1098 | * o switch Link and Tx LED off, stop the LED counters | ||
1099 | * | ||
1100 | * If SK_STOP_RX is set, | ||
1101 | * o stop the port's receive queue | ||
1102 | * - The path data transfer activity is fully stopped now. | ||
1103 | * o perform a local reset of the port's Rx path | ||
1104 | * - reset the PCI FIFO of the Rx queue | ||
1105 | * - reset the RAM Buffer receive queue | ||
1106 | * - reset the MAC Rx FIFO | ||
1107 | * o switch Rx LED off, stop the LED counter | ||
1108 | * | ||
1109 | * If all ports are stopped, | ||
1110 | * o reset the RAM Interface. | ||
1111 | * | ||
1112 | * Notes: | ||
1113 | * o This function may be called during the driver states RESET_PORT and | ||
1114 | * SWITCH_PORT. | ||
1115 | */ | ||
1116 | void SkGeStopPort( | ||
1117 | SK_AC *pAC, /* adapter context */ | ||
1118 | SK_IOC IoC, /* I/O context */ | ||
1119 | int Port, /* port to stop (MAC_1 + n) */ | ||
1120 | int Dir, /* Direction to Stop (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */ | ||
1121 | int RstMode)/* Reset Mode (SK_SOFT_RST, SK_HARD_RST) */ | ||
1122 | { | ||
1123 | #ifndef SK_DIAG | ||
1124 | SK_EVPARA Para; | ||
1125 | #endif /* !SK_DIAG */ | ||
1126 | SK_GEPORT *pPrt; | ||
1127 | SK_U32 DWord; | ||
1128 | SK_U32 XsCsr; | ||
1129 | SK_U32 XaCsr; | ||
1130 | SK_U64 ToutStart; | ||
1131 | int i; | ||
1132 | int ToutCnt; | ||
1133 | |||
1134 | pPrt = &pAC->GIni.GP[Port]; | ||
1135 | |||
1136 | if ((Dir & SK_STOP_TX) != 0) { | ||
1137 | /* disable receiver and transmitter */ | ||
1138 | SkMacRxTxDisable(pAC, IoC, Port); | ||
1139 | |||
1140 | /* stop both transmit queues */ | ||
1141 | /* | ||
1142 | * If the BMU is in the reset state CSR_STOP will terminate | ||
1143 | * immediately. | ||
1144 | */ | ||
1145 | SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_STOP); | ||
1146 | SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_STOP); | ||
1147 | |||
1148 | ToutStart = SkOsGetTime(pAC); | ||
1149 | ToutCnt = 0; | ||
1150 | do { | ||
1151 | /* | ||
1152 | * Clear packet arbiter timeout to make sure | ||
1153 | * this loop will terminate. | ||
1154 | */ | ||
1155 | SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ? | ||
1156 | PA_CLR_TO_TX1 : PA_CLR_TO_TX2)); | ||
1157 | |||
1158 | /* | ||
1159 | * If the transfer stucks at the MAC the STOP command will not | ||
1160 | * terminate if we don't flush the XMAC's transmit FIFO ! | ||
1161 | */ | ||
1162 | SkMacFlushTxFifo(pAC, IoC, Port); | ||
1163 | |||
1164 | XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff); | ||
1165 | XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff); | ||
1166 | |||
1167 | if (SkOsGetTime(pAC) - ToutStart > (SK_TICKS_PER_SEC / 18)) { | ||
1168 | /* | ||
1169 | * Timeout of 1/18 second reached. | ||
1170 | * This needs to be checked at 1/18 sec only. | ||
1171 | */ | ||
1172 | ToutCnt++; | ||
1173 | if (ToutCnt > 1) { | ||
1174 | /* Might be a problem when the driver event handler | ||
1175 | * calls StopPort again. XXX. | ||
1176 | */ | ||
1177 | |||
1178 | /* Fatal Error, Loop aborted */ | ||
1179 | SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E018, | ||
1180 | SKERR_HWI_E018MSG); | ||
1181 | #ifndef SK_DIAG | ||
1182 | Para.Para64 = Port; | ||
1183 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); | ||
1184 | #endif /* !SK_DIAG */ | ||
1185 | return; | ||
1186 | } | ||
1187 | /* | ||
1188 | * Cache incoherency workaround: Assume a start command | ||
1189 | * has been lost while sending the frame. | ||
1190 | */ | ||
1191 | ToutStart = SkOsGetTime(pAC); | ||
1192 | |||
1193 | if ((XsCsr & CSR_STOP) != 0) { | ||
1194 | SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_START); | ||
1195 | } | ||
1196 | if ((XaCsr & CSR_STOP) != 0) { | ||
1197 | SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_START); | ||
1198 | } | ||
1199 | } | ||
1200 | |||
1201 | /* | ||
1202 | * Because of the ASIC problem report entry from 21.08.1998 it is | ||
1203 | * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set. | ||
1204 | */ | ||
1205 | } while ((XsCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE || | ||
1206 | (XaCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE); | ||
1207 | |||
1208 | /* Reset the MAC depending on the RstMode */ | ||
1209 | if (RstMode == SK_SOFT_RST) { | ||
1210 | SkMacSoftRst(pAC, IoC, Port); | ||
1211 | } | ||
1212 | else { | ||
1213 | SkMacHardRst(pAC, IoC, Port); | ||
1214 | } | ||
1215 | |||
1216 | /* Disable Force Sync bit and Enable Alloc bit */ | ||
1217 | SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), | ||
1218 | TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC); | ||
1219 | |||
1220 | /* Stop Interval Timer and Limit Counter of Tx Arbiter */ | ||
1221 | SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), 0L); | ||
1222 | SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), 0L); | ||
1223 | |||
1224 | /* Perform a local reset of the port's Tx path */ | ||
1225 | |||
1226 | /* Reset the PCI FIFO of the async Tx queue */ | ||
1227 | SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_SET_RESET); | ||
1228 | /* Reset the PCI FIFO of the sync Tx queue */ | ||
1229 | SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_SET_RESET); | ||
1230 | /* Reset the RAM Buffer async Tx queue */ | ||
1231 | SK_OUT8(IoC, RB_ADDR(pPrt->PXaQOff, RB_CTRL), RB_RST_SET); | ||
1232 | /* Reset the RAM Buffer sync Tx queue */ | ||
1233 | SK_OUT8(IoC, RB_ADDR(pPrt->PXsQOff, RB_CTRL), RB_RST_SET); | ||
1234 | |||
1235 | /* Reset Tx MAC FIFO */ | ||
1236 | #ifdef GENESIS | ||
1237 | if (pAC->GIni.GIGenesis) { | ||
1238 | /* Note: MFF_RST_SET does NOT reset the XMAC ! */ | ||
1239 | SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_SET); | ||
1240 | |||
1241 | /* switch Link and Tx LED off, stop the LED counters */ | ||
1242 | /* Link LED is switched off by the RLMT and the Diag itself */ | ||
1243 | SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_DIS); | ||
1244 | } | ||
1245 | #endif /* GENESIS */ | ||
1246 | |||
1247 | #ifdef YUKON | ||
1248 | if (pAC->GIni.GIYukon) { | ||
1249 | /* Reset TX MAC FIFO */ | ||
1250 | SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_SET); | ||
1251 | } | ||
1252 | #endif /* YUKON */ | ||
1253 | } | ||
1254 | |||
1255 | if ((Dir & SK_STOP_RX) != 0) { | ||
1256 | /* | ||
1257 | * The RX Stop Command will not terminate if no buffers | ||
1258 | * are queued in the RxD ring. But it will always reach | ||
1259 | * the Idle state. Therefore we can use this feature to | ||
1260 | * stop the transfer of received packets. | ||
1261 | */ | ||
1262 | /* stop the port's receive queue */ | ||
1263 | SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_STOP); | ||
1264 | |||
1265 | i = 100; | ||
1266 | do { | ||
1267 | /* | ||
1268 | * Clear packet arbiter timeout to make sure | ||
1269 | * this loop will terminate | ||
1270 | */ | ||
1271 | SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ? | ||
1272 | PA_CLR_TO_RX1 : PA_CLR_TO_RX2)); | ||
1273 | |||
1274 | DWord = TestStopBit(pAC, IoC, pPrt->PRxQOff); | ||
1275 | |||
1276 | /* timeout if i==0 (bug fix for #10748) */ | ||
1277 | if (--i == 0) { | ||
1278 | SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E024, | ||
1279 | SKERR_HWI_E024MSG); | ||
1280 | break; | ||
1281 | } | ||
1282 | /* | ||
1283 | * because of the ASIC problem report entry from 21.08.98 | ||
1284 | * it is required to wait until CSR_STOP is reset and | ||
1285 | * CSR_SV_IDLE is set. | ||
1286 | */ | ||
1287 | } while ((DWord & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE); | ||
1288 | |||
1289 | /* The path data transfer activity is fully stopped now */ | ||
1290 | |||
1291 | /* Perform a local reset of the port's Rx path */ | ||
1292 | |||
1293 | /* Reset the PCI FIFO of the Rx queue */ | ||
1294 | SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_SET_RESET); | ||
1295 | /* Reset the RAM Buffer receive queue */ | ||
1296 | SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff, RB_CTRL), RB_RST_SET); | ||
1297 | |||
1298 | /* Reset Rx MAC FIFO */ | ||
1299 | #ifdef GENESIS | ||
1300 | if (pAC->GIni.GIGenesis) { | ||
1301 | |||
1302 | SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_SET); | ||
1303 | |||
1304 | /* switch Rx LED off, stop the LED counter */ | ||
1305 | SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_DIS); | ||
1306 | } | ||
1307 | #endif /* GENESIS */ | ||
1308 | |||
1309 | #ifdef YUKON | ||
1310 | if (pAC->GIni.GIYukon) { | ||
1311 | /* Reset Rx MAC FIFO */ | ||
1312 | SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_SET); | ||
1313 | } | ||
1314 | #endif /* YUKON */ | ||
1315 | } | ||
1316 | } /* SkGeStopPort */ | ||
1317 | |||
1318 | |||
1319 | /****************************************************************************** | ||
1320 | * | ||
1321 | * SkGeInit0() - Level 0 Initialization | ||
1322 | * | ||
1323 | * Description: | ||
1324 | * - Initialize the BMU address offsets | ||
1325 | * | ||
1326 | * Returns: | ||
1327 | * nothing | ||
1328 | */ | ||
1329 | static void SkGeInit0( | ||
1330 | SK_AC *pAC, /* adapter context */ | ||
1331 | SK_IOC IoC) /* IO context */ | ||
1332 | { | ||
1333 | int i; | ||
1334 | SK_GEPORT *pPrt; | ||
1335 | |||
1336 | for (i = 0; i < SK_MAX_MACS; i++) { | ||
1337 | pPrt = &pAC->GIni.GP[i]; | ||
1338 | |||
1339 | pPrt->PState = SK_PRT_RESET; | ||
1340 | pPrt->PRxQOff = QOffTab[i].RxQOff; | ||
1341 | pPrt->PXsQOff = QOffTab[i].XsQOff; | ||
1342 | pPrt->PXaQOff = QOffTab[i].XaQOff; | ||
1343 | pPrt->PCheckPar = SK_FALSE; | ||
1344 | pPrt->PIsave = 0; | ||
1345 | pPrt->PPrevShorts = 0; | ||
1346 | pPrt->PLinkResCt = 0; | ||
1347 | pPrt->PAutoNegTOCt = 0; | ||
1348 | pPrt->PPrevRx = 0; | ||
1349 | pPrt->PPrevFcs = 0; | ||
1350 | pPrt->PRxLim = SK_DEF_RX_WA_LIM; | ||
1351 | pPrt->PLinkMode = (SK_U8)SK_LMODE_AUTOFULL; | ||
1352 | pPrt->PLinkSpeedCap = (SK_U8)SK_LSPEED_CAP_1000MBPS; | ||
1353 | pPrt->PLinkSpeed = (SK_U8)SK_LSPEED_1000MBPS; | ||
1354 | pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_UNKNOWN; | ||
1355 | pPrt->PLinkModeConf = (SK_U8)SK_LMODE_AUTOSENSE; | ||
1356 | pPrt->PFlowCtrlMode = (SK_U8)SK_FLOW_MODE_SYM_OR_REM; | ||
1357 | pPrt->PLinkCap = (SK_U8)(SK_LMODE_CAP_HALF | SK_LMODE_CAP_FULL | | ||
1358 | SK_LMODE_CAP_AUTOHALF | SK_LMODE_CAP_AUTOFULL); | ||
1359 | pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN; | ||
1360 | pPrt->PFlowCtrlCap = (SK_U8)SK_FLOW_MODE_SYM_OR_REM; | ||
1361 | pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE; | ||
1362 | pPrt->PMSCap = 0; | ||
1363 | pPrt->PMSMode = (SK_U8)SK_MS_MODE_AUTO; | ||
1364 | pPrt->PMSStatus = (SK_U8)SK_MS_STAT_UNSET; | ||
1365 | pPrt->PLipaAutoNeg = (SK_U8)SK_LIPA_UNKNOWN; | ||
1366 | pPrt->PAutoNegFail = SK_FALSE; | ||
1367 | pPrt->PHWLinkUp = SK_FALSE; | ||
1368 | pPrt->PLinkBroken = SK_TRUE; /* See WA code */ | ||
1369 | pPrt->PPhyPowerState = PHY_PM_OPERATIONAL_MODE; | ||
1370 | pPrt->PMacColThres = TX_COL_DEF; | ||
1371 | pPrt->PMacJamLen = TX_JAM_LEN_DEF; | ||
1372 | pPrt->PMacJamIpgVal = TX_JAM_IPG_DEF; | ||
1373 | pPrt->PMacJamIpgData = TX_IPG_JAM_DEF; | ||
1374 | pPrt->PMacIpgData = IPG_DATA_DEF; | ||
1375 | pPrt->PMacLimit4 = SK_FALSE; | ||
1376 | } | ||
1377 | |||
1378 | pAC->GIni.GIPortUsage = SK_RED_LINK; | ||
1379 | pAC->GIni.GILedBlinkCtrl = (SK_U16)OemConfig.Value; | ||
1380 | pAC->GIni.GIValIrqMask = IS_ALL_MSK; | ||
1381 | |||
1382 | } /* SkGeInit0*/ | ||
1383 | |||
1384 | |||
1385 | /****************************************************************************** | ||
1386 | * | ||
1387 | * SkGeInit1() - Level 1 Initialization | ||
1388 | * | ||
1389 | * Description: | ||
1390 | * o Do a software reset. | ||
1391 | * o Clear all reset bits. | ||
1392 | * o Verify that the detected hardware is present. | ||
1393 | * Return an error if not. | ||
1394 | * o Get the hardware configuration | ||
1395 | * + Read the number of MACs/Ports. | ||
1396 | * + Read the RAM size. | ||
1397 | * + Read the PCI Revision Id. | ||
1398 | * + Find out the adapters host clock speed | ||
1399 | * + Read and check the PHY type | ||
1400 | * | ||
1401 | * Returns: | ||
1402 | * 0: success | ||
1403 | * 5: Unexpected PHY type detected | ||
1404 | * 6: HW self test failed | ||
1405 | */ | ||
1406 | static int SkGeInit1( | ||
1407 | SK_AC *pAC, /* adapter context */ | ||
1408 | SK_IOC IoC) /* IO context */ | ||
1409 | { | ||
1410 | SK_U8 Byte; | ||
1411 | SK_U16 Word; | ||
1412 | SK_U16 CtrlStat; | ||
1413 | SK_U32 DWord; | ||
1414 | int RetVal; | ||
1415 | int i; | ||
1416 | |||
1417 | RetVal = 0; | ||
1418 | |||
1419 | /* save CLK_RUN bits (YUKON-Lite) */ | ||
1420 | SK_IN16(IoC, B0_CTST, &CtrlStat); | ||
1421 | |||
1422 | /* do the SW-reset */ | ||
1423 | SK_OUT8(IoC, B0_CTST, CS_RST_SET); | ||
1424 | |||
1425 | /* release the SW-reset */ | ||
1426 | SK_OUT8(IoC, B0_CTST, CS_RST_CLR); | ||
1427 | |||
1428 | /* reset all error bits in the PCI STATUS register */ | ||
1429 | /* | ||
1430 | * Note: PCI Cfg cycles cannot be used, because they are not | ||
1431 | * available on some platforms after 'boot time'. | ||
1432 | */ | ||
1433 | SK_IN16(IoC, PCI_C(PCI_STATUS), &Word); | ||
1434 | |||
1435 | SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); | ||
1436 | SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS)); | ||
1437 | SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | ||
1438 | |||
1439 | /* release Master Reset */ | ||
1440 | SK_OUT8(IoC, B0_CTST, CS_MRST_CLR); | ||
1441 | |||
1442 | #ifdef CLK_RUN | ||
1443 | CtrlStat |= CS_CLK_RUN_ENA; | ||
1444 | #endif /* CLK_RUN */ | ||
1445 | |||
1446 | /* restore CLK_RUN bits */ | ||
1447 | SK_OUT16(IoC, B0_CTST, (SK_U16)(CtrlStat & | ||
1448 | (CS_CLK_RUN_HOT | CS_CLK_RUN_RST | CS_CLK_RUN_ENA))); | ||
1449 | |||
1450 | /* read Chip Identification Number */ | ||
1451 | SK_IN8(IoC, B2_CHIP_ID, &Byte); | ||
1452 | pAC->GIni.GIChipId = Byte; | ||
1453 | |||
1454 | /* read number of MACs */ | ||
1455 | SK_IN8(IoC, B2_MAC_CFG, &Byte); | ||
1456 | pAC->GIni.GIMacsFound = (Byte & CFG_SNG_MAC) ? 1 : 2; | ||
1457 | |||
1458 | /* get Chip Revision Number */ | ||
1459 | pAC->GIni.GIChipRev = (SK_U8)((Byte & CFG_CHIP_R_MSK) >> 4); | ||
1460 | |||
1461 | /* get diff. PCI parameters */ | ||
1462 | SK_IN16(IoC, B0_CTST, &CtrlStat); | ||
1463 | |||
1464 | /* read the adapters RAM size */ | ||
1465 | SK_IN8(IoC, B2_E_0, &Byte); | ||
1466 | |||
1467 | pAC->GIni.GIGenesis = SK_FALSE; | ||
1468 | pAC->GIni.GIYukon = SK_FALSE; | ||
1469 | pAC->GIni.GIYukonLite = SK_FALSE; | ||
1470 | |||
1471 | #ifdef GENESIS | ||
1472 | if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { | ||
1473 | |||
1474 | pAC->GIni.GIGenesis = SK_TRUE; | ||
1475 | |||
1476 | if (Byte == (SK_U8)3) { | ||
1477 | /* special case: 4 x 64k x 36, offset = 0x80000 */ | ||
1478 | pAC->GIni.GIRamSize = 1024; | ||
1479 | pAC->GIni.GIRamOffs = (SK_U32)512 * 1024; | ||
1480 | } | ||
1481 | else { | ||
1482 | pAC->GIni.GIRamSize = (int)Byte * 512; | ||
1483 | pAC->GIni.GIRamOffs = 0; | ||
1484 | } | ||
1485 | /* all GE adapters work with 53.125 MHz host clock */ | ||
1486 | pAC->GIni.GIHstClkFact = SK_FACT_53; | ||
1487 | |||
1488 | /* set Descr. Poll Timer Init Value to 250 ms */ | ||
1489 | pAC->GIni.GIPollTimerVal = | ||
1490 | SK_DPOLL_DEF * (SK_U32)pAC->GIni.GIHstClkFact / 100; | ||
1491 | } | ||
1492 | #endif /* GENESIS */ | ||
1493 | |||
1494 | #ifdef YUKON | ||
1495 | if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) { | ||
1496 | |||
1497 | pAC->GIni.GIYukon = SK_TRUE; | ||
1498 | |||
1499 | pAC->GIni.GIRamSize = (Byte == (SK_U8)0) ? 128 : (int)Byte * 4; | ||
1500 | |||
1501 | pAC->GIni.GIRamOffs = 0; | ||
1502 | |||
1503 | /* WA for chip Rev. A */ | ||
1504 | pAC->GIni.GIWolOffs = (pAC->GIni.GIChipId == CHIP_ID_YUKON && | ||
1505 | pAC->GIni.GIChipRev == 0) ? WOL_REG_OFFS : 0; | ||
1506 | |||
1507 | /* get PM Capabilities of PCI config space */ | ||
1508 | SK_IN16(IoC, PCI_C(PCI_PM_CAP_REG), &Word); | ||
1509 | |||
1510 | /* check if VAUX is available */ | ||
1511 | if (((CtrlStat & CS_VAUX_AVAIL) != 0) && | ||
1512 | /* check also if PME from D3cold is set */ | ||
1513 | ((Word & PCI_PME_D3C_SUP) != 0)) { | ||
1514 | /* set entry in GE init struct */ | ||
1515 | pAC->GIni.GIVauxAvail = SK_TRUE; | ||
1516 | } | ||
1517 | |||
1518 | if (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) { | ||
1519 | /* this is Rev. A1 */ | ||
1520 | pAC->GIni.GIYukonLite = SK_TRUE; | ||
1521 | } | ||
1522 | else { | ||
1523 | /* save Flash-Address Register */ | ||
1524 | SK_IN32(IoC, B2_FAR, &DWord); | ||
1525 | |||
1526 | /* test Flash-Address Register */ | ||
1527 | SK_OUT8(IoC, B2_FAR + 3, 0xff); | ||
1528 | SK_IN8(IoC, B2_FAR + 3, &Byte); | ||
1529 | |||
1530 | if (Byte != 0) { | ||
1531 | /* this is Rev. A0 */ | ||
1532 | pAC->GIni.GIYukonLite = SK_TRUE; | ||
1533 | |||
1534 | /* restore Flash-Address Register */ | ||
1535 | SK_OUT32(IoC, B2_FAR, DWord); | ||
1536 | } | ||
1537 | } | ||
1538 | |||
1539 | /* switch power to VCC (WA for VAUX problem) */ | ||
1540 | SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA | | ||
1541 | PC_VAUX_OFF | PC_VCC_ON)); | ||
1542 | |||
1543 | /* read the Interrupt source */ | ||
1544 | SK_IN32(IoC, B0_ISRC, &DWord); | ||
1545 | |||
1546 | if ((DWord & IS_HW_ERR) != 0) { | ||
1547 | /* read the HW Error Interrupt source */ | ||
1548 | SK_IN32(IoC, B0_HWE_ISRC, &DWord); | ||
1549 | |||
1550 | if ((DWord & IS_IRQ_SENSOR) != 0) { | ||
1551 | /* disable HW Error IRQ */ | ||
1552 | pAC->GIni.GIValIrqMask &= ~IS_HW_ERR; | ||
1553 | } | ||
1554 | } | ||
1555 | |||
1556 | for (i = 0; i < pAC->GIni.GIMacsFound; i++) { | ||
1557 | /* set GMAC Link Control reset */ | ||
1558 | SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_SET); | ||
1559 | |||
1560 | /* clear GMAC Link Control reset */ | ||
1561 | SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_CLR); | ||
1562 | } | ||
1563 | /* all YU chips work with 78.125 MHz host clock */ | ||
1564 | pAC->GIni.GIHstClkFact = SK_FACT_78; | ||
1565 | |||
1566 | pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX; /* 215 ms */ | ||
1567 | } | ||
1568 | #endif /* YUKON */ | ||
1569 | |||
1570 | /* check if 64-bit PCI Slot is present */ | ||
1571 | pAC->GIni.GIPciSlot64 = (SK_BOOL)((CtrlStat & CS_BUS_SLOT_SZ) != 0); | ||
1572 | |||
1573 | /* check if 66 MHz PCI Clock is active */ | ||
1574 | pAC->GIni.GIPciClock66 = (SK_BOOL)((CtrlStat & CS_BUS_CLOCK) != 0); | ||
1575 | |||
1576 | /* read PCI HW Revision Id. */ | ||
1577 | SK_IN8(IoC, PCI_C(PCI_REV_ID), &Byte); | ||
1578 | pAC->GIni.GIPciHwRev = Byte; | ||
1579 | |||
1580 | /* read the PMD type */ | ||
1581 | SK_IN8(IoC, B2_PMD_TYP, &Byte); | ||
1582 | pAC->GIni.GICopperType = (SK_U8)(Byte == 'T'); | ||
1583 | |||
1584 | /* read the PHY type */ | ||
1585 | SK_IN8(IoC, B2_E_1, &Byte); | ||
1586 | |||
1587 | Byte &= 0x0f; /* the PHY type is stored in the lower nibble */ | ||
1588 | for (i = 0; i < pAC->GIni.GIMacsFound; i++) { | ||
1589 | |||
1590 | #ifdef GENESIS | ||
1591 | if (pAC->GIni.GIGenesis) { | ||
1592 | switch (Byte) { | ||
1593 | case SK_PHY_XMAC: | ||
1594 | pAC->GIni.GP[i].PhyAddr = PHY_ADDR_XMAC; | ||
1595 | break; | ||
1596 | case SK_PHY_BCOM: | ||
1597 | pAC->GIni.GP[i].PhyAddr = PHY_ADDR_BCOM; | ||
1598 | pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO | | ||
1599 | SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE); | ||
1600 | break; | ||
1601 | #ifdef OTHER_PHY | ||
1602 | case SK_PHY_LONE: | ||
1603 | pAC->GIni.GP[i].PhyAddr = PHY_ADDR_LONE; | ||
1604 | break; | ||
1605 | case SK_PHY_NAT: | ||
1606 | pAC->GIni.GP[i].PhyAddr = PHY_ADDR_NAT; | ||
1607 | break; | ||
1608 | #endif /* OTHER_PHY */ | ||
1609 | default: | ||
1610 | /* ERROR: unexpected PHY type detected */ | ||
1611 | RetVal = 5; | ||
1612 | break; | ||
1613 | } | ||
1614 | } | ||
1615 | #endif /* GENESIS */ | ||
1616 | |||
1617 | #ifdef YUKON | ||
1618 | if (pAC->GIni.GIYukon) { | ||
1619 | |||
1620 | if (Byte < (SK_U8)SK_PHY_MARV_COPPER) { | ||
1621 | /* if this field is not initialized */ | ||
1622 | Byte = (SK_U8)SK_PHY_MARV_COPPER; | ||
1623 | |||
1624 | pAC->GIni.GICopperType = SK_TRUE; | ||
1625 | } | ||
1626 | |||
1627 | pAC->GIni.GP[i].PhyAddr = PHY_ADDR_MARV; | ||
1628 | |||
1629 | if (pAC->GIni.GICopperType) { | ||
1630 | |||
1631 | pAC->GIni.GP[i].PLinkSpeedCap = (SK_U8)(SK_LSPEED_CAP_AUTO | | ||
1632 | SK_LSPEED_CAP_10MBPS | SK_LSPEED_CAP_100MBPS | | ||
1633 | SK_LSPEED_CAP_1000MBPS); | ||
1634 | |||
1635 | pAC->GIni.GP[i].PLinkSpeed = (SK_U8)SK_LSPEED_AUTO; | ||
1636 | |||
1637 | pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO | | ||
1638 | SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE); | ||
1639 | } | ||
1640 | else { | ||
1641 | Byte = (SK_U8)SK_PHY_MARV_FIBER; | ||
1642 | } | ||
1643 | } | ||
1644 | #endif /* YUKON */ | ||
1645 | |||
1646 | pAC->GIni.GP[i].PhyType = (int)Byte; | ||
1647 | |||
1648 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, | ||
1649 | ("PHY type: %d PHY addr: %04x\n", Byte, | ||
1650 | pAC->GIni.GP[i].PhyAddr)); | ||
1651 | } | ||
1652 | |||
1653 | /* get MAC Type & set function pointers dependent on */ | ||
1654 | #ifdef GENESIS | ||
1655 | if (pAC->GIni.GIGenesis) { | ||
1656 | |||
1657 | pAC->GIni.GIMacType = SK_MAC_XMAC; | ||
1658 | |||
1659 | pAC->GIni.GIFunc.pFnMacUpdateStats = SkXmUpdateStats; | ||
1660 | pAC->GIni.GIFunc.pFnMacStatistic = SkXmMacStatistic; | ||
1661 | pAC->GIni.GIFunc.pFnMacResetCounter = SkXmResetCounter; | ||
1662 | pAC->GIni.GIFunc.pFnMacOverflow = SkXmOverflowStatus; | ||
1663 | } | ||
1664 | #endif /* GENESIS */ | ||
1665 | |||
1666 | #ifdef YUKON | ||
1667 | if (pAC->GIni.GIYukon) { | ||
1668 | |||
1669 | pAC->GIni.GIMacType = SK_MAC_GMAC; | ||
1670 | |||
1671 | pAC->GIni.GIFunc.pFnMacUpdateStats = SkGmUpdateStats; | ||
1672 | pAC->GIni.GIFunc.pFnMacStatistic = SkGmMacStatistic; | ||
1673 | pAC->GIni.GIFunc.pFnMacResetCounter = SkGmResetCounter; | ||
1674 | pAC->GIni.GIFunc.pFnMacOverflow = SkGmOverflowStatus; | ||
1675 | |||
1676 | #ifdef SPECIAL_HANDLING | ||
1677 | if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { | ||
1678 | /* check HW self test result */ | ||
1679 | SK_IN8(IoC, B2_E_3, &Byte); | ||
1680 | if (Byte & B2_E3_RES_MASK) { | ||
1681 | RetVal = 6; | ||
1682 | } | ||
1683 | } | ||
1684 | #endif | ||
1685 | } | ||
1686 | #endif /* YUKON */ | ||
1687 | |||
1688 | return(RetVal); | ||
1689 | } /* SkGeInit1 */ | ||
1690 | |||
1691 | |||
1692 | /****************************************************************************** | ||
1693 | * | ||
1694 | * SkGeInit2() - Level 2 Initialization | ||
1695 | * | ||
1696 | * Description: | ||
1697 | * - start the Blink Source Counter | ||
1698 | * - start the Descriptor Poll Timer | ||
1699 | * - configure the MAC-Arbiter | ||
1700 | * - configure the Packet-Arbiter | ||
1701 | * - enable the Tx Arbiters | ||
1702 | * - enable the RAM Interface Arbiter | ||
1703 | * | ||
1704 | * Returns: | ||
1705 | * nothing | ||
1706 | */ | ||
1707 | static void SkGeInit2( | ||
1708 | SK_AC *pAC, /* adapter context */ | ||
1709 | SK_IOC IoC) /* IO context */ | ||
1710 | { | ||
1711 | #ifdef GENESIS | ||
1712 | SK_U32 DWord; | ||
1713 | #endif /* GENESIS */ | ||
1714 | int i; | ||
1715 | |||
1716 | /* start the Descriptor Poll Timer */ | ||
1717 | if (pAC->GIni.GIPollTimerVal != 0) { | ||
1718 | if (pAC->GIni.GIPollTimerVal > SK_DPOLL_MAX) { | ||
1719 | pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX; | ||
1720 | |||
1721 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E017, SKERR_HWI_E017MSG); | ||
1722 | } | ||
1723 | SK_OUT32(IoC, B28_DPT_INI, pAC->GIni.GIPollTimerVal); | ||
1724 | SK_OUT8(IoC, B28_DPT_CTRL, DPT_START); | ||
1725 | } | ||
1726 | |||
1727 | #ifdef GENESIS | ||
1728 | if (pAC->GIni.GIGenesis) { | ||
1729 | /* start the Blink Source Counter */ | ||
1730 | DWord = SK_BLK_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100; | ||
1731 | |||
1732 | SK_OUT32(IoC, B2_BSC_INI, DWord); | ||
1733 | SK_OUT8(IoC, B2_BSC_CTRL, BSC_START); | ||
1734 | |||
1735 | /* | ||
1736 | * Configure the MAC Arbiter and the Packet Arbiter. | ||
1737 | * They will be started once and never be stopped. | ||
1738 | */ | ||
1739 | SkGeInitMacArb(pAC, IoC); | ||
1740 | |||
1741 | SkGeInitPktArb(pAC, IoC); | ||
1742 | } | ||
1743 | #endif /* GENESIS */ | ||
1744 | |||
1745 | #ifdef YUKON | ||
1746 | if (pAC->GIni.GIYukon) { | ||
1747 | /* start Time Stamp Timer */ | ||
1748 | SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_START); | ||
1749 | } | ||
1750 | #endif /* YUKON */ | ||
1751 | |||
1752 | /* enable the Tx Arbiters */ | ||
1753 | for (i = 0; i < pAC->GIni.GIMacsFound; i++) { | ||
1754 | SK_OUT8(IoC, MR_ADDR(i, TXA_CTRL), TXA_ENA_ARB); | ||
1755 | } | ||
1756 | |||
1757 | /* enable the RAM Interface Arbiter */ | ||
1758 | SkGeInitRamIface(pAC, IoC); | ||
1759 | |||
1760 | } /* SkGeInit2 */ | ||
1761 | |||
1762 | /****************************************************************************** | ||
1763 | * | ||
1764 | * SkGeInit() - Initialize the GE Adapter with the specified level. | ||
1765 | * | ||
1766 | * Description: | ||
1767 | * Level 0: Initialize the Module structures. | ||
1768 | * Level 1: Generic Hardware Initialization. The IOP/MemBase pointer has | ||
1769 | * to be set before calling this level. | ||
1770 | * | ||
1771 | * o Do a software reset. | ||
1772 | * o Clear all reset bits. | ||
1773 | * o Verify that the detected hardware is present. | ||
1774 | * Return an error if not. | ||
1775 | * o Get the hardware configuration | ||
1776 | * + Set GIMacsFound with the number of MACs. | ||
1777 | * + Store the RAM size in GIRamSize. | ||
1778 | * + Save the PCI Revision ID in GIPciHwRev. | ||
1779 | * o return an error | ||
1780 | * if Number of MACs > SK_MAX_MACS | ||
1781 | * | ||
1782 | * After returning from Level 0 the adapter | ||
1783 | * may be accessed with IO operations. | ||
1784 | * | ||
1785 | * Level 2: start the Blink Source Counter | ||
1786 | * | ||
1787 | * Returns: | ||
1788 | * 0: success | ||
1789 | * 1: Number of MACs exceeds SK_MAX_MACS (after level 1) | ||
1790 | * 2: Adapter not present or not accessible | ||
1791 | * 3: Illegal initialization level | ||
1792 | * 4: Initialization Level 1 Call missing | ||
1793 | * 5: Unexpected PHY type detected | ||
1794 | * 6: HW self test failed | ||
1795 | */ | ||
1796 | int SkGeInit( | ||
1797 | SK_AC *pAC, /* adapter context */ | ||
1798 | SK_IOC IoC, /* IO context */ | ||
1799 | int Level) /* initialization level */ | ||
1800 | { | ||
1801 | int RetVal; /* return value */ | ||
1802 | SK_U32 DWord; | ||
1803 | |||
1804 | RetVal = 0; | ||
1805 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, | ||
1806 | ("SkGeInit(Level %d)\n", Level)); | ||
1807 | |||
1808 | switch (Level) { | ||
1809 | case SK_INIT_DATA: | ||
1810 | /* Initialization Level 0 */ | ||
1811 | SkGeInit0(pAC, IoC); | ||
1812 | pAC->GIni.GILevel = SK_INIT_DATA; | ||
1813 | break; | ||
1814 | |||
1815 | case SK_INIT_IO: | ||
1816 | /* Initialization Level 1 */ | ||
1817 | RetVal = SkGeInit1(pAC, IoC); | ||
1818 | if (RetVal != 0) { | ||
1819 | break; | ||
1820 | } | ||
1821 | |||
1822 | /* check if the adapter seems to be accessible */ | ||
1823 | SK_OUT32(IoC, B2_IRQM_INI, SK_TEST_VAL); | ||
1824 | SK_IN32(IoC, B2_IRQM_INI, &DWord); | ||
1825 | SK_OUT32(IoC, B2_IRQM_INI, 0L); | ||
1826 | |||
1827 | if (DWord != SK_TEST_VAL) { | ||
1828 | RetVal = 2; | ||
1829 | break; | ||
1830 | } | ||
1831 | |||
1832 | /* check if the number of GIMacsFound matches SK_MAX_MACS */ | ||
1833 | if (pAC->GIni.GIMacsFound > SK_MAX_MACS) { | ||
1834 | RetVal = 1; | ||
1835 | break; | ||
1836 | } | ||
1837 | |||
1838 | /* Level 1 successfully passed */ | ||
1839 | pAC->GIni.GILevel = SK_INIT_IO; | ||
1840 | break; | ||
1841 | |||
1842 | case SK_INIT_RUN: | ||
1843 | /* Initialization Level 2 */ | ||
1844 | if (pAC->GIni.GILevel != SK_INIT_IO) { | ||
1845 | #ifndef SK_DIAG | ||
1846 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E002, SKERR_HWI_E002MSG); | ||
1847 | #endif /* !SK_DIAG */ | ||
1848 | RetVal = 4; | ||
1849 | break; | ||
1850 | } | ||
1851 | SkGeInit2(pAC, IoC); | ||
1852 | |||
1853 | /* Level 2 successfully passed */ | ||
1854 | pAC->GIni.GILevel = SK_INIT_RUN; | ||
1855 | break; | ||
1856 | |||
1857 | default: | ||
1858 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E003, SKERR_HWI_E003MSG); | ||
1859 | RetVal = 3; | ||
1860 | break; | ||
1861 | } | ||
1862 | |||
1863 | return(RetVal); | ||
1864 | } /* SkGeInit */ | ||
1865 | |||
1866 | |||
1867 | /****************************************************************************** | ||
1868 | * | ||
1869 | * SkGeDeInit() - Deinitialize the adapter | ||
1870 | * | ||
1871 | * Description: | ||
1872 | * All ports of the adapter will be stopped if not already done. | ||
1873 | * Do a software reset and switch off all LEDs. | ||
1874 | * | ||
1875 | * Returns: | ||
1876 | * nothing | ||
1877 | */ | ||
1878 | void SkGeDeInit( | ||
1879 | SK_AC *pAC, /* adapter context */ | ||
1880 | SK_IOC IoC) /* IO context */ | ||
1881 | { | ||
1882 | int i; | ||
1883 | SK_U16 Word; | ||
1884 | |||
1885 | #if (!defined(SK_SLIM) && !defined(VCPU)) | ||
1886 | /* ensure I2C is ready */ | ||
1887 | SkI2cWaitIrq(pAC, IoC); | ||
1888 | #endif | ||
1889 | |||
1890 | /* stop all current transfer activity */ | ||
1891 | for (i = 0; i < pAC->GIni.GIMacsFound; i++) { | ||
1892 | if (pAC->GIni.GP[i].PState != SK_PRT_STOP && | ||
1893 | pAC->GIni.GP[i].PState != SK_PRT_RESET) { | ||
1894 | |||
1895 | SkGeStopPort(pAC, IoC, i, SK_STOP_ALL, SK_HARD_RST); | ||
1896 | } | ||
1897 | } | ||
1898 | |||
1899 | /* Reset all bits in the PCI STATUS register */ | ||
1900 | /* | ||
1901 | * Note: PCI Cfg cycles cannot be used, because they are not | ||
1902 | * available on some platforms after 'boot time'. | ||
1903 | */ | ||
1904 | SK_IN16(IoC, PCI_C(PCI_STATUS), &Word); | ||
1905 | |||
1906 | SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); | ||
1907 | SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS)); | ||
1908 | SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | ||
1909 | |||
1910 | /* do the reset, all LEDs are switched off now */ | ||
1911 | SK_OUT8(IoC, B0_CTST, CS_RST_SET); | ||
1912 | |||
1913 | pAC->GIni.GILevel = SK_INIT_DATA; | ||
1914 | } /* SkGeDeInit */ | ||
1915 | |||
1916 | |||
1917 | /****************************************************************************** | ||
1918 | * | ||
1919 | * SkGeInitPort() Initialize the specified port. | ||
1920 | * | ||
1921 | * Description: | ||
1922 | * PRxQSize, PXSQSize, and PXAQSize has to be | ||
1923 | * configured for the specified port before calling this function. | ||
1924 | * The descriptor rings has to be initialized too. | ||
1925 | * | ||
1926 | * o (Re)configure queues of the specified port. | ||
1927 | * o configure the MAC of the specified port. | ||
1928 | * o put ASIC and MAC(s) in operational mode. | ||
1929 | * o initialize Rx/Tx and Sync LED | ||
1930 | * o initialize RAM Buffers and MAC FIFOs | ||
1931 | * | ||
1932 | * The port is ready to connect when returning. | ||
1933 | * | ||
1934 | * Note: | ||
1935 | * The MAC's Rx and Tx state machine is still disabled when returning. | ||
1936 | * | ||
1937 | * Returns: | ||
1938 | * 0: success | ||
1939 | * 1: Queue size initialization error. The configured values | ||
1940 | * for PRxQSize, PXSQSize, or PXAQSize are invalid for one | ||
1941 | * or more queues. The specified port was NOT initialized. | ||
1942 | * An error log entry was generated. | ||
1943 | * 2: The port has to be stopped before it can be initialized again. | ||
1944 | */ | ||
1945 | int SkGeInitPort( | ||
1946 | SK_AC *pAC, /* adapter context */ | ||
1947 | SK_IOC IoC, /* IO context */ | ||
1948 | int Port) /* Port to configure */ | ||
1949 | { | ||
1950 | SK_GEPORT *pPrt; | ||
1951 | |||
1952 | pPrt = &pAC->GIni.GP[Port]; | ||
1953 | |||
1954 | if (SkGeCheckQSize(pAC, Port) != 0) { | ||
1955 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E004, SKERR_HWI_E004MSG); | ||
1956 | return(1); | ||
1957 | } | ||
1958 | |||
1959 | if (pPrt->PState == SK_PRT_INIT || pPrt->PState == SK_PRT_RUN) { | ||
1960 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E005, SKERR_HWI_E005MSG); | ||
1961 | return(2); | ||
1962 | } | ||
1963 | |||
1964 | /* configuration ok, initialize the Port now */ | ||
1965 | |||
1966 | #ifdef GENESIS | ||
1967 | if (pAC->GIni.GIGenesis) { | ||
1968 | /* initialize Rx, Tx and Link LED */ | ||
1969 | /* | ||
1970 | * If 1000BT Phy needs LED initialization than swap | ||
1971 | * LED and XMAC initialization order | ||
1972 | */ | ||
1973 | SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA); | ||
1974 | SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_ENA); | ||
1975 | /* The Link LED is initialized by RLMT or Diagnostics itself */ | ||
1976 | |||
1977 | SkXmInitMac(pAC, IoC, Port); | ||
1978 | } | ||
1979 | #endif /* GENESIS */ | ||
1980 | |||
1981 | #ifdef YUKON | ||
1982 | if (pAC->GIni.GIYukon) { | ||
1983 | |||
1984 | SkGmInitMac(pAC, IoC, Port); | ||
1985 | } | ||
1986 | #endif /* YUKON */ | ||
1987 | |||
1988 | /* do NOT initialize the Link Sync Counter */ | ||
1989 | |||
1990 | SkGeInitMacFifo(pAC, IoC, Port); | ||
1991 | |||
1992 | SkGeInitRamBufs(pAC, IoC, Port); | ||
1993 | |||
1994 | if (pPrt->PXSQSize != 0) { | ||
1995 | /* enable Force Sync bit if synchronous queue available */ | ||
1996 | SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_ENA_FSYNC); | ||
1997 | } | ||
1998 | |||
1999 | SkGeInitBmu(pAC, IoC, Port); | ||
2000 | |||
2001 | /* mark port as initialized */ | ||
2002 | pPrt->PState = SK_PRT_INIT; | ||
2003 | |||
2004 | return(0); | ||
2005 | } /* SkGeInitPort */ | ||
diff --git a/drivers/net/sk98lin/skgemib.c b/drivers/net/sk98lin/skgemib.c new file mode 100644 index 000000000000..0a6f67a7a395 --- /dev/null +++ b/drivers/net/sk98lin/skgemib.c | |||
@@ -0,0 +1,1075 @@ | |||
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 | {OID_SKGE_LINK_CAP, | ||
875 | SK_PNMI_MAC_ENTRIES, | ||
876 | sizeof(SK_PNMI_CONF), | ||
877 | SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkCapability), | ||
878 | SK_PNMI_RO, MacPrivateConf, 0}, | ||
879 | {OID_SKGE_LINK_MODE, | ||
880 | SK_PNMI_MAC_ENTRIES, | ||
881 | sizeof(SK_PNMI_CONF), | ||
882 | SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkMode), | ||
883 | SK_PNMI_RW, MacPrivateConf, 0}, | ||
884 | {OID_SKGE_LINK_MODE_STATUS, | ||
885 | SK_PNMI_MAC_ENTRIES, | ||
886 | sizeof(SK_PNMI_CONF), | ||
887 | SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkModeStatus), | ||
888 | SK_PNMI_RO, MacPrivateConf, 0}, | ||
889 | {OID_SKGE_LINK_STATUS, | ||
890 | SK_PNMI_MAC_ENTRIES, | ||
891 | sizeof(SK_PNMI_CONF), | ||
892 | SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkStatus), | ||
893 | SK_PNMI_RO, MacPrivateConf, 0}, | ||
894 | {OID_SKGE_FLOWCTRL_CAP, | ||
895 | SK_PNMI_MAC_ENTRIES, | ||
896 | sizeof(SK_PNMI_CONF), | ||
897 | SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlCapability), | ||
898 | SK_PNMI_RO, MacPrivateConf, 0}, | ||
899 | {OID_SKGE_FLOWCTRL_MODE, | ||
900 | SK_PNMI_MAC_ENTRIES, | ||
901 | sizeof(SK_PNMI_CONF), | ||
902 | SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlMode), | ||
903 | SK_PNMI_RW, MacPrivateConf, 0}, | ||
904 | {OID_SKGE_FLOWCTRL_STATUS, | ||
905 | SK_PNMI_MAC_ENTRIES, | ||
906 | sizeof(SK_PNMI_CONF), | ||
907 | SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlStatus), | ||
908 | SK_PNMI_RO, MacPrivateConf, 0}, | ||
909 | {OID_SKGE_PHY_OPERATION_CAP, | ||
910 | SK_PNMI_MAC_ENTRIES, | ||
911 | sizeof(SK_PNMI_CONF), | ||
912 | SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationCapability), | ||
913 | SK_PNMI_RO, MacPrivateConf, 0}, | ||
914 | {OID_SKGE_PHY_OPERATION_MODE, | ||
915 | SK_PNMI_MAC_ENTRIES, | ||
916 | sizeof(SK_PNMI_CONF), | ||
917 | SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationMode), | ||
918 | SK_PNMI_RW, MacPrivateConf, 0}, | ||
919 | {OID_SKGE_PHY_OPERATION_STATUS, | ||
920 | SK_PNMI_MAC_ENTRIES, | ||
921 | sizeof(SK_PNMI_CONF), | ||
922 | SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationStatus), | ||
923 | SK_PNMI_RO, MacPrivateConf, 0}, | ||
924 | {OID_SKGE_SPEED_CAP, | ||
925 | SK_PNMI_MAC_ENTRIES, | ||
926 | sizeof(SK_PNMI_CONF), | ||
927 | SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedCapability), | ||
928 | SK_PNMI_RO, MacPrivateConf, 0}, | ||
929 | {OID_SKGE_SPEED_MODE, | ||
930 | SK_PNMI_MAC_ENTRIES, | ||
931 | sizeof(SK_PNMI_CONF), | ||
932 | SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedMode), | ||
933 | SK_PNMI_RW, MacPrivateConf, 0}, | ||
934 | {OID_SKGE_SPEED_STATUS, | ||
935 | SK_PNMI_MAC_ENTRIES, | ||
936 | sizeof(SK_PNMI_CONF), | ||
937 | SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedStatus), | ||
938 | SK_PNMI_RO, MacPrivateConf, 0}, | ||
939 | {OID_SKGE_TRAP, | ||
940 | 1, | ||
941 | 0, | ||
942 | SK_PNMI_MAI_OFF(Trap), | ||
943 | SK_PNMI_RO, General, 0}, | ||
944 | {OID_SKGE_TRAP_NUMBER, | ||
945 | 1, | ||
946 | 0, | ||
947 | SK_PNMI_MAI_OFF(TrapNumber), | ||
948 | SK_PNMI_RO, General, 0}, | ||
949 | {OID_SKGE_RLMT_MODE, | ||
950 | 1, | ||
951 | 0, | ||
952 | SK_PNMI_MAI_OFF(RlmtMode), | ||
953 | SK_PNMI_RW, Rlmt, 0}, | ||
954 | {OID_SKGE_RLMT_PORT_NUMBER, | ||
955 | 1, | ||
956 | 0, | ||
957 | SK_PNMI_MAI_OFF(RlmtPortNumber), | ||
958 | SK_PNMI_RO, Rlmt, 0}, | ||
959 | {OID_SKGE_RLMT_PORT_ACTIVE, | ||
960 | 1, | ||
961 | 0, | ||
962 | SK_PNMI_MAI_OFF(RlmtPortActive), | ||
963 | SK_PNMI_RO, Rlmt, 0}, | ||
964 | {OID_SKGE_RLMT_PORT_PREFERRED, | ||
965 | 1, | ||
966 | 0, | ||
967 | SK_PNMI_MAI_OFF(RlmtPortPreferred), | ||
968 | SK_PNMI_RW, Rlmt, 0}, | ||
969 | {OID_SKGE_RLMT_CHANGE_CTS, | ||
970 | 1, | ||
971 | 0, | ||
972 | SK_PNMI_MAI_OFF(RlmtChangeCts), | ||
973 | SK_PNMI_RO, Rlmt, 0}, | ||
974 | {OID_SKGE_RLMT_CHANGE_TIME, | ||
975 | 1, | ||
976 | 0, | ||
977 | SK_PNMI_MAI_OFF(RlmtChangeTime), | ||
978 | SK_PNMI_RO, Rlmt, 0}, | ||
979 | {OID_SKGE_RLMT_CHANGE_ESTIM, | ||
980 | 1, | ||
981 | 0, | ||
982 | SK_PNMI_MAI_OFF(RlmtChangeEstimate), | ||
983 | SK_PNMI_RO, Rlmt, 0}, | ||
984 | {OID_SKGE_RLMT_CHANGE_THRES, | ||
985 | 1, | ||
986 | 0, | ||
987 | SK_PNMI_MAI_OFF(RlmtChangeThreshold), | ||
988 | SK_PNMI_RW, Rlmt, 0}, | ||
989 | {OID_SKGE_RLMT_PORT_INDEX, | ||
990 | SK_PNMI_MAC_ENTRIES, | ||
991 | sizeof(SK_PNMI_RLMT), | ||
992 | SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtIndex), | ||
993 | SK_PNMI_RO, RlmtStat, 0}, | ||
994 | {OID_SKGE_RLMT_STATUS, | ||
995 | SK_PNMI_MAC_ENTRIES, | ||
996 | sizeof(SK_PNMI_RLMT), | ||
997 | SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtStatus), | ||
998 | SK_PNMI_RO, RlmtStat, 0}, | ||
999 | {OID_SKGE_RLMT_TX_HELLO_CTS, | ||
1000 | SK_PNMI_MAC_ENTRIES, | ||
1001 | sizeof(SK_PNMI_RLMT), | ||
1002 | SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxHelloCts), | ||
1003 | SK_PNMI_RO, RlmtStat, 0}, | ||
1004 | {OID_SKGE_RLMT_RX_HELLO_CTS, | ||
1005 | SK_PNMI_MAC_ENTRIES, | ||
1006 | sizeof(SK_PNMI_RLMT), | ||
1007 | SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxHelloCts), | ||
1008 | SK_PNMI_RO, RlmtStat, 0}, | ||
1009 | {OID_SKGE_RLMT_TX_SP_REQ_CTS, | ||
1010 | SK_PNMI_MAC_ENTRIES, | ||
1011 | sizeof(SK_PNMI_RLMT), | ||
1012 | SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxSpHelloReqCts), | ||
1013 | SK_PNMI_RO, RlmtStat, 0}, | ||
1014 | {OID_SKGE_RLMT_RX_SP_CTS, | ||
1015 | SK_PNMI_MAC_ENTRIES, | ||
1016 | sizeof(SK_PNMI_RLMT), | ||
1017 | SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxSpHelloCts), | ||
1018 | SK_PNMI_RO, RlmtStat, 0}, | ||
1019 | {OID_SKGE_RLMT_MONITOR_NUMBER, | ||
1020 | 1, | ||
1021 | 0, | ||
1022 | SK_PNMI_MAI_OFF(RlmtMonitorNumber), | ||
1023 | SK_PNMI_RO, General, 0}, | ||
1024 | {OID_SKGE_RLMT_MONITOR_INDEX, | ||
1025 | SK_PNMI_MONITOR_ENTRIES, | ||
1026 | sizeof(SK_PNMI_RLMT_MONITOR), | ||
1027 | SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorIndex), | ||
1028 | SK_PNMI_RO, Monitor, 0}, | ||
1029 | {OID_SKGE_RLMT_MONITOR_ADDR, | ||
1030 | SK_PNMI_MONITOR_ENTRIES, | ||
1031 | sizeof(SK_PNMI_RLMT_MONITOR), | ||
1032 | SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAddr), | ||
1033 | SK_PNMI_RO, Monitor, 0}, | ||
1034 | {OID_SKGE_RLMT_MONITOR_ERRS, | ||
1035 | SK_PNMI_MONITOR_ENTRIES, | ||
1036 | sizeof(SK_PNMI_RLMT_MONITOR), | ||
1037 | SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorErrorCts), | ||
1038 | SK_PNMI_RO, Monitor, 0}, | ||
1039 | {OID_SKGE_RLMT_MONITOR_TIMESTAMP, | ||
1040 | SK_PNMI_MONITOR_ENTRIES, | ||
1041 | sizeof(SK_PNMI_RLMT_MONITOR), | ||
1042 | SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorTimestamp), | ||
1043 | SK_PNMI_RO, Monitor, 0}, | ||
1044 | {OID_SKGE_RLMT_MONITOR_ADMIN, | ||
1045 | SK_PNMI_MONITOR_ENTRIES, | ||
1046 | sizeof(SK_PNMI_RLMT_MONITOR), | ||
1047 | SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAdmin), | ||
1048 | SK_PNMI_RW, Monitor, 0}, | ||
1049 | {OID_SKGE_MTU, | ||
1050 | 1, | ||
1051 | 0, | ||
1052 | SK_PNMI_MAI_OFF(MtuSize), | ||
1053 | SK_PNMI_RW, MacPrivateConf, 0}, | ||
1054 | {OID_SKGE_VCT_GET, | ||
1055 | 0, | ||
1056 | 0, | ||
1057 | 0, | ||
1058 | SK_PNMI_RO, Vct, 0}, | ||
1059 | {OID_SKGE_VCT_SET, | ||
1060 | 0, | ||
1061 | 0, | ||
1062 | 0, | ||
1063 | SK_PNMI_WO, Vct, 0}, | ||
1064 | {OID_SKGE_VCT_STATUS, | ||
1065 | 0, | ||
1066 | 0, | ||
1067 | 0, | ||
1068 | SK_PNMI_RO, Vct, 0}, | ||
1069 | {OID_SKGE_BOARDLEVEL, | ||
1070 | 0, | ||
1071 | 0, | ||
1072 | 0, | ||
1073 | SK_PNMI_RO, General, 0}, | ||
1074 | }; | ||
1075 | |||
diff --git a/drivers/net/sk98lin/skgepnmi.c b/drivers/net/sk98lin/skgepnmi.c new file mode 100644 index 000000000000..b36dd9ac6b29 --- /dev/null +++ b/drivers/net/sk98lin/skgepnmi.c | |||
@@ -0,0 +1,8210 @@ | |||
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 SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf, | ||
60 | unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); | ||
61 | int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, | ||
62 | unsigned int *pLen, SK_U32 NetIndex); | ||
63 | int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, | ||
64 | unsigned int *pLen, SK_U32 NetIndex); | ||
65 | int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, | ||
66 | unsigned int *pLen, SK_U32 NetIndex); | ||
67 | int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param); | ||
68 | int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf, | ||
69 | unsigned int * pLen, SK_U32 NetIndex); | ||
70 | |||
71 | |||
72 | /* | ||
73 | * Private Function prototypes | ||
74 | */ | ||
75 | |||
76 | PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int | ||
77 | PhysPortIndex); | ||
78 | PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int | ||
79 | PhysPortIndex); | ||
80 | PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac); | ||
81 | PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf); | ||
82 | PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC, | ||
83 | unsigned int PhysPortIndex, unsigned int StatIndex); | ||
84 | PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex, | ||
85 | unsigned int StatIndex, SK_U32 NetIndex); | ||
86 | PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size); | ||
87 | PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen, | ||
88 | unsigned int *pEntries); | ||
89 | PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr, | ||
90 | unsigned int KeyArrLen, unsigned int *pKeyNo); | ||
91 | PNMI_STATIC int LookupId(SK_U32 Id); | ||
92 | PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac, | ||
93 | unsigned int LastMac); | ||
94 | PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf, | ||
95 | unsigned int *pLen, SK_U32 NetIndex); | ||
96 | PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, | ||
97 | char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); | ||
98 | PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac); | ||
99 | PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId, | ||
100 | unsigned int PortIndex); | ||
101 | PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId, | ||
102 | unsigned int SensorIndex); | ||
103 | PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId); | ||
104 | PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex); | ||
105 | PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex); | ||
106 | PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC); | ||
107 | PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf); | ||
108 | PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf, | ||
109 | unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex); | ||
110 | PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32); | ||
111 | |||
112 | /* | ||
113 | * Table to correlate OID with handler function and index to | ||
114 | * hardware register stored in StatAddress if applicable. | ||
115 | */ | ||
116 | #include "skgemib.c" | ||
117 | |||
118 | /* global variables **********************************************************/ | ||
119 | |||
120 | /* | ||
121 | * Overflow status register bit table and corresponding counter | ||
122 | * dependent on MAC type - the number relates to the size of overflow | ||
123 | * mask returned by the pFnMacOverflow function | ||
124 | */ | ||
125 | PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = { | ||
126 | /* Bit0 */ { SK_PNMI_HTX, SK_PNMI_HTX_UNICAST}, | ||
127 | /* Bit1 */ { SK_PNMI_HTX_OCTETHIGH, SK_PNMI_HTX_BROADCAST}, | ||
128 | /* Bit2 */ { SK_PNMI_HTX_OCTETLOW, SK_PNMI_HTX_PMACC}, | ||
129 | /* Bit3 */ { SK_PNMI_HTX_BROADCAST, SK_PNMI_HTX_MULTICAST}, | ||
130 | /* Bit4 */ { SK_PNMI_HTX_MULTICAST, SK_PNMI_HTX_OCTETLOW}, | ||
131 | /* Bit5 */ { SK_PNMI_HTX_UNICAST, SK_PNMI_HTX_OCTETHIGH}, | ||
132 | /* Bit6 */ { SK_PNMI_HTX_LONGFRAMES, SK_PNMI_HTX_64}, | ||
133 | /* Bit7 */ { SK_PNMI_HTX_BURST, SK_PNMI_HTX_127}, | ||
134 | /* Bit8 */ { SK_PNMI_HTX_PMACC, SK_PNMI_HTX_255}, | ||
135 | /* Bit9 */ { SK_PNMI_HTX_MACC, SK_PNMI_HTX_511}, | ||
136 | /* Bit10 */ { SK_PNMI_HTX_SINGLE_COL, SK_PNMI_HTX_1023}, | ||
137 | /* Bit11 */ { SK_PNMI_HTX_MULTI_COL, SK_PNMI_HTX_MAX}, | ||
138 | /* Bit12 */ { SK_PNMI_HTX_EXCESS_COL, SK_PNMI_HTX_LONGFRAMES}, | ||
139 | /* Bit13 */ { SK_PNMI_HTX_LATE_COL, SK_PNMI_HTX_RESERVED}, | ||
140 | /* Bit14 */ { SK_PNMI_HTX_DEFFERAL, SK_PNMI_HTX_COL}, | ||
141 | /* Bit15 */ { SK_PNMI_HTX_EXCESS_DEF, SK_PNMI_HTX_LATE_COL}, | ||
142 | /* Bit16 */ { SK_PNMI_HTX_UNDERRUN, SK_PNMI_HTX_EXCESS_COL}, | ||
143 | /* Bit17 */ { SK_PNMI_HTX_CARRIER, SK_PNMI_HTX_MULTI_COL}, | ||
144 | /* Bit18 */ { SK_PNMI_HTX_UTILUNDER, SK_PNMI_HTX_SINGLE_COL}, | ||
145 | /* Bit19 */ { SK_PNMI_HTX_UTILOVER, SK_PNMI_HTX_UNDERRUN}, | ||
146 | /* Bit20 */ { SK_PNMI_HTX_64, SK_PNMI_HTX_RESERVED}, | ||
147 | /* Bit21 */ { SK_PNMI_HTX_127, SK_PNMI_HTX_RESERVED}, | ||
148 | /* Bit22 */ { SK_PNMI_HTX_255, SK_PNMI_HTX_RESERVED}, | ||
149 | /* Bit23 */ { SK_PNMI_HTX_511, SK_PNMI_HTX_RESERVED}, | ||
150 | /* Bit24 */ { SK_PNMI_HTX_1023, SK_PNMI_HTX_RESERVED}, | ||
151 | /* Bit25 */ { SK_PNMI_HTX_MAX, SK_PNMI_HTX_RESERVED}, | ||
152 | /* Bit26 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, | ||
153 | /* Bit27 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, | ||
154 | /* Bit28 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, | ||
155 | /* Bit29 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, | ||
156 | /* Bit30 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, | ||
157 | /* Bit31 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, | ||
158 | /* Bit32 */ { SK_PNMI_HRX, SK_PNMI_HRX_UNICAST}, | ||
159 | /* Bit33 */ { SK_PNMI_HRX_OCTETHIGH, SK_PNMI_HRX_BROADCAST}, | ||
160 | /* Bit34 */ { SK_PNMI_HRX_OCTETLOW, SK_PNMI_HRX_PMACC}, | ||
161 | /* Bit35 */ { SK_PNMI_HRX_BROADCAST, SK_PNMI_HRX_MULTICAST}, | ||
162 | /* Bit36 */ { SK_PNMI_HRX_MULTICAST, SK_PNMI_HRX_FCS}, | ||
163 | /* Bit37 */ { SK_PNMI_HRX_UNICAST, SK_PNMI_HRX_RESERVED}, | ||
164 | /* Bit38 */ { SK_PNMI_HRX_PMACC, SK_PNMI_HRX_OCTETLOW}, | ||
165 | /* Bit39 */ { SK_PNMI_HRX_MACC, SK_PNMI_HRX_OCTETHIGH}, | ||
166 | /* Bit40 */ { SK_PNMI_HRX_PMACC_ERR, SK_PNMI_HRX_BADOCTETLOW}, | ||
167 | /* Bit41 */ { SK_PNMI_HRX_MACC_UNKWN, SK_PNMI_HRX_BADOCTETHIGH}, | ||
168 | /* Bit42 */ { SK_PNMI_HRX_BURST, SK_PNMI_HRX_UNDERSIZE}, | ||
169 | /* Bit43 */ { SK_PNMI_HRX_MISSED, SK_PNMI_HRX_RUNT}, | ||
170 | /* Bit44 */ { SK_PNMI_HRX_FRAMING, SK_PNMI_HRX_64}, | ||
171 | /* Bit45 */ { SK_PNMI_HRX_OVERFLOW, SK_PNMI_HRX_127}, | ||
172 | /* Bit46 */ { SK_PNMI_HRX_JABBER, SK_PNMI_HRX_255}, | ||
173 | /* Bit47 */ { SK_PNMI_HRX_CARRIER, SK_PNMI_HRX_511}, | ||
174 | /* Bit48 */ { SK_PNMI_HRX_IRLENGTH, SK_PNMI_HRX_1023}, | ||
175 | /* Bit49 */ { SK_PNMI_HRX_SYMBOL, SK_PNMI_HRX_MAX}, | ||
176 | /* Bit50 */ { SK_PNMI_HRX_SHORTS, SK_PNMI_HRX_LONGFRAMES}, | ||
177 | /* Bit51 */ { SK_PNMI_HRX_RUNT, SK_PNMI_HRX_TOO_LONG}, | ||
178 | /* Bit52 */ { SK_PNMI_HRX_TOO_LONG, SK_PNMI_HRX_JABBER}, | ||
179 | /* Bit53 */ { SK_PNMI_HRX_FCS, SK_PNMI_HRX_RESERVED}, | ||
180 | /* Bit54 */ { SK_PNMI_HRX_RESERVED, SK_PNMI_HRX_OVERFLOW}, | ||
181 | /* Bit55 */ { SK_PNMI_HRX_CEXT, SK_PNMI_HRX_RESERVED}, | ||
182 | /* Bit56 */ { SK_PNMI_HRX_UTILUNDER, SK_PNMI_HRX_RESERVED}, | ||
183 | /* Bit57 */ { SK_PNMI_HRX_UTILOVER, SK_PNMI_HRX_RESERVED}, | ||
184 | /* Bit58 */ { SK_PNMI_HRX_64, SK_PNMI_HRX_RESERVED}, | ||
185 | /* Bit59 */ { SK_PNMI_HRX_127, SK_PNMI_HRX_RESERVED}, | ||
186 | /* Bit60 */ { SK_PNMI_HRX_255, SK_PNMI_HRX_RESERVED}, | ||
187 | /* Bit61 */ { SK_PNMI_HRX_511, SK_PNMI_HRX_RESERVED}, | ||
188 | /* Bit62 */ { SK_PNMI_HRX_1023, SK_PNMI_HRX_RESERVED}, | ||
189 | /* Bit63 */ { SK_PNMI_HRX_MAX, SK_PNMI_HRX_RESERVED} | ||
190 | }; | ||
191 | |||
192 | /* | ||
193 | * Table for hardware register saving on resets and port switches | ||
194 | */ | ||
195 | PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = { | ||
196 | /* SK_PNMI_HTX */ | ||
197 | {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}}, | ||
198 | /* SK_PNMI_HTX_OCTETHIGH */ | ||
199 | {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}}, | ||
200 | /* SK_PNMI_HTX_OCTETLOW */ | ||
201 | {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}}, | ||
202 | /* SK_PNMI_HTX_BROADCAST */ | ||
203 | {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}}, | ||
204 | /* SK_PNMI_HTX_MULTICAST */ | ||
205 | {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}}, | ||
206 | /* SK_PNMI_HTX_UNICAST */ | ||
207 | {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}}, | ||
208 | /* SK_PNMI_HTX_BURST */ | ||
209 | {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}}, | ||
210 | /* SK_PNMI_HTX_PMACC */ | ||
211 | {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}}, | ||
212 | /* SK_PNMI_HTX_MACC */ | ||
213 | {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}}, | ||
214 | /* SK_PNMI_HTX_COL */ | ||
215 | {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}}, | ||
216 | /* SK_PNMI_HTX_SINGLE_COL */ | ||
217 | {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}}, | ||
218 | /* SK_PNMI_HTX_MULTI_COL */ | ||
219 | {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}}, | ||
220 | /* SK_PNMI_HTX_EXCESS_COL */ | ||
221 | {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}}, | ||
222 | /* SK_PNMI_HTX_LATE_COL */ | ||
223 | {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}}, | ||
224 | /* SK_PNMI_HTX_DEFFERAL */ | ||
225 | {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}}, | ||
226 | /* SK_PNMI_HTX_EXCESS_DEF */ | ||
227 | {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}}, | ||
228 | /* SK_PNMI_HTX_UNDERRUN */ | ||
229 | {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}}, | ||
230 | /* SK_PNMI_HTX_CARRIER */ | ||
231 | {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}}, | ||
232 | /* SK_PNMI_HTX_UTILUNDER */ | ||
233 | {{0, SK_FALSE}, {0, SK_FALSE}}, | ||
234 | /* SK_PNMI_HTX_UTILOVER */ | ||
235 | {{0, SK_FALSE}, {0, SK_FALSE}}, | ||
236 | /* SK_PNMI_HTX_64 */ | ||
237 | {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}}, | ||
238 | /* SK_PNMI_HTX_127 */ | ||
239 | {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}}, | ||
240 | /* SK_PNMI_HTX_255 */ | ||
241 | {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}}, | ||
242 | /* SK_PNMI_HTX_511 */ | ||
243 | {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}}, | ||
244 | /* SK_PNMI_HTX_1023 */ | ||
245 | {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}}, | ||
246 | /* SK_PNMI_HTX_MAX */ | ||
247 | {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}}, | ||
248 | /* SK_PNMI_HTX_LONGFRAMES */ | ||
249 | {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}}, | ||
250 | /* SK_PNMI_HTX_SYNC */ | ||
251 | {{0, SK_FALSE}, {0, SK_FALSE}}, | ||
252 | /* SK_PNMI_HTX_SYNC_OCTET */ | ||
253 | {{0, SK_FALSE}, {0, SK_FALSE}}, | ||
254 | /* SK_PNMI_HTX_RESERVED */ | ||
255 | {{0, SK_FALSE}, {0, SK_FALSE}}, | ||
256 | /* SK_PNMI_HRX */ | ||
257 | {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}}, | ||
258 | /* SK_PNMI_HRX_OCTETHIGH */ | ||
259 | {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}}, | ||
260 | /* SK_PNMI_HRX_OCTETLOW */ | ||
261 | {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}}, | ||
262 | /* SK_PNMI_HRX_BADOCTETHIGH */ | ||
263 | {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}}, | ||
264 | /* SK_PNMI_HRX_BADOCTETLOW */ | ||
265 | {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}}, | ||
266 | /* SK_PNMI_HRX_BROADCAST */ | ||
267 | {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}}, | ||
268 | /* SK_PNMI_HRX_MULTICAST */ | ||
269 | {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}}, | ||
270 | /* SK_PNMI_HRX_UNICAST */ | ||
271 | {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}}, | ||
272 | /* SK_PNMI_HRX_PMACC */ | ||
273 | {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}}, | ||
274 | /* SK_PNMI_HRX_MACC */ | ||
275 | {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}}, | ||
276 | /* SK_PNMI_HRX_PMACC_ERR */ | ||
277 | {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}}, | ||
278 | /* SK_PNMI_HRX_MACC_UNKWN */ | ||
279 | {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}}, | ||
280 | /* SK_PNMI_HRX_BURST */ | ||
281 | {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}}, | ||
282 | /* SK_PNMI_HRX_MISSED */ | ||
283 | {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}}, | ||
284 | /* SK_PNMI_HRX_FRAMING */ | ||
285 | {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}}, | ||
286 | /* SK_PNMI_HRX_UNDERSIZE */ | ||
287 | {{0, SK_FALSE}, {GM_RXF_SHT, SK_TRUE}}, | ||
288 | /* SK_PNMI_HRX_OVERFLOW */ | ||
289 | {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}}, | ||
290 | /* SK_PNMI_HRX_JABBER */ | ||
291 | {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}}, | ||
292 | /* SK_PNMI_HRX_CARRIER */ | ||
293 | {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}}, | ||
294 | /* SK_PNMI_HRX_IRLENGTH */ | ||
295 | {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}}, | ||
296 | /* SK_PNMI_HRX_SYMBOL */ | ||
297 | {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}}, | ||
298 | /* SK_PNMI_HRX_SHORTS */ | ||
299 | {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}}, | ||
300 | /* SK_PNMI_HRX_RUNT */ | ||
301 | {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}}, | ||
302 | /* SK_PNMI_HRX_TOO_LONG */ | ||
303 | {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}}, | ||
304 | /* SK_PNMI_HRX_FCS */ | ||
305 | {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}}, | ||
306 | /* SK_PNMI_HRX_CEXT */ | ||
307 | {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}}, | ||
308 | /* SK_PNMI_HRX_UTILUNDER */ | ||
309 | {{0, SK_FALSE}, {0, SK_FALSE}}, | ||
310 | /* SK_PNMI_HRX_UTILOVER */ | ||
311 | {{0, SK_FALSE}, {0, SK_FALSE}}, | ||
312 | /* SK_PNMI_HRX_64 */ | ||
313 | {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}}, | ||
314 | /* SK_PNMI_HRX_127 */ | ||
315 | {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}}, | ||
316 | /* SK_PNMI_HRX_255 */ | ||
317 | {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}}, | ||
318 | /* SK_PNMI_HRX_511 */ | ||
319 | {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}}, | ||
320 | /* SK_PNMI_HRX_1023 */ | ||
321 | {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}}, | ||
322 | /* SK_PNMI_HRX_MAX */ | ||
323 | {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}}, | ||
324 | /* SK_PNMI_HRX_LONGFRAMES */ | ||
325 | {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}}, | ||
326 | /* SK_PNMI_HRX_RESERVED */ | ||
327 | {{0, SK_FALSE}, {0, SK_FALSE}} | ||
328 | }; | ||
329 | |||
330 | |||
331 | /***************************************************************************** | ||
332 | * | ||
333 | * Public functions | ||
334 | * | ||
335 | */ | ||
336 | |||
337 | /***************************************************************************** | ||
338 | * | ||
339 | * SkPnmiInit - Init function of PNMI | ||
340 | * | ||
341 | * Description: | ||
342 | * SK_INIT_DATA: Initialises the data structures | ||
343 | * SK_INIT_IO: Resets the XMAC statistics, determines the device and | ||
344 | * connector type. | ||
345 | * SK_INIT_RUN: Starts a timer event for port switch per hour | ||
346 | * calculation. | ||
347 | * | ||
348 | * Returns: | ||
349 | * Always 0 | ||
350 | */ | ||
351 | int SkPnmiInit( | ||
352 | SK_AC *pAC, /* Pointer to adapter context */ | ||
353 | SK_IOC IoC, /* IO context handle */ | ||
354 | int Level) /* Initialization level */ | ||
355 | { | ||
356 | unsigned int PortMax; /* Number of ports */ | ||
357 | unsigned int PortIndex; /* Current port index in loop */ | ||
358 | SK_U16 Val16; /* Multiple purpose 16 bit variable */ | ||
359 | SK_U8 Val8; /* Mulitple purpose 8 bit variable */ | ||
360 | SK_EVPARA EventParam; /* Event struct for timer event */ | ||
361 | SK_PNMI_VCT *pVctBackupData; | ||
362 | |||
363 | |||
364 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, | ||
365 | ("PNMI: SkPnmiInit: Called, level=%d\n", Level)); | ||
366 | |||
367 | switch (Level) { | ||
368 | |||
369 | case SK_INIT_DATA: | ||
370 | SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi)); | ||
371 | pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN; | ||
372 | pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC)); | ||
373 | pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES; | ||
374 | for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) { | ||
375 | |||
376 | pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE; | ||
377 | pAC->Pnmi.DualNetActiveFlag = SK_FALSE; | ||
378 | } | ||
379 | |||
380 | #ifdef SK_PNMI_CHECK | ||
381 | if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) { | ||
382 | |||
383 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG); | ||
384 | |||
385 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL, | ||
386 | ("CounterOffset struct size (%d) differs from" | ||
387 | "SK_PNMI_MAX_IDX (%d)\n", | ||
388 | SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX)); | ||
389 | } | ||
390 | |||
391 | if (SK_PNMI_MAX_IDX != | ||
392 | (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) { | ||
393 | |||
394 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG); | ||
395 | |||
396 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL, | ||
397 | ("StatAddr table size (%d) differs from " | ||
398 | "SK_PNMI_MAX_IDX (%d)\n", | ||
399 | (sizeof(StatAddr) / | ||
400 | (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)), | ||
401 | SK_PNMI_MAX_IDX)); | ||
402 | } | ||
403 | #endif /* SK_PNMI_CHECK */ | ||
404 | break; | ||
405 | |||
406 | case SK_INIT_IO: | ||
407 | /* | ||
408 | * Reset MAC counters | ||
409 | */ | ||
410 | PortMax = pAC->GIni.GIMacsFound; | ||
411 | |||
412 | for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) { | ||
413 | |||
414 | pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex); | ||
415 | } | ||
416 | |||
417 | /* Initialize DSP variables for Vct() to 0xff => Never written! */ | ||
418 | for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) { | ||
419 | pAC->GIni.GP[PortIndex].PCableLen = 0xff; | ||
420 | pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex]; | ||
421 | pVctBackupData->PCableLen = 0xff; | ||
422 | } | ||
423 | |||
424 | /* | ||
425 | * Get pci bus speed | ||
426 | */ | ||
427 | SK_IN16(IoC, B0_CTST, &Val16); | ||
428 | if ((Val16 & CS_BUS_CLOCK) == 0) { | ||
429 | |||
430 | pAC->Pnmi.PciBusSpeed = 33; | ||
431 | } | ||
432 | else { | ||
433 | pAC->Pnmi.PciBusSpeed = 66; | ||
434 | } | ||
435 | |||
436 | /* | ||
437 | * Get pci bus width | ||
438 | */ | ||
439 | SK_IN16(IoC, B0_CTST, &Val16); | ||
440 | if ((Val16 & CS_BUS_SLOT_SZ) == 0) { | ||
441 | |||
442 | pAC->Pnmi.PciBusWidth = 32; | ||
443 | } | ||
444 | else { | ||
445 | pAC->Pnmi.PciBusWidth = 64; | ||
446 | } | ||
447 | |||
448 | /* | ||
449 | * Get chipset | ||
450 | */ | ||
451 | switch (pAC->GIni.GIChipId) { | ||
452 | case CHIP_ID_GENESIS: | ||
453 | pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC; | ||
454 | break; | ||
455 | |||
456 | case CHIP_ID_YUKON: | ||
457 | pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON; | ||
458 | break; | ||
459 | |||
460 | default: | ||
461 | break; | ||
462 | } | ||
463 | |||
464 | /* | ||
465 | * Get PMD and DeviceType | ||
466 | */ | ||
467 | SK_IN8(IoC, B2_PMD_TYP, &Val8); | ||
468 | switch (Val8) { | ||
469 | case 'S': | ||
470 | pAC->Pnmi.PMD = 3; | ||
471 | if (pAC->GIni.GIMacsFound > 1) { | ||
472 | |||
473 | pAC->Pnmi.DeviceType = 0x00020002; | ||
474 | } | ||
475 | else { | ||
476 | pAC->Pnmi.DeviceType = 0x00020001; | ||
477 | } | ||
478 | break; | ||
479 | |||
480 | case 'L': | ||
481 | pAC->Pnmi.PMD = 2; | ||
482 | if (pAC->GIni.GIMacsFound > 1) { | ||
483 | |||
484 | pAC->Pnmi.DeviceType = 0x00020004; | ||
485 | } | ||
486 | else { | ||
487 | pAC->Pnmi.DeviceType = 0x00020003; | ||
488 | } | ||
489 | break; | ||
490 | |||
491 | case 'C': | ||
492 | pAC->Pnmi.PMD = 4; | ||
493 | if (pAC->GIni.GIMacsFound > 1) { | ||
494 | |||
495 | pAC->Pnmi.DeviceType = 0x00020006; | ||
496 | } | ||
497 | else { | ||
498 | pAC->Pnmi.DeviceType = 0x00020005; | ||
499 | } | ||
500 | break; | ||
501 | |||
502 | case 'T': | ||
503 | pAC->Pnmi.PMD = 5; | ||
504 | if (pAC->GIni.GIMacsFound > 1) { | ||
505 | |||
506 | pAC->Pnmi.DeviceType = 0x00020008; | ||
507 | } | ||
508 | else { | ||
509 | pAC->Pnmi.DeviceType = 0x00020007; | ||
510 | } | ||
511 | break; | ||
512 | |||
513 | default : | ||
514 | pAC->Pnmi.PMD = 1; | ||
515 | pAC->Pnmi.DeviceType = 0; | ||
516 | break; | ||
517 | } | ||
518 | |||
519 | /* | ||
520 | * Get connector | ||
521 | */ | ||
522 | SK_IN8(IoC, B2_CONN_TYP, &Val8); | ||
523 | switch (Val8) { | ||
524 | case 'C': | ||
525 | pAC->Pnmi.Connector = 2; | ||
526 | break; | ||
527 | |||
528 | case 'D': | ||
529 | pAC->Pnmi.Connector = 3; | ||
530 | break; | ||
531 | |||
532 | case 'F': | ||
533 | pAC->Pnmi.Connector = 4; | ||
534 | break; | ||
535 | |||
536 | case 'J': | ||
537 | pAC->Pnmi.Connector = 5; | ||
538 | break; | ||
539 | |||
540 | case 'V': | ||
541 | pAC->Pnmi.Connector = 6; | ||
542 | break; | ||
543 | |||
544 | default: | ||
545 | pAC->Pnmi.Connector = 1; | ||
546 | break; | ||
547 | } | ||
548 | break; | ||
549 | |||
550 | case SK_INIT_RUN: | ||
551 | /* | ||
552 | * Start timer for RLMT change counter | ||
553 | */ | ||
554 | SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); | ||
555 | SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer, | ||
556 | 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER, | ||
557 | EventParam); | ||
558 | break; | ||
559 | |||
560 | default: | ||
561 | break; /* Nothing todo */ | ||
562 | } | ||
563 | |||
564 | return (0); | ||
565 | } | ||
566 | |||
567 | /***************************************************************************** | ||
568 | * | ||
569 | * SkPnmiGetVar - Retrieves the value of a single OID | ||
570 | * | ||
571 | * Description: | ||
572 | * Calls a general sub-function for all this stuff. If the instance | ||
573 | * -1 is passed, the values of all instances are returned in an | ||
574 | * array of values. | ||
575 | * | ||
576 | * Returns: | ||
577 | * SK_PNMI_ERR_OK The request was successfully performed | ||
578 | * SK_PNMI_ERR_GENERAL A general severe internal error occured | ||
579 | * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take | ||
580 | * the data. | ||
581 | * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown | ||
582 | * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't | ||
583 | * exist (e.g. port instance 3 on a two port | ||
584 | * adapter. | ||
585 | */ | ||
586 | static int SkPnmiGetVar( | ||
587 | SK_AC *pAC, /* Pointer to adapter context */ | ||
588 | SK_IOC IoC, /* IO context handle */ | ||
589 | SK_U32 Id, /* Object ID that is to be processed */ | ||
590 | void *pBuf, /* Buffer to which the management data will be copied */ | ||
591 | unsigned int *pLen, /* On call: buffer length. On return: used buffer */ | ||
592 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
593 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
594 | { | ||
595 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, | ||
596 | ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n", | ||
597 | Id, *pLen, Instance, NetIndex)); | ||
598 | |||
599 | return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen, | ||
600 | Instance, NetIndex)); | ||
601 | } | ||
602 | |||
603 | /***************************************************************************** | ||
604 | * | ||
605 | * SkPnmiPreSetVar - Presets the value of a single OID | ||
606 | * | ||
607 | * Description: | ||
608 | * Calls a general sub-function for all this stuff. The preset does | ||
609 | * the same as a set, but returns just before finally setting the | ||
610 | * new value. This is useful to check if a set might be successfull. | ||
611 | * If the instance -1 is passed, an array of values is supposed and | ||
612 | * all instances of the OID will be set. | ||
613 | * | ||
614 | * Returns: | ||
615 | * SK_PNMI_ERR_OK The request was successfully performed. | ||
616 | * SK_PNMI_ERR_GENERAL A general severe internal error occured. | ||
617 | * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain | ||
618 | * the correct data (e.g. a 32bit value is | ||
619 | * needed, but a 16 bit value was passed). | ||
620 | * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid | ||
621 | * value range. | ||
622 | * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. | ||
623 | * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown. | ||
624 | * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't | ||
625 | * exist (e.g. port instance 3 on a two port | ||
626 | * adapter. | ||
627 | */ | ||
628 | static int SkPnmiPreSetVar( | ||
629 | SK_AC *pAC, /* Pointer to adapter context */ | ||
630 | SK_IOC IoC, /* IO context handle */ | ||
631 | SK_U32 Id, /* Object ID that is to be processed */ | ||
632 | void *pBuf, /* Buffer to which the management data will be copied */ | ||
633 | unsigned int *pLen, /* Total length of management data */ | ||
634 | SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */ | ||
635 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
636 | { | ||
637 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, | ||
638 | ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n", | ||
639 | Id, *pLen, Instance, NetIndex)); | ||
640 | |||
641 | |||
642 | return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen, | ||
643 | Instance, NetIndex)); | ||
644 | } | ||
645 | |||
646 | /***************************************************************************** | ||
647 | * | ||
648 | * SkPnmiSetVar - Sets the value of a single OID | ||
649 | * | ||
650 | * Description: | ||
651 | * Calls a general sub-function for all this stuff. The preset does | ||
652 | * the same as a set, but returns just before finally setting the | ||
653 | * new value. This is useful to check if a set might be successfull. | ||
654 | * If the instance -1 is passed, an array of values is supposed and | ||
655 | * all instances of the OID will be set. | ||
656 | * | ||
657 | * Returns: | ||
658 | * SK_PNMI_ERR_OK The request was successfully performed. | ||
659 | * SK_PNMI_ERR_GENERAL A general severe internal error occured. | ||
660 | * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain | ||
661 | * the correct data (e.g. a 32bit value is | ||
662 | * needed, but a 16 bit value was passed). | ||
663 | * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid | ||
664 | * value range. | ||
665 | * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. | ||
666 | * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown. | ||
667 | * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't | ||
668 | * exist (e.g. port instance 3 on a two port | ||
669 | * adapter. | ||
670 | */ | ||
671 | int SkPnmiSetVar( | ||
672 | SK_AC *pAC, /* Pointer to adapter context */ | ||
673 | SK_IOC IoC, /* IO context handle */ | ||
674 | SK_U32 Id, /* Object ID that is to be processed */ | ||
675 | void *pBuf, /* Buffer to which the management data will be copied */ | ||
676 | unsigned int *pLen, /* Total length of management data */ | ||
677 | SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */ | ||
678 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
679 | { | ||
680 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, | ||
681 | ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n", | ||
682 | Id, *pLen, Instance, NetIndex)); | ||
683 | |||
684 | return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen, | ||
685 | Instance, NetIndex)); | ||
686 | } | ||
687 | |||
688 | /***************************************************************************** | ||
689 | * | ||
690 | * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA | ||
691 | * | ||
692 | * Description: | ||
693 | * Runs through the IdTable, queries the single OIDs and stores the | ||
694 | * returned data into the management database structure | ||
695 | * SK_PNMI_STRUCT_DATA. The offset of the OID in the structure | ||
696 | * is stored in the IdTable. The return value of the function will also | ||
697 | * be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the | ||
698 | * minimum size of SK_PNMI_MIN_STRUCT_SIZE. | ||
699 | * | ||
700 | * Returns: | ||
701 | * SK_PNMI_ERR_OK The request was successfully performed | ||
702 | * SK_PNMI_ERR_GENERAL A general severe internal error occured | ||
703 | * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take | ||
704 | * the data. | ||
705 | * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist | ||
706 | */ | ||
707 | int SkPnmiGetStruct( | ||
708 | SK_AC *pAC, /* Pointer to adapter context */ | ||
709 | SK_IOC IoC, /* IO context handle */ | ||
710 | void *pBuf, /* Buffer to which the management data will be copied. */ | ||
711 | unsigned int *pLen, /* Length of buffer */ | ||
712 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
713 | { | ||
714 | int Ret; | ||
715 | unsigned int TableIndex; | ||
716 | unsigned int DstOffset; | ||
717 | unsigned int InstanceNo; | ||
718 | unsigned int InstanceCnt; | ||
719 | SK_U32 Instance; | ||
720 | unsigned int TmpLen; | ||
721 | char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE]; | ||
722 | |||
723 | |||
724 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, | ||
725 | ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n", | ||
726 | *pLen, NetIndex)); | ||
727 | |||
728 | if (*pLen < SK_PNMI_STRUCT_SIZE) { | ||
729 | |||
730 | if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) { | ||
731 | |||
732 | SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT, | ||
733 | (SK_U32)(-1)); | ||
734 | } | ||
735 | |||
736 | *pLen = SK_PNMI_STRUCT_SIZE; | ||
737 | return (SK_PNMI_ERR_TOO_SHORT); | ||
738 | } | ||
739 | |||
740 | /* | ||
741 | * Check NetIndex | ||
742 | */ | ||
743 | if (NetIndex >= pAC->Rlmt.NumNets) { | ||
744 | return (SK_PNMI_ERR_UNKNOWN_NET); | ||
745 | } | ||
746 | |||
747 | /* Update statistic */ | ||
748 | SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call"); | ||
749 | |||
750 | if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) != | ||
751 | SK_PNMI_ERR_OK) { | ||
752 | |||
753 | SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); | ||
754 | *pLen = SK_PNMI_MIN_STRUCT_SIZE; | ||
755 | return (Ret); | ||
756 | } | ||
757 | |||
758 | if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) { | ||
759 | |||
760 | SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); | ||
761 | *pLen = SK_PNMI_MIN_STRUCT_SIZE; | ||
762 | return (Ret); | ||
763 | } | ||
764 | |||
765 | if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) { | ||
766 | |||
767 | SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); | ||
768 | *pLen = SK_PNMI_MIN_STRUCT_SIZE; | ||
769 | return (Ret); | ||
770 | } | ||
771 | |||
772 | /* | ||
773 | * Increment semaphores to indicate that an update was | ||
774 | * already done | ||
775 | */ | ||
776 | pAC->Pnmi.MacUpdatedFlag ++; | ||
777 | pAC->Pnmi.RlmtUpdatedFlag ++; | ||
778 | pAC->Pnmi.SirqUpdatedFlag ++; | ||
779 | |||
780 | /* Get vpd keys for instance calculation */ | ||
781 | Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen); | ||
782 | if (Ret != SK_PNMI_ERR_OK) { | ||
783 | |||
784 | pAC->Pnmi.MacUpdatedFlag --; | ||
785 | pAC->Pnmi.RlmtUpdatedFlag --; | ||
786 | pAC->Pnmi.SirqUpdatedFlag --; | ||
787 | |||
788 | SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return"); | ||
789 | SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); | ||
790 | *pLen = SK_PNMI_MIN_STRUCT_SIZE; | ||
791 | return (SK_PNMI_ERR_GENERAL); | ||
792 | } | ||
793 | |||
794 | /* Retrieve values */ | ||
795 | SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE); | ||
796 | for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) { | ||
797 | |||
798 | InstanceNo = IdTable[TableIndex].InstanceNo; | ||
799 | for (InstanceCnt = 1; InstanceCnt <= InstanceNo; | ||
800 | InstanceCnt ++) { | ||
801 | |||
802 | DstOffset = IdTable[TableIndex].Offset + | ||
803 | (InstanceCnt - 1) * | ||
804 | IdTable[TableIndex].StructSize; | ||
805 | |||
806 | /* | ||
807 | * For the VPD the instance is not an index number | ||
808 | * but the key itself. Determin with the instance | ||
809 | * counter the VPD key to be used. | ||
810 | */ | ||
811 | if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY || | ||
812 | IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE || | ||
813 | IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS || | ||
814 | IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) { | ||
815 | |||
816 | SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4); | ||
817 | } | ||
818 | else { | ||
819 | Instance = (SK_U32)InstanceCnt; | ||
820 | } | ||
821 | |||
822 | TmpLen = *pLen - DstOffset; | ||
823 | Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET, | ||
824 | IdTable[TableIndex].Id, (char *)pBuf + | ||
825 | DstOffset, &TmpLen, Instance, TableIndex, NetIndex); | ||
826 | |||
827 | /* | ||
828 | * An unknown instance error means that we reached | ||
829 | * the last instance of that variable. Proceed with | ||
830 | * the next OID in the table and ignore the return | ||
831 | * code. | ||
832 | */ | ||
833 | if (Ret == SK_PNMI_ERR_UNKNOWN_INST) { | ||
834 | |||
835 | break; | ||
836 | } | ||
837 | |||
838 | if (Ret != SK_PNMI_ERR_OK) { | ||
839 | |||
840 | pAC->Pnmi.MacUpdatedFlag --; | ||
841 | pAC->Pnmi.RlmtUpdatedFlag --; | ||
842 | pAC->Pnmi.SirqUpdatedFlag --; | ||
843 | |||
844 | SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return"); | ||
845 | SK_PNMI_SET_STAT(pBuf, Ret, DstOffset); | ||
846 | *pLen = SK_PNMI_MIN_STRUCT_SIZE; | ||
847 | return (Ret); | ||
848 | } | ||
849 | } | ||
850 | } | ||
851 | |||
852 | pAC->Pnmi.MacUpdatedFlag --; | ||
853 | pAC->Pnmi.RlmtUpdatedFlag --; | ||
854 | pAC->Pnmi.SirqUpdatedFlag --; | ||
855 | |||
856 | *pLen = SK_PNMI_STRUCT_SIZE; | ||
857 | SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return"); | ||
858 | SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1)); | ||
859 | return (SK_PNMI_ERR_OK); | ||
860 | } | ||
861 | |||
862 | /***************************************************************************** | ||
863 | * | ||
864 | * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA | ||
865 | * | ||
866 | * Description: | ||
867 | * Calls a general sub-function for all this set stuff. The preset does | ||
868 | * the same as a set, but returns just before finally setting the | ||
869 | * new value. This is useful to check if a set might be successfull. | ||
870 | * The sub-function runs through the IdTable, checks which OIDs are able | ||
871 | * to set, and calls the handler function of the OID to perform the | ||
872 | * preset. The return value of the function will also be stored in | ||
873 | * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of | ||
874 | * SK_PNMI_MIN_STRUCT_SIZE. | ||
875 | * | ||
876 | * Returns: | ||
877 | * SK_PNMI_ERR_OK The request was successfully performed. | ||
878 | * SK_PNMI_ERR_GENERAL A general severe internal error occured. | ||
879 | * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain | ||
880 | * the correct data (e.g. a 32bit value is | ||
881 | * needed, but a 16 bit value was passed). | ||
882 | * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid | ||
883 | * value range. | ||
884 | */ | ||
885 | int SkPnmiPreSetStruct( | ||
886 | SK_AC *pAC, /* Pointer to adapter context */ | ||
887 | SK_IOC IoC, /* IO context handle */ | ||
888 | void *pBuf, /* Buffer which contains the data to be set */ | ||
889 | unsigned int *pLen, /* Length of buffer */ | ||
890 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
891 | { | ||
892 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, | ||
893 | ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n", | ||
894 | *pLen, NetIndex)); | ||
895 | |||
896 | return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf, | ||
897 | pLen, NetIndex)); | ||
898 | } | ||
899 | |||
900 | /***************************************************************************** | ||
901 | * | ||
902 | * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA | ||
903 | * | ||
904 | * Description: | ||
905 | * Calls a general sub-function for all this set stuff. The return value | ||
906 | * of the function will also be stored in SK_PNMI_STRUCT_DATA if the | ||
907 | * passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE. | ||
908 | * The sub-function runs through the IdTable, checks which OIDs are able | ||
909 | * to set, and calls the handler function of the OID to perform the | ||
910 | * set. The return value of the function will also be stored in | ||
911 | * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of | ||
912 | * SK_PNMI_MIN_STRUCT_SIZE. | ||
913 | * | ||
914 | * Returns: | ||
915 | * SK_PNMI_ERR_OK The request was successfully performed. | ||
916 | * SK_PNMI_ERR_GENERAL A general severe internal error occured. | ||
917 | * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain | ||
918 | * the correct data (e.g. a 32bit value is | ||
919 | * needed, but a 16 bit value was passed). | ||
920 | * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid | ||
921 | * value range. | ||
922 | */ | ||
923 | int SkPnmiSetStruct( | ||
924 | SK_AC *pAC, /* Pointer to adapter context */ | ||
925 | SK_IOC IoC, /* IO context handle */ | ||
926 | void *pBuf, /* Buffer which contains the data to be set */ | ||
927 | unsigned int *pLen, /* Length of buffer */ | ||
928 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
929 | { | ||
930 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, | ||
931 | ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n", | ||
932 | *pLen, NetIndex)); | ||
933 | |||
934 | return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf, | ||
935 | pLen, NetIndex)); | ||
936 | } | ||
937 | |||
938 | /***************************************************************************** | ||
939 | * | ||
940 | * SkPnmiEvent - Event handler | ||
941 | * | ||
942 | * Description: | ||
943 | * Handles the following events: | ||
944 | * SK_PNMI_EVT_SIRQ_OVERFLOW When a hardware counter overflows an | ||
945 | * interrupt will be generated which is | ||
946 | * first handled by SIRQ which generates a | ||
947 | * this event. The event increments the | ||
948 | * upper 32 bit of the 64 bit counter. | ||
949 | * SK_PNMI_EVT_SEN_XXX The event is generated by the I2C module | ||
950 | * when a sensor reports a warning or | ||
951 | * error. The event will store a trap | ||
952 | * message in the trap buffer. | ||
953 | * SK_PNMI_EVT_CHG_EST_TIMER The timer event was initiated by this | ||
954 | * module and is used to calculate the | ||
955 | * port switches per hour. | ||
956 | * SK_PNMI_EVT_CLEAR_COUNTER The event clears all counters and | ||
957 | * timestamps. | ||
958 | * SK_PNMI_EVT_XMAC_RESET The event is generated by the driver | ||
959 | * before a hard reset of the XMAC is | ||
960 | * performed. All counters will be saved | ||
961 | * and added to the hardware counter | ||
962 | * values after reset to grant continuous | ||
963 | * counter values. | ||
964 | * SK_PNMI_EVT_RLMT_PORT_UP Generated by RLMT to notify that a port | ||
965 | * went logically up. A trap message will | ||
966 | * be stored to the trap buffer. | ||
967 | * SK_PNMI_EVT_RLMT_PORT_DOWN Generated by RLMT to notify that a port | ||
968 | * went logically down. A trap message will | ||
969 | * be stored to the trap buffer. | ||
970 | * SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two | ||
971 | * spanning tree root bridges were | ||
972 | * detected. A trap message will be stored | ||
973 | * to the trap buffer. | ||
974 | * SK_PNMI_EVT_RLMT_ACTIVE_DOWN Notifies PNMI that an active port went | ||
975 | * down. PNMI will not further add the | ||
976 | * statistic values to the virtual port. | ||
977 | * SK_PNMI_EVT_RLMT_ACTIVE_UP Notifies PNMI that a port went up and | ||
978 | * is now an active port. PNMI will now | ||
979 | * add the statistic data of this port to | ||
980 | * the virtual port. | ||
981 | * SK_PNMI_EVT_RLMT_SET_NETS Notifies PNMI about the net mode. The first parameter | ||
982 | * contains the number of nets. 1 means single net, 2 means | ||
983 | * dual net. The second parameter is -1 | ||
984 | * | ||
985 | * Returns: | ||
986 | * Always 0 | ||
987 | */ | ||
988 | int SkPnmiEvent( | ||
989 | SK_AC *pAC, /* Pointer to adapter context */ | ||
990 | SK_IOC IoC, /* IO context handle */ | ||
991 | SK_U32 Event, /* Event-Id */ | ||
992 | SK_EVPARA Param) /* Event dependent parameter */ | ||
993 | { | ||
994 | unsigned int PhysPortIndex; | ||
995 | unsigned int MaxNetNumber; | ||
996 | int CounterIndex; | ||
997 | int Ret; | ||
998 | SK_U16 MacStatus; | ||
999 | SK_U64 OverflowStatus; | ||
1000 | SK_U64 Mask; | ||
1001 | int MacType; | ||
1002 | SK_U64 Value; | ||
1003 | SK_U32 Val32; | ||
1004 | SK_U16 Register; | ||
1005 | SK_EVPARA EventParam; | ||
1006 | SK_U64 NewestValue; | ||
1007 | SK_U64 OldestValue; | ||
1008 | SK_U64 Delta; | ||
1009 | SK_PNMI_ESTIMATE *pEst; | ||
1010 | SK_U32 NetIndex; | ||
1011 | SK_GEPORT *pPrt; | ||
1012 | SK_PNMI_VCT *pVctBackupData; | ||
1013 | SK_U32 RetCode; | ||
1014 | int i; | ||
1015 | SK_U32 CableLength; | ||
1016 | |||
1017 | |||
1018 | #ifdef DEBUG | ||
1019 | if (Event != SK_PNMI_EVT_XMAC_RESET) { | ||
1020 | |||
1021 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, | ||
1022 | ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n", | ||
1023 | (unsigned int)Event, (unsigned int)Param.Para64)); | ||
1024 | } | ||
1025 | #endif /* DEBUG */ | ||
1026 | SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call"); | ||
1027 | |||
1028 | MacType = pAC->GIni.GIMacType; | ||
1029 | |||
1030 | switch (Event) { | ||
1031 | |||
1032 | case SK_PNMI_EVT_SIRQ_OVERFLOW: | ||
1033 | PhysPortIndex = (int)Param.Para32[0]; | ||
1034 | MacStatus = (SK_U16)Param.Para32[1]; | ||
1035 | #ifdef DEBUG | ||
1036 | if (PhysPortIndex >= SK_MAX_MACS) { | ||
1037 | |||
1038 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, | ||
1039 | ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter" | ||
1040 | " wrong, PhysPortIndex=0x%x\n", | ||
1041 | PhysPortIndex)); | ||
1042 | return (0); | ||
1043 | } | ||
1044 | #endif /* DEBUG */ | ||
1045 | OverflowStatus = 0; | ||
1046 | |||
1047 | /* | ||
1048 | * Check which source caused an overflow interrupt. | ||
1049 | */ | ||
1050 | if ((pAC->GIni.GIFunc.pFnMacOverflow(pAC, IoC, PhysPortIndex, | ||
1051 | MacStatus, &OverflowStatus) != 0) || | ||
1052 | (OverflowStatus == 0)) { | ||
1053 | |||
1054 | SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return"); | ||
1055 | return (0); | ||
1056 | } | ||
1057 | |||
1058 | /* | ||
1059 | * Check the overflow status register and increment | ||
1060 | * the upper dword of corresponding counter. | ||
1061 | */ | ||
1062 | for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8; | ||
1063 | CounterIndex ++) { | ||
1064 | |||
1065 | Mask = (SK_U64)1 << CounterIndex; | ||
1066 | if ((OverflowStatus & Mask) == 0) { | ||
1067 | |||
1068 | continue; | ||
1069 | } | ||
1070 | |||
1071 | switch (StatOvrflwBit[CounterIndex][MacType]) { | ||
1072 | |||
1073 | case SK_PNMI_HTX_UTILUNDER: | ||
1074 | case SK_PNMI_HTX_UTILOVER: | ||
1075 | if (MacType == SK_MAC_XMAC) { | ||
1076 | XM_IN16(IoC, PhysPortIndex, XM_TX_CMD, &Register); | ||
1077 | Register |= XM_TX_SAM_LINE; | ||
1078 | XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD, Register); | ||
1079 | } | ||
1080 | break; | ||
1081 | |||
1082 | case SK_PNMI_HRX_UTILUNDER: | ||
1083 | case SK_PNMI_HRX_UTILOVER: | ||
1084 | if (MacType == SK_MAC_XMAC) { | ||
1085 | XM_IN16(IoC, PhysPortIndex, XM_RX_CMD, &Register); | ||
1086 | Register |= XM_RX_SAM_LINE; | ||
1087 | XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD, Register); | ||
1088 | } | ||
1089 | break; | ||
1090 | |||
1091 | case SK_PNMI_HTX_OCTETHIGH: | ||
1092 | case SK_PNMI_HTX_OCTETLOW: | ||
1093 | case SK_PNMI_HTX_RESERVED: | ||
1094 | case SK_PNMI_HRX_OCTETHIGH: | ||
1095 | case SK_PNMI_HRX_OCTETLOW: | ||
1096 | case SK_PNMI_HRX_IRLENGTH: | ||
1097 | case SK_PNMI_HRX_RESERVED: | ||
1098 | |||
1099 | /* | ||
1100 | * the following counters aren't be handled (id > 63) | ||
1101 | */ | ||
1102 | case SK_PNMI_HTX_SYNC: | ||
1103 | case SK_PNMI_HTX_SYNC_OCTET: | ||
1104 | break; | ||
1105 | |||
1106 | case SK_PNMI_HRX_LONGFRAMES: | ||
1107 | if (MacType == SK_MAC_GMAC) { | ||
1108 | pAC->Pnmi.Port[PhysPortIndex]. | ||
1109 | CounterHigh[CounterIndex] ++; | ||
1110 | } | ||
1111 | break; | ||
1112 | |||
1113 | default: | ||
1114 | pAC->Pnmi.Port[PhysPortIndex]. | ||
1115 | CounterHigh[CounterIndex] ++; | ||
1116 | } | ||
1117 | } | ||
1118 | break; | ||
1119 | |||
1120 | case SK_PNMI_EVT_SEN_WAR_LOW: | ||
1121 | #ifdef DEBUG | ||
1122 | if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) { | ||
1123 | |||
1124 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, | ||
1125 | ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n", | ||
1126 | (unsigned int)Param.Para64)); | ||
1127 | return (0); | ||
1128 | } | ||
1129 | #endif /* DEBUG */ | ||
1130 | |||
1131 | /* | ||
1132 | * Store a trap message in the trap buffer and generate | ||
1133 | * an event for user space applications with the | ||
1134 | * SK_DRIVER_SENDEVENT macro. | ||
1135 | */ | ||
1136 | QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW, | ||
1137 | (unsigned int)Param.Para64); | ||
1138 | (void)SK_DRIVER_SENDEVENT(pAC, IoC); | ||
1139 | break; | ||
1140 | |||
1141 | case SK_PNMI_EVT_SEN_WAR_UPP: | ||
1142 | #ifdef DEBUG | ||
1143 | if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) { | ||
1144 | |||
1145 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, | ||
1146 | ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n", | ||
1147 | (unsigned int)Param.Para64)); | ||
1148 | return (0); | ||
1149 | } | ||
1150 | #endif /* DEBUG */ | ||
1151 | |||
1152 | /* | ||
1153 | * Store a trap message in the trap buffer and generate | ||
1154 | * an event for user space applications with the | ||
1155 | * SK_DRIVER_SENDEVENT macro. | ||
1156 | */ | ||
1157 | QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP, | ||
1158 | (unsigned int)Param.Para64); | ||
1159 | (void)SK_DRIVER_SENDEVENT(pAC, IoC); | ||
1160 | break; | ||
1161 | |||
1162 | case SK_PNMI_EVT_SEN_ERR_LOW: | ||
1163 | #ifdef DEBUG | ||
1164 | if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) { | ||
1165 | |||
1166 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, | ||
1167 | ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n", | ||
1168 | (unsigned int)Param.Para64)); | ||
1169 | return (0); | ||
1170 | } | ||
1171 | #endif /* DEBUG */ | ||
1172 | |||
1173 | /* | ||
1174 | * Store a trap message in the trap buffer and generate | ||
1175 | * an event for user space applications with the | ||
1176 | * SK_DRIVER_SENDEVENT macro. | ||
1177 | */ | ||
1178 | QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW, | ||
1179 | (unsigned int)Param.Para64); | ||
1180 | (void)SK_DRIVER_SENDEVENT(pAC, IoC); | ||
1181 | break; | ||
1182 | |||
1183 | case SK_PNMI_EVT_SEN_ERR_UPP: | ||
1184 | #ifdef DEBUG | ||
1185 | if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) { | ||
1186 | |||
1187 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, | ||
1188 | ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n", | ||
1189 | (unsigned int)Param.Para64)); | ||
1190 | return (0); | ||
1191 | } | ||
1192 | #endif /* DEBUG */ | ||
1193 | |||
1194 | /* | ||
1195 | * Store a trap message in the trap buffer and generate | ||
1196 | * an event for user space applications with the | ||
1197 | * SK_DRIVER_SENDEVENT macro. | ||
1198 | */ | ||
1199 | QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP, | ||
1200 | (unsigned int)Param.Para64); | ||
1201 | (void)SK_DRIVER_SENDEVENT(pAC, IoC); | ||
1202 | break; | ||
1203 | |||
1204 | case SK_PNMI_EVT_CHG_EST_TIMER: | ||
1205 | /* | ||
1206 | * Calculate port switch average on a per hour basis | ||
1207 | * Time interval for check : 28125 ms | ||
1208 | * Number of values for average : 8 | ||
1209 | * | ||
1210 | * Be careful in changing these values, on change check | ||
1211 | * - typedef of SK_PNMI_ESTIMATE (Size of EstValue | ||
1212 | * array one less than value number) | ||
1213 | * - Timer initialization SkTimerStart() in SkPnmiInit | ||
1214 | * - Delta value below must be multiplicated with | ||
1215 | * power of 2 | ||
1216 | * | ||
1217 | */ | ||
1218 | pEst = &pAC->Pnmi.RlmtChangeEstimate; | ||
1219 | CounterIndex = pEst->EstValueIndex + 1; | ||
1220 | if (CounterIndex == 7) { | ||
1221 | |||
1222 | CounterIndex = 0; | ||
1223 | } | ||
1224 | pEst->EstValueIndex = CounterIndex; | ||
1225 | |||
1226 | NewestValue = pAC->Pnmi.RlmtChangeCts; | ||
1227 | OldestValue = pEst->EstValue[CounterIndex]; | ||
1228 | pEst->EstValue[CounterIndex] = NewestValue; | ||
1229 | |||
1230 | /* | ||
1231 | * Calculate average. Delta stores the number of | ||
1232 | * port switches per 28125 * 8 = 225000 ms | ||
1233 | */ | ||
1234 | if (NewestValue >= OldestValue) { | ||
1235 | |||
1236 | Delta = NewestValue - OldestValue; | ||
1237 | } | ||
1238 | else { | ||
1239 | /* Overflow situation */ | ||
1240 | Delta = (SK_U64)(0 - OldestValue) + NewestValue; | ||
1241 | } | ||
1242 | |||
1243 | /* | ||
1244 | * Extrapolate delta to port switches per hour. | ||
1245 | * Estimate = Delta * (3600000 / 225000) | ||
1246 | * = Delta * 16 | ||
1247 | * = Delta << 4 | ||
1248 | */ | ||
1249 | pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4; | ||
1250 | |||
1251 | /* | ||
1252 | * Check if threshold is exceeded. If the threshold is | ||
1253 | * permanently exceeded every 28125 ms an event will be | ||
1254 | * generated to remind the user of this condition. | ||
1255 | */ | ||
1256 | if ((pAC->Pnmi.RlmtChangeThreshold != 0) && | ||
1257 | (pAC->Pnmi.RlmtChangeEstimate.Estimate >= | ||
1258 | pAC->Pnmi.RlmtChangeThreshold)) { | ||
1259 | |||
1260 | QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES); | ||
1261 | (void)SK_DRIVER_SENDEVENT(pAC, IoC); | ||
1262 | } | ||
1263 | |||
1264 | SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); | ||
1265 | SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer, | ||
1266 | 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER, | ||
1267 | EventParam); | ||
1268 | break; | ||
1269 | |||
1270 | case SK_PNMI_EVT_CLEAR_COUNTER: | ||
1271 | /* | ||
1272 | * Param.Para32[0] contains the NetIndex (0 ..1). | ||
1273 | * Param.Para32[1] is reserved, contains -1. | ||
1274 | */ | ||
1275 | NetIndex = (SK_U32)Param.Para32[0]; | ||
1276 | |||
1277 | #ifdef DEBUG | ||
1278 | if (NetIndex >= pAC->Rlmt.NumNets) { | ||
1279 | |||
1280 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, | ||
1281 | ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n", | ||
1282 | NetIndex)); | ||
1283 | |||
1284 | return (0); | ||
1285 | } | ||
1286 | #endif /* DEBUG */ | ||
1287 | |||
1288 | /* | ||
1289 | * Set all counters and timestamps to zero. | ||
1290 | * The according NetIndex is required as a | ||
1291 | * parameter of the event. | ||
1292 | */ | ||
1293 | ResetCounter(pAC, IoC, NetIndex); | ||
1294 | break; | ||
1295 | |||
1296 | case SK_PNMI_EVT_XMAC_RESET: | ||
1297 | /* | ||
1298 | * To grant continuous counter values store the current | ||
1299 | * XMAC statistic values to the entries 1..n of the | ||
1300 | * CounterOffset array. XMAC Errata #2 | ||
1301 | */ | ||
1302 | #ifdef DEBUG | ||
1303 | if ((unsigned int)Param.Para64 >= SK_MAX_MACS) { | ||
1304 | |||
1305 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, | ||
1306 | ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n", | ||
1307 | (unsigned int)Param.Para64)); | ||
1308 | return (0); | ||
1309 | } | ||
1310 | #endif | ||
1311 | PhysPortIndex = (unsigned int)Param.Para64; | ||
1312 | |||
1313 | /* | ||
1314 | * Update XMAC statistic to get fresh values | ||
1315 | */ | ||
1316 | Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1); | ||
1317 | if (Ret != SK_PNMI_ERR_OK) { | ||
1318 | |||
1319 | SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return"); | ||
1320 | return (0); | ||
1321 | } | ||
1322 | /* | ||
1323 | * Increment semaphore to indicate that an update was | ||
1324 | * already done | ||
1325 | */ | ||
1326 | pAC->Pnmi.MacUpdatedFlag ++; | ||
1327 | |||
1328 | for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX; | ||
1329 | CounterIndex ++) { | ||
1330 | |||
1331 | if (!StatAddr[CounterIndex][MacType].GetOffset) { | ||
1332 | |||
1333 | continue; | ||
1334 | } | ||
1335 | |||
1336 | pAC->Pnmi.Port[PhysPortIndex].CounterOffset[CounterIndex] = | ||
1337 | GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex); | ||
1338 | |||
1339 | pAC->Pnmi.Port[PhysPortIndex].CounterHigh[CounterIndex] = 0; | ||
1340 | } | ||
1341 | |||
1342 | pAC->Pnmi.MacUpdatedFlag --; | ||
1343 | break; | ||
1344 | |||
1345 | case SK_PNMI_EVT_RLMT_PORT_UP: | ||
1346 | PhysPortIndex = (unsigned int)Param.Para32[0]; | ||
1347 | #ifdef DEBUG | ||
1348 | if (PhysPortIndex >= SK_MAX_MACS) { | ||
1349 | |||
1350 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, | ||
1351 | ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter" | ||
1352 | " wrong, PhysPortIndex=%d\n", PhysPortIndex)); | ||
1353 | |||
1354 | return (0); | ||
1355 | } | ||
1356 | #endif /* DEBUG */ | ||
1357 | |||
1358 | /* | ||
1359 | * Store a trap message in the trap buffer and generate an event for | ||
1360 | * user space applications with the SK_DRIVER_SENDEVENT macro. | ||
1361 | */ | ||
1362 | QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex); | ||
1363 | (void)SK_DRIVER_SENDEVENT(pAC, IoC); | ||
1364 | |||
1365 | /* Bugfix for XMAC errata (#10620)*/ | ||
1366 | if (MacType == SK_MAC_XMAC) { | ||
1367 | /* Add incremental difference to offset (#10620)*/ | ||
1368 | (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
1369 | XM_RXE_SHT_ERR, &Val32); | ||
1370 | |||
1371 | Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex]. | ||
1372 | CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32); | ||
1373 | pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] += | ||
1374 | Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark; | ||
1375 | } | ||
1376 | |||
1377 | /* Tell VctStatus() that a link was up meanwhile. */ | ||
1378 | pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK; | ||
1379 | break; | ||
1380 | |||
1381 | case SK_PNMI_EVT_RLMT_PORT_DOWN: | ||
1382 | PhysPortIndex = (unsigned int)Param.Para32[0]; | ||
1383 | |||
1384 | #ifdef DEBUG | ||
1385 | if (PhysPortIndex >= SK_MAX_MACS) { | ||
1386 | |||
1387 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, | ||
1388 | ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter" | ||
1389 | " wrong, PhysPortIndex=%d\n", PhysPortIndex)); | ||
1390 | |||
1391 | return (0); | ||
1392 | } | ||
1393 | #endif /* DEBUG */ | ||
1394 | |||
1395 | /* | ||
1396 | * Store a trap message in the trap buffer and generate an event for | ||
1397 | * user space applications with the SK_DRIVER_SENDEVENT macro. | ||
1398 | */ | ||
1399 | QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex); | ||
1400 | (void)SK_DRIVER_SENDEVENT(pAC, IoC); | ||
1401 | |||
1402 | /* Bugfix #10620 - get zero level for incremental difference */ | ||
1403 | if (MacType == SK_MAC_XMAC) { | ||
1404 | |||
1405 | (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
1406 | XM_RXE_SHT_ERR, &Val32); | ||
1407 | |||
1408 | pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark = | ||
1409 | (((SK_U64)pAC->Pnmi.Port[PhysPortIndex]. | ||
1410 | CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32); | ||
1411 | } | ||
1412 | break; | ||
1413 | |||
1414 | case SK_PNMI_EVT_RLMT_ACTIVE_DOWN: | ||
1415 | PhysPortIndex = (unsigned int)Param.Para32[0]; | ||
1416 | NetIndex = (SK_U32)Param.Para32[1]; | ||
1417 | |||
1418 | #ifdef DEBUG | ||
1419 | if (PhysPortIndex >= SK_MAX_MACS) { | ||
1420 | |||
1421 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, | ||
1422 | ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n", | ||
1423 | PhysPortIndex)); | ||
1424 | } | ||
1425 | |||
1426 | if (NetIndex >= pAC->Rlmt.NumNets) { | ||
1427 | |||
1428 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, | ||
1429 | ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n", | ||
1430 | NetIndex)); | ||
1431 | } | ||
1432 | #endif /* DEBUG */ | ||
1433 | |||
1434 | /* | ||
1435 | * For now, ignore event if NetIndex != 0. | ||
1436 | */ | ||
1437 | if (Param.Para32[1] != 0) { | ||
1438 | |||
1439 | return (0); | ||
1440 | } | ||
1441 | |||
1442 | /* | ||
1443 | * Nothing to do if port is already inactive | ||
1444 | */ | ||
1445 | if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { | ||
1446 | |||
1447 | return (0); | ||
1448 | } | ||
1449 | |||
1450 | /* | ||
1451 | * Update statistic counters to calculate new offset for the virtual | ||
1452 | * port and increment semaphore to indicate that an update was already | ||
1453 | * done. | ||
1454 | */ | ||
1455 | if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) != | ||
1456 | SK_PNMI_ERR_OK) { | ||
1457 | |||
1458 | SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return"); | ||
1459 | return (0); | ||
1460 | } | ||
1461 | pAC->Pnmi.MacUpdatedFlag ++; | ||
1462 | |||
1463 | /* | ||
1464 | * Calculate new counter offset for virtual port to grant continous | ||
1465 | * counting on port switches. The virtual port consists of all currently | ||
1466 | * active ports. The port down event indicates that a port is removed | ||
1467 | * from the virtual port. Therefore add the counter value of the removed | ||
1468 | * port to the CounterOffset for the virtual port to grant the same | ||
1469 | * counter value. | ||
1470 | */ | ||
1471 | for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX; | ||
1472 | CounterIndex ++) { | ||
1473 | |||
1474 | if (!StatAddr[CounterIndex][MacType].GetOffset) { | ||
1475 | |||
1476 | continue; | ||
1477 | } | ||
1478 | |||
1479 | Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex); | ||
1480 | |||
1481 | pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value; | ||
1482 | } | ||
1483 | |||
1484 | /* | ||
1485 | * Set port to inactive | ||
1486 | */ | ||
1487 | pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE; | ||
1488 | |||
1489 | pAC->Pnmi.MacUpdatedFlag --; | ||
1490 | break; | ||
1491 | |||
1492 | case SK_PNMI_EVT_RLMT_ACTIVE_UP: | ||
1493 | PhysPortIndex = (unsigned int)Param.Para32[0]; | ||
1494 | NetIndex = (SK_U32)Param.Para32[1]; | ||
1495 | |||
1496 | #ifdef DEBUG | ||
1497 | if (PhysPortIndex >= SK_MAX_MACS) { | ||
1498 | |||
1499 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, | ||
1500 | ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n", | ||
1501 | PhysPortIndex)); | ||
1502 | } | ||
1503 | |||
1504 | if (NetIndex >= pAC->Rlmt.NumNets) { | ||
1505 | |||
1506 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, | ||
1507 | ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n", | ||
1508 | NetIndex)); | ||
1509 | } | ||
1510 | #endif /* DEBUG */ | ||
1511 | |||
1512 | /* | ||
1513 | * For now, ignore event if NetIndex != 0. | ||
1514 | */ | ||
1515 | if (Param.Para32[1] != 0) { | ||
1516 | |||
1517 | return (0); | ||
1518 | } | ||
1519 | |||
1520 | /* | ||
1521 | * Nothing to do if port is already active | ||
1522 | */ | ||
1523 | if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { | ||
1524 | |||
1525 | return (0); | ||
1526 | } | ||
1527 | |||
1528 | /* | ||
1529 | * Statistic maintenance | ||
1530 | */ | ||
1531 | pAC->Pnmi.RlmtChangeCts ++; | ||
1532 | pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC)); | ||
1533 | |||
1534 | /* | ||
1535 | * Store a trap message in the trap buffer and generate an event for | ||
1536 | * user space applications with the SK_DRIVER_SENDEVENT macro. | ||
1537 | */ | ||
1538 | QueueRlmtNewMacTrap(pAC, PhysPortIndex); | ||
1539 | (void)SK_DRIVER_SENDEVENT(pAC, IoC); | ||
1540 | |||
1541 | /* | ||
1542 | * Update statistic counters to calculate new offset for the virtual | ||
1543 | * port and increment semaphore to indicate that an update was | ||
1544 | * already done. | ||
1545 | */ | ||
1546 | if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) != | ||
1547 | SK_PNMI_ERR_OK) { | ||
1548 | |||
1549 | SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return"); | ||
1550 | return (0); | ||
1551 | } | ||
1552 | pAC->Pnmi.MacUpdatedFlag ++; | ||
1553 | |||
1554 | /* | ||
1555 | * Calculate new counter offset for virtual port to grant continous | ||
1556 | * counting on port switches. A new port is added to the virtual port. | ||
1557 | * Therefore substract the counter value of the new port from the | ||
1558 | * CounterOffset for the virtual port to grant the same value. | ||
1559 | */ | ||
1560 | for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX; | ||
1561 | CounterIndex ++) { | ||
1562 | |||
1563 | if (!StatAddr[CounterIndex][MacType].GetOffset) { | ||
1564 | |||
1565 | continue; | ||
1566 | } | ||
1567 | |||
1568 | Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex); | ||
1569 | |||
1570 | pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value; | ||
1571 | } | ||
1572 | |||
1573 | /* Set port to active */ | ||
1574 | pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE; | ||
1575 | |||
1576 | pAC->Pnmi.MacUpdatedFlag --; | ||
1577 | break; | ||
1578 | |||
1579 | case SK_PNMI_EVT_RLMT_SEGMENTATION: | ||
1580 | /* | ||
1581 | * Para.Para32[0] contains the NetIndex. | ||
1582 | */ | ||
1583 | |||
1584 | /* | ||
1585 | * Store a trap message in the trap buffer and generate an event for | ||
1586 | * user space applications with the SK_DRIVER_SENDEVENT macro. | ||
1587 | */ | ||
1588 | QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION); | ||
1589 | (void)SK_DRIVER_SENDEVENT(pAC, IoC); | ||
1590 | break; | ||
1591 | |||
1592 | case SK_PNMI_EVT_RLMT_SET_NETS: | ||
1593 | /* | ||
1594 | * Param.Para32[0] contains the number of Nets. | ||
1595 | * Param.Para32[1] is reserved, contains -1. | ||
1596 | */ | ||
1597 | /* | ||
1598 | * Check number of nets | ||
1599 | */ | ||
1600 | MaxNetNumber = pAC->GIni.GIMacsFound; | ||
1601 | if (((unsigned int)Param.Para32[0] < 1) | ||
1602 | || ((unsigned int)Param.Para32[0] > MaxNetNumber)) { | ||
1603 | return (SK_PNMI_ERR_UNKNOWN_NET); | ||
1604 | } | ||
1605 | |||
1606 | if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */ | ||
1607 | pAC->Pnmi.DualNetActiveFlag = SK_FALSE; | ||
1608 | } | ||
1609 | else { /* dual net mode */ | ||
1610 | pAC->Pnmi.DualNetActiveFlag = SK_TRUE; | ||
1611 | } | ||
1612 | break; | ||
1613 | |||
1614 | case SK_PNMI_EVT_VCT_RESET: | ||
1615 | PhysPortIndex = Param.Para32[0]; | ||
1616 | pPrt = &pAC->GIni.GP[PhysPortIndex]; | ||
1617 | pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex]; | ||
1618 | |||
1619 | if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) { | ||
1620 | RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE); | ||
1621 | if (RetCode == 2) { | ||
1622 | /* | ||
1623 | * VCT test is still running. | ||
1624 | * Start VCT timer counter again. | ||
1625 | */ | ||
1626 | SK_MEMSET((char *) &Param, 0, sizeof(Param)); | ||
1627 | Param.Para32[0] = PhysPortIndex; | ||
1628 | Param.Para32[1] = -1; | ||
1629 | SkTimerStart(pAC, IoC, | ||
1630 | &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer, | ||
1631 | 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param); | ||
1632 | break; | ||
1633 | } | ||
1634 | pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING; | ||
1635 | pAC->Pnmi.VctStatus[PhysPortIndex] |= | ||
1636 | (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE); | ||
1637 | |||
1638 | /* Copy results for later use to PNMI struct. */ | ||
1639 | for (i = 0; i < 4; i++) { | ||
1640 | if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) { | ||
1641 | if ((pPrt->PMdiPairLen[i] > 35) && | ||
1642 | (pPrt->PMdiPairLen[i] < 0xff)) { | ||
1643 | pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH; | ||
1644 | } | ||
1645 | } | ||
1646 | if ((pPrt->PMdiPairLen[i] > 35) && | ||
1647 | (pPrt->PMdiPairLen[i] != 0xff)) { | ||
1648 | CableLength = 1000 * | ||
1649 | (((175 * pPrt->PMdiPairLen[i]) / 210) - 28); | ||
1650 | } | ||
1651 | else { | ||
1652 | CableLength = 0; | ||
1653 | } | ||
1654 | pVctBackupData->PMdiPairLen[i] = CableLength; | ||
1655 | pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i]; | ||
1656 | } | ||
1657 | |||
1658 | Param.Para32[0] = PhysPortIndex; | ||
1659 | Param.Para32[1] = -1; | ||
1660 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param); | ||
1661 | SkEventDispatcher(pAC, IoC); | ||
1662 | } | ||
1663 | |||
1664 | break; | ||
1665 | |||
1666 | default: | ||
1667 | break; | ||
1668 | } | ||
1669 | |||
1670 | SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return"); | ||
1671 | return (0); | ||
1672 | } | ||
1673 | |||
1674 | |||
1675 | /****************************************************************************** | ||
1676 | * | ||
1677 | * Private functions | ||
1678 | * | ||
1679 | */ | ||
1680 | |||
1681 | /***************************************************************************** | ||
1682 | * | ||
1683 | * PnmiVar - Gets, presets, and sets single OIDs | ||
1684 | * | ||
1685 | * Description: | ||
1686 | * Looks up the requested OID, calls the corresponding handler | ||
1687 | * function, and passes the parameters with the get, preset, or | ||
1688 | * set command. The function is called by SkGePnmiGetVar, | ||
1689 | * SkGePnmiPreSetVar, or SkGePnmiSetVar. | ||
1690 | * | ||
1691 | * Returns: | ||
1692 | * SK_PNMI_ERR_XXX. For details have a look at the description of the | ||
1693 | * calling functions. | ||
1694 | * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist | ||
1695 | */ | ||
1696 | PNMI_STATIC int PnmiVar( | ||
1697 | SK_AC *pAC, /* Pointer to adapter context */ | ||
1698 | SK_IOC IoC, /* IO context handle */ | ||
1699 | int Action, /* GET/PRESET/SET action */ | ||
1700 | SK_U32 Id, /* Object ID that is to be processed */ | ||
1701 | char *pBuf, /* Buffer used for the management data transfer */ | ||
1702 | unsigned int *pLen, /* Total length of pBuf management data */ | ||
1703 | SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */ | ||
1704 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
1705 | { | ||
1706 | unsigned int TableIndex; | ||
1707 | int Ret; | ||
1708 | |||
1709 | |||
1710 | if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) { | ||
1711 | |||
1712 | *pLen = 0; | ||
1713 | return (SK_PNMI_ERR_UNKNOWN_OID); | ||
1714 | } | ||
1715 | |||
1716 | /* Check NetIndex */ | ||
1717 | if (NetIndex >= pAC->Rlmt.NumNets) { | ||
1718 | return (SK_PNMI_ERR_UNKNOWN_NET); | ||
1719 | } | ||
1720 | |||
1721 | SK_PNMI_CHECKFLAGS("PnmiVar: On call"); | ||
1722 | |||
1723 | Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen, | ||
1724 | Instance, TableIndex, NetIndex); | ||
1725 | |||
1726 | SK_PNMI_CHECKFLAGS("PnmiVar: On return"); | ||
1727 | |||
1728 | return (Ret); | ||
1729 | } | ||
1730 | |||
1731 | /***************************************************************************** | ||
1732 | * | ||
1733 | * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA | ||
1734 | * | ||
1735 | * Description: | ||
1736 | * The return value of the function will also be stored in | ||
1737 | * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of | ||
1738 | * SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable, | ||
1739 | * checks which OIDs are able to set, and calls the handler function of | ||
1740 | * the OID to perform the set. The return value of the function will | ||
1741 | * also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the | ||
1742 | * minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called | ||
1743 | * by SkGePnmiPreSetStruct and SkGePnmiSetStruct. | ||
1744 | * | ||
1745 | * Returns: | ||
1746 | * SK_PNMI_ERR_XXX. The codes are described in the calling functions. | ||
1747 | * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist | ||
1748 | */ | ||
1749 | PNMI_STATIC int PnmiStruct( | ||
1750 | SK_AC *pAC, /* Pointer to adapter context */ | ||
1751 | SK_IOC IoC, /* IO context handle */ | ||
1752 | int Action, /* PRESET/SET action to be performed */ | ||
1753 | char *pBuf, /* Buffer used for the management data transfer */ | ||
1754 | unsigned int *pLen, /* Length of pBuf management data buffer */ | ||
1755 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
1756 | { | ||
1757 | int Ret; | ||
1758 | unsigned int TableIndex; | ||
1759 | unsigned int DstOffset; | ||
1760 | unsigned int Len; | ||
1761 | unsigned int InstanceNo; | ||
1762 | unsigned int InstanceCnt; | ||
1763 | SK_U32 Instance; | ||
1764 | SK_U32 Id; | ||
1765 | |||
1766 | |||
1767 | /* Check if the passed buffer has the right size */ | ||
1768 | if (*pLen < SK_PNMI_STRUCT_SIZE) { | ||
1769 | |||
1770 | /* Check if we can return the error within the buffer */ | ||
1771 | if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) { | ||
1772 | |||
1773 | SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT, | ||
1774 | (SK_U32)(-1)); | ||
1775 | } | ||
1776 | |||
1777 | *pLen = SK_PNMI_STRUCT_SIZE; | ||
1778 | return (SK_PNMI_ERR_TOO_SHORT); | ||
1779 | } | ||
1780 | |||
1781 | /* Check NetIndex */ | ||
1782 | if (NetIndex >= pAC->Rlmt.NumNets) { | ||
1783 | return (SK_PNMI_ERR_UNKNOWN_NET); | ||
1784 | } | ||
1785 | |||
1786 | SK_PNMI_CHECKFLAGS("PnmiStruct: On call"); | ||
1787 | |||
1788 | /* | ||
1789 | * Update the values of RLMT and SIRQ and increment semaphores to | ||
1790 | * indicate that an update was already done. | ||
1791 | */ | ||
1792 | if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) { | ||
1793 | |||
1794 | SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); | ||
1795 | *pLen = SK_PNMI_MIN_STRUCT_SIZE; | ||
1796 | return (Ret); | ||
1797 | } | ||
1798 | |||
1799 | if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) { | ||
1800 | |||
1801 | SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); | ||
1802 | *pLen = SK_PNMI_MIN_STRUCT_SIZE; | ||
1803 | return (Ret); | ||
1804 | } | ||
1805 | |||
1806 | pAC->Pnmi.RlmtUpdatedFlag ++; | ||
1807 | pAC->Pnmi.SirqUpdatedFlag ++; | ||
1808 | |||
1809 | /* Preset/Set values */ | ||
1810 | for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) { | ||
1811 | |||
1812 | if ((IdTable[TableIndex].Access != SK_PNMI_RW) && | ||
1813 | (IdTable[TableIndex].Access != SK_PNMI_WO)) { | ||
1814 | |||
1815 | continue; | ||
1816 | } | ||
1817 | |||
1818 | InstanceNo = IdTable[TableIndex].InstanceNo; | ||
1819 | Id = IdTable[TableIndex].Id; | ||
1820 | |||
1821 | for (InstanceCnt = 1; InstanceCnt <= InstanceNo; | ||
1822 | InstanceCnt ++) { | ||
1823 | |||
1824 | DstOffset = IdTable[TableIndex].Offset + | ||
1825 | (InstanceCnt - 1) * | ||
1826 | IdTable[TableIndex].StructSize; | ||
1827 | |||
1828 | /* | ||
1829 | * Because VPD multiple instance variables are | ||
1830 | * not setable we do not need to evaluate VPD | ||
1831 | * instances. Have a look to VPD instance | ||
1832 | * calculation in SkPnmiGetStruct(). | ||
1833 | */ | ||
1834 | Instance = (SK_U32)InstanceCnt; | ||
1835 | |||
1836 | /* | ||
1837 | * Evaluate needed buffer length | ||
1838 | */ | ||
1839 | Len = 0; | ||
1840 | Ret = IdTable[TableIndex].Func(pAC, IoC, | ||
1841 | SK_PNMI_GET, IdTable[TableIndex].Id, | ||
1842 | NULL, &Len, Instance, TableIndex, NetIndex); | ||
1843 | |||
1844 | if (Ret == SK_PNMI_ERR_UNKNOWN_INST) { | ||
1845 | |||
1846 | break; | ||
1847 | } | ||
1848 | if (Ret != SK_PNMI_ERR_TOO_SHORT) { | ||
1849 | |||
1850 | pAC->Pnmi.RlmtUpdatedFlag --; | ||
1851 | pAC->Pnmi.SirqUpdatedFlag --; | ||
1852 | |||
1853 | SK_PNMI_CHECKFLAGS("PnmiStruct: On return"); | ||
1854 | SK_PNMI_SET_STAT(pBuf, | ||
1855 | SK_PNMI_ERR_GENERAL, DstOffset); | ||
1856 | *pLen = SK_PNMI_MIN_STRUCT_SIZE; | ||
1857 | return (SK_PNMI_ERR_GENERAL); | ||
1858 | } | ||
1859 | if (Id == OID_SKGE_VPD_ACTION) { | ||
1860 | |||
1861 | switch (*(pBuf + DstOffset)) { | ||
1862 | |||
1863 | case SK_PNMI_VPD_CREATE: | ||
1864 | Len = 3 + *(pBuf + DstOffset + 3); | ||
1865 | break; | ||
1866 | |||
1867 | case SK_PNMI_VPD_DELETE: | ||
1868 | Len = 3; | ||
1869 | break; | ||
1870 | |||
1871 | default: | ||
1872 | Len = 1; | ||
1873 | break; | ||
1874 | } | ||
1875 | } | ||
1876 | |||
1877 | /* Call the OID handler function */ | ||
1878 | Ret = IdTable[TableIndex].Func(pAC, IoC, Action, | ||
1879 | IdTable[TableIndex].Id, pBuf + DstOffset, | ||
1880 | &Len, Instance, TableIndex, NetIndex); | ||
1881 | |||
1882 | if (Ret != SK_PNMI_ERR_OK) { | ||
1883 | |||
1884 | pAC->Pnmi.RlmtUpdatedFlag --; | ||
1885 | pAC->Pnmi.SirqUpdatedFlag --; | ||
1886 | |||
1887 | SK_PNMI_CHECKFLAGS("PnmiStruct: On return"); | ||
1888 | SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE, | ||
1889 | DstOffset); | ||
1890 | *pLen = SK_PNMI_MIN_STRUCT_SIZE; | ||
1891 | return (SK_PNMI_ERR_BAD_VALUE); | ||
1892 | } | ||
1893 | } | ||
1894 | } | ||
1895 | |||
1896 | pAC->Pnmi.RlmtUpdatedFlag --; | ||
1897 | pAC->Pnmi.SirqUpdatedFlag --; | ||
1898 | |||
1899 | SK_PNMI_CHECKFLAGS("PnmiStruct: On return"); | ||
1900 | SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1)); | ||
1901 | return (SK_PNMI_ERR_OK); | ||
1902 | } | ||
1903 | |||
1904 | /***************************************************************************** | ||
1905 | * | ||
1906 | * LookupId - Lookup an OID in the IdTable | ||
1907 | * | ||
1908 | * Description: | ||
1909 | * Scans the IdTable to find the table entry of an OID. | ||
1910 | * | ||
1911 | * Returns: | ||
1912 | * The table index or -1 if not found. | ||
1913 | */ | ||
1914 | PNMI_STATIC int LookupId( | ||
1915 | SK_U32 Id) /* Object identifier to be searched */ | ||
1916 | { | ||
1917 | int i; | ||
1918 | |||
1919 | for (i = 0; i < ID_TABLE_SIZE; i++) { | ||
1920 | |||
1921 | if (IdTable[i].Id == Id) { | ||
1922 | |||
1923 | return i; | ||
1924 | } | ||
1925 | } | ||
1926 | |||
1927 | return (-1); | ||
1928 | } | ||
1929 | |||
1930 | /***************************************************************************** | ||
1931 | * | ||
1932 | * OidStruct - Handler of OID_SKGE_ALL_DATA | ||
1933 | * | ||
1934 | * Description: | ||
1935 | * This OID performs a Get/Preset/SetStruct call and returns all data | ||
1936 | * in a SK_PNMI_STRUCT_DATA structure. | ||
1937 | * | ||
1938 | * Returns: | ||
1939 | * SK_PNMI_ERR_OK The request was successfully performed. | ||
1940 | * SK_PNMI_ERR_GENERAL A general severe internal error occured. | ||
1941 | * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain | ||
1942 | * the correct data (e.g. a 32bit value is | ||
1943 | * needed, but a 16 bit value was passed). | ||
1944 | * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid | ||
1945 | * value range. | ||
1946 | * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. | ||
1947 | * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't | ||
1948 | * exist (e.g. port instance 3 on a two port | ||
1949 | * adapter. | ||
1950 | */ | ||
1951 | PNMI_STATIC int OidStruct( | ||
1952 | SK_AC *pAC, /* Pointer to adapter context */ | ||
1953 | SK_IOC IoC, /* IO context handle */ | ||
1954 | int Action, /* GET/PRESET/SET action */ | ||
1955 | SK_U32 Id, /* Object ID that is to be processed */ | ||
1956 | char *pBuf, /* Buffer used for the management data transfer */ | ||
1957 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
1958 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
1959 | unsigned int TableIndex, /* Index to the Id table */ | ||
1960 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
1961 | { | ||
1962 | if (Id != OID_SKGE_ALL_DATA) { | ||
1963 | |||
1964 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003, | ||
1965 | SK_PNMI_ERR003MSG); | ||
1966 | |||
1967 | *pLen = 0; | ||
1968 | return (SK_PNMI_ERR_GENERAL); | ||
1969 | } | ||
1970 | |||
1971 | /* | ||
1972 | * Check instance. We only handle single instance variables | ||
1973 | */ | ||
1974 | if (Instance != (SK_U32)(-1) && Instance != 1) { | ||
1975 | |||
1976 | *pLen = 0; | ||
1977 | return (SK_PNMI_ERR_UNKNOWN_INST); | ||
1978 | } | ||
1979 | |||
1980 | switch (Action) { | ||
1981 | |||
1982 | case SK_PNMI_GET: | ||
1983 | return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex)); | ||
1984 | |||
1985 | case SK_PNMI_PRESET: | ||
1986 | return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex)); | ||
1987 | |||
1988 | case SK_PNMI_SET: | ||
1989 | return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex)); | ||
1990 | } | ||
1991 | |||
1992 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG); | ||
1993 | |||
1994 | *pLen = 0; | ||
1995 | return (SK_PNMI_ERR_GENERAL); | ||
1996 | } | ||
1997 | |||
1998 | /***************************************************************************** | ||
1999 | * | ||
2000 | * Perform - OID handler of OID_SKGE_ACTION | ||
2001 | * | ||
2002 | * Description: | ||
2003 | * None. | ||
2004 | * | ||
2005 | * Returns: | ||
2006 | * SK_PNMI_ERR_OK The request was successfully performed. | ||
2007 | * SK_PNMI_ERR_GENERAL A general severe internal error occured. | ||
2008 | * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain | ||
2009 | * the correct data (e.g. a 32bit value is | ||
2010 | * needed, but a 16 bit value was passed). | ||
2011 | * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid | ||
2012 | * value range. | ||
2013 | * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. | ||
2014 | * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't | ||
2015 | * exist (e.g. port instance 3 on a two port | ||
2016 | * adapter. | ||
2017 | */ | ||
2018 | PNMI_STATIC int Perform( | ||
2019 | SK_AC *pAC, /* Pointer to adapter context */ | ||
2020 | SK_IOC IoC, /* IO context handle */ | ||
2021 | int Action, /* GET/PRESET/SET action */ | ||
2022 | SK_U32 Id, /* Object ID that is to be processed */ | ||
2023 | char *pBuf, /* Buffer used for the management data transfer */ | ||
2024 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
2025 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
2026 | unsigned int TableIndex, /* Index to the Id table */ | ||
2027 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
2028 | { | ||
2029 | int Ret; | ||
2030 | SK_U32 ActionOp; | ||
2031 | |||
2032 | |||
2033 | /* | ||
2034 | * Check instance. We only handle single instance variables | ||
2035 | */ | ||
2036 | if (Instance != (SK_U32)(-1) && Instance != 1) { | ||
2037 | |||
2038 | *pLen = 0; | ||
2039 | return (SK_PNMI_ERR_UNKNOWN_INST); | ||
2040 | } | ||
2041 | |||
2042 | if (*pLen < sizeof(SK_U32)) { | ||
2043 | |||
2044 | *pLen = sizeof(SK_U32); | ||
2045 | return (SK_PNMI_ERR_TOO_SHORT); | ||
2046 | } | ||
2047 | |||
2048 | /* Check if a get should be performed */ | ||
2049 | if (Action == SK_PNMI_GET) { | ||
2050 | |||
2051 | /* A get is easy. We always return the same value */ | ||
2052 | ActionOp = (SK_U32)SK_PNMI_ACT_IDLE; | ||
2053 | SK_PNMI_STORE_U32(pBuf, ActionOp); | ||
2054 | *pLen = sizeof(SK_U32); | ||
2055 | |||
2056 | return (SK_PNMI_ERR_OK); | ||
2057 | } | ||
2058 | |||
2059 | /* Continue with PRESET/SET action */ | ||
2060 | if (*pLen > sizeof(SK_U32)) { | ||
2061 | |||
2062 | return (SK_PNMI_ERR_BAD_VALUE); | ||
2063 | } | ||
2064 | |||
2065 | /* Check if the command is a known one */ | ||
2066 | SK_PNMI_READ_U32(pBuf, ActionOp); | ||
2067 | if (*pLen > sizeof(SK_U32) || | ||
2068 | (ActionOp != SK_PNMI_ACT_IDLE && | ||
2069 | ActionOp != SK_PNMI_ACT_RESET && | ||
2070 | ActionOp != SK_PNMI_ACT_SELFTEST && | ||
2071 | ActionOp != SK_PNMI_ACT_RESETCNT)) { | ||
2072 | |||
2073 | *pLen = 0; | ||
2074 | return (SK_PNMI_ERR_BAD_VALUE); | ||
2075 | } | ||
2076 | |||
2077 | /* A preset ends here */ | ||
2078 | if (Action == SK_PNMI_PRESET) { | ||
2079 | |||
2080 | return (SK_PNMI_ERR_OK); | ||
2081 | } | ||
2082 | |||
2083 | switch (ActionOp) { | ||
2084 | |||
2085 | case SK_PNMI_ACT_IDLE: | ||
2086 | /* Nothing to do */ | ||
2087 | break; | ||
2088 | |||
2089 | case SK_PNMI_ACT_RESET: | ||
2090 | /* | ||
2091 | * Perform a driver reset or something that comes near | ||
2092 | * to this. | ||
2093 | */ | ||
2094 | Ret = SK_DRIVER_RESET(pAC, IoC); | ||
2095 | if (Ret != 0) { | ||
2096 | |||
2097 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005, | ||
2098 | SK_PNMI_ERR005MSG); | ||
2099 | |||
2100 | return (SK_PNMI_ERR_GENERAL); | ||
2101 | } | ||
2102 | break; | ||
2103 | |||
2104 | case SK_PNMI_ACT_SELFTEST: | ||
2105 | /* | ||
2106 | * Perform a driver selftest or something similar to this. | ||
2107 | * Currently this feature is not used and will probably | ||
2108 | * implemented in another way. | ||
2109 | */ | ||
2110 | Ret = SK_DRIVER_SELFTEST(pAC, IoC); | ||
2111 | pAC->Pnmi.TestResult = Ret; | ||
2112 | break; | ||
2113 | |||
2114 | case SK_PNMI_ACT_RESETCNT: | ||
2115 | /* Set all counters and timestamps to zero */ | ||
2116 | ResetCounter(pAC, IoC, NetIndex); | ||
2117 | break; | ||
2118 | |||
2119 | default: | ||
2120 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006, | ||
2121 | SK_PNMI_ERR006MSG); | ||
2122 | |||
2123 | return (SK_PNMI_ERR_GENERAL); | ||
2124 | } | ||
2125 | |||
2126 | return (SK_PNMI_ERR_OK); | ||
2127 | } | ||
2128 | |||
2129 | /***************************************************************************** | ||
2130 | * | ||
2131 | * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX | ||
2132 | * | ||
2133 | * Description: | ||
2134 | * Retrieves the statistic values of the virtual port (logical | ||
2135 | * index 0). Only special OIDs of NDIS are handled which consist | ||
2136 | * of a 32 bit instead of a 64 bit value. The OIDs are public | ||
2137 | * because perhaps some other platform can use them too. | ||
2138 | * | ||
2139 | * Returns: | ||
2140 | * SK_PNMI_ERR_OK The request was successfully performed. | ||
2141 | * SK_PNMI_ERR_GENERAL A general severe internal error occured. | ||
2142 | * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain | ||
2143 | * the correct data (e.g. a 32bit value is | ||
2144 | * needed, but a 16 bit value was passed). | ||
2145 | * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't | ||
2146 | * exist (e.g. port instance 3 on a two port | ||
2147 | * adapter. | ||
2148 | */ | ||
2149 | PNMI_STATIC int Mac8023Stat( | ||
2150 | SK_AC *pAC, /* Pointer to adapter context */ | ||
2151 | SK_IOC IoC, /* IO context handle */ | ||
2152 | int Action, /* GET/PRESET/SET action */ | ||
2153 | SK_U32 Id, /* Object ID that is to be processed */ | ||
2154 | char *pBuf, /* Buffer used for the management data transfer */ | ||
2155 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
2156 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
2157 | unsigned int TableIndex, /* Index to the Id table */ | ||
2158 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
2159 | { | ||
2160 | int Ret; | ||
2161 | SK_U64 StatVal; | ||
2162 | SK_U32 StatVal32; | ||
2163 | SK_BOOL Is64BitReq = SK_FALSE; | ||
2164 | |||
2165 | /* | ||
2166 | * Only the active Mac is returned | ||
2167 | */ | ||
2168 | if (Instance != (SK_U32)(-1) && Instance != 1) { | ||
2169 | |||
2170 | *pLen = 0; | ||
2171 | return (SK_PNMI_ERR_UNKNOWN_INST); | ||
2172 | } | ||
2173 | |||
2174 | /* | ||
2175 | * Check action type | ||
2176 | */ | ||
2177 | if (Action != SK_PNMI_GET) { | ||
2178 | |||
2179 | *pLen = 0; | ||
2180 | return (SK_PNMI_ERR_READ_ONLY); | ||
2181 | } | ||
2182 | |||
2183 | /* Check length */ | ||
2184 | switch (Id) { | ||
2185 | |||
2186 | case OID_802_3_PERMANENT_ADDRESS: | ||
2187 | case OID_802_3_CURRENT_ADDRESS: | ||
2188 | if (*pLen < sizeof(SK_MAC_ADDR)) { | ||
2189 | |||
2190 | *pLen = sizeof(SK_MAC_ADDR); | ||
2191 | return (SK_PNMI_ERR_TOO_SHORT); | ||
2192 | } | ||
2193 | break; | ||
2194 | |||
2195 | default: | ||
2196 | #ifndef SK_NDIS_64BIT_CTR | ||
2197 | if (*pLen < sizeof(SK_U32)) { | ||
2198 | *pLen = sizeof(SK_U32); | ||
2199 | return (SK_PNMI_ERR_TOO_SHORT); | ||
2200 | } | ||
2201 | |||
2202 | #else /* SK_NDIS_64BIT_CTR */ | ||
2203 | |||
2204 | /* for compatibility, at least 32bit are required for OID */ | ||
2205 | if (*pLen < sizeof(SK_U32)) { | ||
2206 | /* | ||
2207 | * but indicate handling for 64bit values, | ||
2208 | * if insufficient space is provided | ||
2209 | */ | ||
2210 | *pLen = sizeof(SK_U64); | ||
2211 | return (SK_PNMI_ERR_TOO_SHORT); | ||
2212 | } | ||
2213 | |||
2214 | Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE; | ||
2215 | #endif /* SK_NDIS_64BIT_CTR */ | ||
2216 | break; | ||
2217 | } | ||
2218 | |||
2219 | /* | ||
2220 | * Update all statistics, because we retrieve virtual MAC, which | ||
2221 | * consists of multiple physical statistics and increment semaphore | ||
2222 | * to indicate that an update was already done. | ||
2223 | */ | ||
2224 | Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1); | ||
2225 | if ( Ret != SK_PNMI_ERR_OK) { | ||
2226 | |||
2227 | *pLen = 0; | ||
2228 | return (Ret); | ||
2229 | } | ||
2230 | pAC->Pnmi.MacUpdatedFlag ++; | ||
2231 | |||
2232 | /* | ||
2233 | * Get value (MAC Index 0 identifies the virtual MAC) | ||
2234 | */ | ||
2235 | switch (Id) { | ||
2236 | |||
2237 | case OID_802_3_PERMANENT_ADDRESS: | ||
2238 | CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress); | ||
2239 | *pLen = sizeof(SK_MAC_ADDR); | ||
2240 | break; | ||
2241 | |||
2242 | case OID_802_3_CURRENT_ADDRESS: | ||
2243 | CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress); | ||
2244 | *pLen = sizeof(SK_MAC_ADDR); | ||
2245 | break; | ||
2246 | |||
2247 | default: | ||
2248 | StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex); | ||
2249 | |||
2250 | /* by default 32bit values are evaluated */ | ||
2251 | if (!Is64BitReq) { | ||
2252 | StatVal32 = (SK_U32)StatVal; | ||
2253 | SK_PNMI_STORE_U32(pBuf, StatVal32); | ||
2254 | *pLen = sizeof(SK_U32); | ||
2255 | } | ||
2256 | else { | ||
2257 | SK_PNMI_STORE_U64(pBuf, StatVal); | ||
2258 | *pLen = sizeof(SK_U64); | ||
2259 | } | ||
2260 | break; | ||
2261 | } | ||
2262 | |||
2263 | pAC->Pnmi.MacUpdatedFlag --; | ||
2264 | |||
2265 | return (SK_PNMI_ERR_OK); | ||
2266 | } | ||
2267 | |||
2268 | /***************************************************************************** | ||
2269 | * | ||
2270 | * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX | ||
2271 | * | ||
2272 | * Description: | ||
2273 | * Retrieves the MAC statistic data. | ||
2274 | * | ||
2275 | * Returns: | ||
2276 | * SK_PNMI_ERR_OK The request was successfully performed. | ||
2277 | * SK_PNMI_ERR_GENERAL A general severe internal error occured. | ||
2278 | * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain | ||
2279 | * the correct data (e.g. a 32bit value is | ||
2280 | * needed, but a 16 bit value was passed). | ||
2281 | * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't | ||
2282 | * exist (e.g. port instance 3 on a two port | ||
2283 | * adapter. | ||
2284 | */ | ||
2285 | PNMI_STATIC int MacPrivateStat( | ||
2286 | SK_AC *pAC, /* Pointer to adapter context */ | ||
2287 | SK_IOC IoC, /* IO context handle */ | ||
2288 | int Action, /* GET/PRESET/SET action */ | ||
2289 | SK_U32 Id, /* Object ID that is to be processed */ | ||
2290 | char *pBuf, /* Buffer used for the management data transfer */ | ||
2291 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
2292 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
2293 | unsigned int TableIndex, /* Index to the Id table */ | ||
2294 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
2295 | { | ||
2296 | unsigned int LogPortMax; | ||
2297 | unsigned int LogPortIndex; | ||
2298 | unsigned int PhysPortMax; | ||
2299 | unsigned int Limit; | ||
2300 | unsigned int Offset; | ||
2301 | int MacType; | ||
2302 | int Ret; | ||
2303 | SK_U64 StatVal; | ||
2304 | |||
2305 | |||
2306 | |||
2307 | /* Calculate instance if wished. MAC index 0 is the virtual MAC */ | ||
2308 | PhysPortMax = pAC->GIni.GIMacsFound; | ||
2309 | LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); | ||
2310 | |||
2311 | MacType = pAC->GIni.GIMacType; | ||
2312 | |||
2313 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */ | ||
2314 | LogPortMax--; | ||
2315 | } | ||
2316 | |||
2317 | if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */ | ||
2318 | /* Check instance range */ | ||
2319 | if ((Instance < 1) || (Instance > LogPortMax)) { | ||
2320 | |||
2321 | *pLen = 0; | ||
2322 | return (SK_PNMI_ERR_UNKNOWN_INST); | ||
2323 | } | ||
2324 | LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance); | ||
2325 | Limit = LogPortIndex + 1; | ||
2326 | } | ||
2327 | |||
2328 | else { /* Instance == (SK_U32)(-1), get all Instances of that OID */ | ||
2329 | |||
2330 | LogPortIndex = 0; | ||
2331 | Limit = LogPortMax; | ||
2332 | } | ||
2333 | |||
2334 | /* Check action */ | ||
2335 | if (Action != SK_PNMI_GET) { | ||
2336 | |||
2337 | *pLen = 0; | ||
2338 | return (SK_PNMI_ERR_READ_ONLY); | ||
2339 | } | ||
2340 | |||
2341 | /* Check length */ | ||
2342 | if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) { | ||
2343 | |||
2344 | *pLen = (Limit - LogPortIndex) * sizeof(SK_U64); | ||
2345 | return (SK_PNMI_ERR_TOO_SHORT); | ||
2346 | } | ||
2347 | |||
2348 | /* | ||
2349 | * Update MAC statistic and increment semaphore to indicate that | ||
2350 | * an update was already done. | ||
2351 | */ | ||
2352 | Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1); | ||
2353 | if (Ret != SK_PNMI_ERR_OK) { | ||
2354 | |||
2355 | *pLen = 0; | ||
2356 | return (Ret); | ||
2357 | } | ||
2358 | pAC->Pnmi.MacUpdatedFlag ++; | ||
2359 | |||
2360 | /* Get value */ | ||
2361 | Offset = 0; | ||
2362 | for (; LogPortIndex < Limit; LogPortIndex ++) { | ||
2363 | |||
2364 | switch (Id) { | ||
2365 | |||
2366 | /* XXX not yet implemented due to XMAC problems | ||
2367 | case OID_SKGE_STAT_TX_UTIL: | ||
2368 | return (SK_PNMI_ERR_GENERAL); | ||
2369 | */ | ||
2370 | /* XXX not yet implemented due to XMAC problems | ||
2371 | case OID_SKGE_STAT_RX_UTIL: | ||
2372 | return (SK_PNMI_ERR_GENERAL); | ||
2373 | */ | ||
2374 | case OID_SKGE_STAT_RX: | ||
2375 | if (MacType == SK_MAC_GMAC) { | ||
2376 | StatVal = | ||
2377 | GetStatVal(pAC, IoC, LogPortIndex, | ||
2378 | SK_PNMI_HRX_BROADCAST, NetIndex) + | ||
2379 | GetStatVal(pAC, IoC, LogPortIndex, | ||
2380 | SK_PNMI_HRX_MULTICAST, NetIndex) + | ||
2381 | GetStatVal(pAC, IoC, LogPortIndex, | ||
2382 | SK_PNMI_HRX_UNICAST, NetIndex) + | ||
2383 | GetStatVal(pAC, IoC, LogPortIndex, | ||
2384 | SK_PNMI_HRX_UNDERSIZE, NetIndex); | ||
2385 | } | ||
2386 | else { | ||
2387 | StatVal = GetStatVal(pAC, IoC, LogPortIndex, | ||
2388 | IdTable[TableIndex].Param, NetIndex); | ||
2389 | } | ||
2390 | break; | ||
2391 | |||
2392 | case OID_SKGE_STAT_TX: | ||
2393 | if (MacType == SK_MAC_GMAC) { | ||
2394 | StatVal = | ||
2395 | GetStatVal(pAC, IoC, LogPortIndex, | ||
2396 | SK_PNMI_HTX_BROADCAST, NetIndex) + | ||
2397 | GetStatVal(pAC, IoC, LogPortIndex, | ||
2398 | SK_PNMI_HTX_MULTICAST, NetIndex) + | ||
2399 | GetStatVal(pAC, IoC, LogPortIndex, | ||
2400 | SK_PNMI_HTX_UNICAST, NetIndex); | ||
2401 | } | ||
2402 | else { | ||
2403 | StatVal = GetStatVal(pAC, IoC, LogPortIndex, | ||
2404 | IdTable[TableIndex].Param, NetIndex); | ||
2405 | } | ||
2406 | break; | ||
2407 | |||
2408 | default: | ||
2409 | StatVal = GetStatVal(pAC, IoC, LogPortIndex, | ||
2410 | IdTable[TableIndex].Param, NetIndex); | ||
2411 | } | ||
2412 | SK_PNMI_STORE_U64(pBuf + Offset, StatVal); | ||
2413 | |||
2414 | Offset += sizeof(SK_U64); | ||
2415 | } | ||
2416 | *pLen = Offset; | ||
2417 | |||
2418 | pAC->Pnmi.MacUpdatedFlag --; | ||
2419 | |||
2420 | return (SK_PNMI_ERR_OK); | ||
2421 | } | ||
2422 | |||
2423 | /***************************************************************************** | ||
2424 | * | ||
2425 | * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR | ||
2426 | * | ||
2427 | * Description: | ||
2428 | * Get/Presets/Sets the current and factory MAC address. The MAC | ||
2429 | * address of the virtual port, which is reported to the OS, may | ||
2430 | * not be changed, but the physical ones. A set to the virtual port | ||
2431 | * will be ignored. No error should be reported because otherwise | ||
2432 | * a multiple instance set (-1) would always fail. | ||
2433 | * | ||
2434 | * Returns: | ||
2435 | * SK_PNMI_ERR_OK The request was successfully performed. | ||
2436 | * SK_PNMI_ERR_GENERAL A general severe internal error occured. | ||
2437 | * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain | ||
2438 | * the correct data (e.g. a 32bit value is | ||
2439 | * needed, but a 16 bit value was passed). | ||
2440 | * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid | ||
2441 | * value range. | ||
2442 | * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. | ||
2443 | * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't | ||
2444 | * exist (e.g. port instance 3 on a two port | ||
2445 | * adapter. | ||
2446 | */ | ||
2447 | PNMI_STATIC int Addr( | ||
2448 | SK_AC *pAC, /* Pointer to adapter context */ | ||
2449 | SK_IOC IoC, /* IO context handle */ | ||
2450 | int Action, /* GET/PRESET/SET action */ | ||
2451 | SK_U32 Id, /* Object ID that is to be processed */ | ||
2452 | char *pBuf, /* Buffer used for the management data transfer */ | ||
2453 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
2454 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
2455 | unsigned int TableIndex, /* Index to the Id table */ | ||
2456 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
2457 | { | ||
2458 | int Ret; | ||
2459 | unsigned int LogPortMax; | ||
2460 | unsigned int PhysPortMax; | ||
2461 | unsigned int LogPortIndex; | ||
2462 | unsigned int PhysPortIndex; | ||
2463 | unsigned int Limit; | ||
2464 | unsigned int Offset = 0; | ||
2465 | |||
2466 | /* | ||
2467 | * Calculate instance if wished. MAC index 0 is the virtual | ||
2468 | * MAC. | ||
2469 | */ | ||
2470 | PhysPortMax = pAC->GIni.GIMacsFound; | ||
2471 | LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); | ||
2472 | |||
2473 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */ | ||
2474 | LogPortMax--; | ||
2475 | } | ||
2476 | |||
2477 | if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */ | ||
2478 | /* Check instance range */ | ||
2479 | if ((Instance < 1) || (Instance > LogPortMax)) { | ||
2480 | |||
2481 | *pLen = 0; | ||
2482 | return (SK_PNMI_ERR_UNKNOWN_INST); | ||
2483 | } | ||
2484 | LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance); | ||
2485 | Limit = LogPortIndex + 1; | ||
2486 | } | ||
2487 | else { /* Instance == (SK_U32)(-1), get all Instances of that OID */ | ||
2488 | |||
2489 | LogPortIndex = 0; | ||
2490 | Limit = LogPortMax; | ||
2491 | } | ||
2492 | |||
2493 | /* | ||
2494 | * Perform Action | ||
2495 | */ | ||
2496 | if (Action == SK_PNMI_GET) { | ||
2497 | |||
2498 | /* Check length */ | ||
2499 | if (*pLen < (Limit - LogPortIndex) * 6) { | ||
2500 | |||
2501 | *pLen = (Limit - LogPortIndex) * 6; | ||
2502 | return (SK_PNMI_ERR_TOO_SHORT); | ||
2503 | } | ||
2504 | |||
2505 | /* | ||
2506 | * Get value | ||
2507 | */ | ||
2508 | for (; LogPortIndex < Limit; LogPortIndex ++) { | ||
2509 | |||
2510 | switch (Id) { | ||
2511 | |||
2512 | case OID_SKGE_PHYS_CUR_ADDR: | ||
2513 | if (LogPortIndex == 0) { | ||
2514 | CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress); | ||
2515 | } | ||
2516 | else { | ||
2517 | PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); | ||
2518 | |||
2519 | CopyMac(pBuf + Offset, | ||
2520 | &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress); | ||
2521 | } | ||
2522 | Offset += 6; | ||
2523 | break; | ||
2524 | |||
2525 | case OID_SKGE_PHYS_FAC_ADDR: | ||
2526 | if (LogPortIndex == 0) { | ||
2527 | CopyMac(pBuf + Offset, | ||
2528 | &pAC->Addr.Net[NetIndex].PermanentMacAddress); | ||
2529 | } | ||
2530 | else { | ||
2531 | PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( | ||
2532 | pAC, LogPortIndex); | ||
2533 | |||
2534 | CopyMac(pBuf + Offset, | ||
2535 | &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress); | ||
2536 | } | ||
2537 | Offset += 6; | ||
2538 | break; | ||
2539 | |||
2540 | default: | ||
2541 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008, | ||
2542 | SK_PNMI_ERR008MSG); | ||
2543 | |||
2544 | *pLen = 0; | ||
2545 | return (SK_PNMI_ERR_GENERAL); | ||
2546 | } | ||
2547 | } | ||
2548 | |||
2549 | *pLen = Offset; | ||
2550 | } | ||
2551 | else { | ||
2552 | /* | ||
2553 | * The logical MAC address may not be changed only | ||
2554 | * the physical ones | ||
2555 | */ | ||
2556 | if (Id == OID_SKGE_PHYS_FAC_ADDR) { | ||
2557 | |||
2558 | *pLen = 0; | ||
2559 | return (SK_PNMI_ERR_READ_ONLY); | ||
2560 | } | ||
2561 | |||
2562 | /* | ||
2563 | * Only the current address may be changed | ||
2564 | */ | ||
2565 | if (Id != OID_SKGE_PHYS_CUR_ADDR) { | ||
2566 | |||
2567 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009, | ||
2568 | SK_PNMI_ERR009MSG); | ||
2569 | |||
2570 | *pLen = 0; | ||
2571 | return (SK_PNMI_ERR_GENERAL); | ||
2572 | } | ||
2573 | |||
2574 | /* Check length */ | ||
2575 | if (*pLen < (Limit - LogPortIndex) * 6) { | ||
2576 | |||
2577 | *pLen = (Limit - LogPortIndex) * 6; | ||
2578 | return (SK_PNMI_ERR_TOO_SHORT); | ||
2579 | } | ||
2580 | if (*pLen > (Limit - LogPortIndex) * 6) { | ||
2581 | |||
2582 | *pLen = 0; | ||
2583 | return (SK_PNMI_ERR_BAD_VALUE); | ||
2584 | } | ||
2585 | |||
2586 | /* | ||
2587 | * Check Action | ||
2588 | */ | ||
2589 | if (Action == SK_PNMI_PRESET) { | ||
2590 | |||
2591 | *pLen = 0; | ||
2592 | return (SK_PNMI_ERR_OK); | ||
2593 | } | ||
2594 | |||
2595 | /* | ||
2596 | * Set OID_SKGE_MAC_CUR_ADDR | ||
2597 | */ | ||
2598 | for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) { | ||
2599 | |||
2600 | /* | ||
2601 | * A set to virtual port and set of broadcast | ||
2602 | * address will be ignored | ||
2603 | */ | ||
2604 | if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset, | ||
2605 | "\xff\xff\xff\xff\xff\xff", 6) == 0) { | ||
2606 | |||
2607 | continue; | ||
2608 | } | ||
2609 | |||
2610 | PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, | ||
2611 | LogPortIndex); | ||
2612 | |||
2613 | Ret = SkAddrOverride(pAC, IoC, PhysPortIndex, | ||
2614 | (SK_MAC_ADDR *)(pBuf + Offset), | ||
2615 | (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS : | ||
2616 | SK_ADDR_PHYSICAL_ADDRESS)); | ||
2617 | if (Ret != SK_ADDR_OVERRIDE_SUCCESS) { | ||
2618 | |||
2619 | return (SK_PNMI_ERR_GENERAL); | ||
2620 | } | ||
2621 | } | ||
2622 | *pLen = Offset; | ||
2623 | } | ||
2624 | |||
2625 | return (SK_PNMI_ERR_OK); | ||
2626 | } | ||
2627 | |||
2628 | /***************************************************************************** | ||
2629 | * | ||
2630 | * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX | ||
2631 | * | ||
2632 | * Description: | ||
2633 | * Retrieves the statistic values of the CSUM module. The CSUM data | ||
2634 | * structure must be available in the SK_AC even if the CSUM module | ||
2635 | * is not included, because PNMI reads the statistic data from the | ||
2636 | * CSUM part of SK_AC directly. | ||
2637 | * | ||
2638 | * Returns: | ||
2639 | * SK_PNMI_ERR_OK The request was successfully performed. | ||
2640 | * SK_PNMI_ERR_GENERAL A general severe internal error occured. | ||
2641 | * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain | ||
2642 | * the correct data (e.g. a 32bit value is | ||
2643 | * needed, but a 16 bit value was passed). | ||
2644 | * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't | ||
2645 | * exist (e.g. port instance 3 on a two port | ||
2646 | * adapter. | ||
2647 | */ | ||
2648 | PNMI_STATIC int CsumStat( | ||
2649 | SK_AC *pAC, /* Pointer to adapter context */ | ||
2650 | SK_IOC IoC, /* IO context handle */ | ||
2651 | int Action, /* GET/PRESET/SET action */ | ||
2652 | SK_U32 Id, /* Object ID that is to be processed */ | ||
2653 | char *pBuf, /* Buffer used for the management data transfer */ | ||
2654 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
2655 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
2656 | unsigned int TableIndex, /* Index to the Id table */ | ||
2657 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
2658 | { | ||
2659 | unsigned int Index; | ||
2660 | unsigned int Limit; | ||
2661 | unsigned int Offset = 0; | ||
2662 | SK_U64 StatVal; | ||
2663 | |||
2664 | |||
2665 | /* | ||
2666 | * Calculate instance if wished | ||
2667 | */ | ||
2668 | if (Instance != (SK_U32)(-1)) { | ||
2669 | |||
2670 | if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) { | ||
2671 | |||
2672 | *pLen = 0; | ||
2673 | return (SK_PNMI_ERR_UNKNOWN_INST); | ||
2674 | } | ||
2675 | Index = (unsigned int)Instance - 1; | ||
2676 | Limit = Index + 1; | ||
2677 | } | ||
2678 | else { | ||
2679 | Index = 0; | ||
2680 | Limit = SKCS_NUM_PROTOCOLS; | ||
2681 | } | ||
2682 | |||
2683 | /* | ||
2684 | * Check action | ||
2685 | */ | ||
2686 | if (Action != SK_PNMI_GET) { | ||
2687 | |||
2688 | *pLen = 0; | ||
2689 | return (SK_PNMI_ERR_READ_ONLY); | ||
2690 | } | ||
2691 | |||
2692 | /* Check length */ | ||
2693 | if (*pLen < (Limit - Index) * sizeof(SK_U64)) { | ||
2694 | |||
2695 | *pLen = (Limit - Index) * sizeof(SK_U64); | ||
2696 | return (SK_PNMI_ERR_TOO_SHORT); | ||
2697 | } | ||
2698 | |||
2699 | /* | ||
2700 | * Get value | ||
2701 | */ | ||
2702 | for (; Index < Limit; Index ++) { | ||
2703 | |||
2704 | switch (Id) { | ||
2705 | |||
2706 | case OID_SKGE_CHKSM_RX_OK_CTS: | ||
2707 | StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts; | ||
2708 | break; | ||
2709 | |||
2710 | case OID_SKGE_CHKSM_RX_UNABLE_CTS: | ||
2711 | StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts; | ||
2712 | break; | ||
2713 | |||
2714 | case OID_SKGE_CHKSM_RX_ERR_CTS: | ||
2715 | StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts; | ||
2716 | break; | ||
2717 | |||
2718 | case OID_SKGE_CHKSM_TX_OK_CTS: | ||
2719 | StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts; | ||
2720 | break; | ||
2721 | |||
2722 | case OID_SKGE_CHKSM_TX_UNABLE_CTS: | ||
2723 | StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts; | ||
2724 | break; | ||
2725 | |||
2726 | default: | ||
2727 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010, | ||
2728 | SK_PNMI_ERR010MSG); | ||
2729 | |||
2730 | *pLen = 0; | ||
2731 | return (SK_PNMI_ERR_GENERAL); | ||
2732 | } | ||
2733 | |||
2734 | SK_PNMI_STORE_U64(pBuf + Offset, StatVal); | ||
2735 | Offset += sizeof(SK_U64); | ||
2736 | } | ||
2737 | |||
2738 | /* | ||
2739 | * Store used buffer space | ||
2740 | */ | ||
2741 | *pLen = Offset; | ||
2742 | |||
2743 | return (SK_PNMI_ERR_OK); | ||
2744 | } | ||
2745 | |||
2746 | /***************************************************************************** | ||
2747 | * | ||
2748 | * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX | ||
2749 | * | ||
2750 | * Description: | ||
2751 | * Retrieves the statistic values of the I2C module, which handles | ||
2752 | * the temperature and voltage sensors. | ||
2753 | * | ||
2754 | * Returns: | ||
2755 | * SK_PNMI_ERR_OK The request was successfully performed. | ||
2756 | * SK_PNMI_ERR_GENERAL A general severe internal error occured. | ||
2757 | * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain | ||
2758 | * the correct data (e.g. a 32bit value is | ||
2759 | * needed, but a 16 bit value was passed). | ||
2760 | * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't | ||
2761 | * exist (e.g. port instance 3 on a two port | ||
2762 | * adapter. | ||
2763 | */ | ||
2764 | PNMI_STATIC int SensorStat( | ||
2765 | SK_AC *pAC, /* Pointer to adapter context */ | ||
2766 | SK_IOC IoC, /* IO context handle */ | ||
2767 | int Action, /* GET/PRESET/SET action */ | ||
2768 | SK_U32 Id, /* Object ID that is to be processed */ | ||
2769 | char *pBuf, /* Buffer used for the management data transfer */ | ||
2770 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
2771 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
2772 | unsigned int TableIndex, /* Index to the Id table */ | ||
2773 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
2774 | { | ||
2775 | unsigned int i; | ||
2776 | unsigned int Index; | ||
2777 | unsigned int Limit; | ||
2778 | unsigned int Offset; | ||
2779 | unsigned int Len; | ||
2780 | SK_U32 Val32; | ||
2781 | SK_U64 Val64; | ||
2782 | |||
2783 | |||
2784 | /* | ||
2785 | * Calculate instance if wished | ||
2786 | */ | ||
2787 | if ((Instance != (SK_U32)(-1))) { | ||
2788 | |||
2789 | if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) { | ||
2790 | |||
2791 | *pLen = 0; | ||
2792 | return (SK_PNMI_ERR_UNKNOWN_INST); | ||
2793 | } | ||
2794 | |||
2795 | Index = (unsigned int)Instance -1; | ||
2796 | Limit = (unsigned int)Instance; | ||
2797 | } | ||
2798 | else { | ||
2799 | Index = 0; | ||
2800 | Limit = (unsigned int) pAC->I2c.MaxSens; | ||
2801 | } | ||
2802 | |||
2803 | /* | ||
2804 | * Check action | ||
2805 | */ | ||
2806 | if (Action != SK_PNMI_GET) { | ||
2807 | |||
2808 | *pLen = 0; | ||
2809 | return (SK_PNMI_ERR_READ_ONLY); | ||
2810 | } | ||
2811 | |||
2812 | /* Check length */ | ||
2813 | switch (Id) { | ||
2814 | |||
2815 | case OID_SKGE_SENSOR_VALUE: | ||
2816 | case OID_SKGE_SENSOR_WAR_THRES_LOW: | ||
2817 | case OID_SKGE_SENSOR_WAR_THRES_UPP: | ||
2818 | case OID_SKGE_SENSOR_ERR_THRES_LOW: | ||
2819 | case OID_SKGE_SENSOR_ERR_THRES_UPP: | ||
2820 | if (*pLen < (Limit - Index) * sizeof(SK_U32)) { | ||
2821 | |||
2822 | *pLen = (Limit - Index) * sizeof(SK_U32); | ||
2823 | return (SK_PNMI_ERR_TOO_SHORT); | ||
2824 | } | ||
2825 | break; | ||
2826 | |||
2827 | case OID_SKGE_SENSOR_DESCR: | ||
2828 | for (Offset = 0, i = Index; i < Limit; i ++) { | ||
2829 | |||
2830 | Len = (unsigned int) | ||
2831 | SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1; | ||
2832 | if (Len >= SK_PNMI_STRINGLEN2) { | ||
2833 | |||
2834 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011, | ||
2835 | SK_PNMI_ERR011MSG); | ||
2836 | |||
2837 | *pLen = 0; | ||
2838 | return (SK_PNMI_ERR_GENERAL); | ||
2839 | } | ||
2840 | Offset += Len; | ||
2841 | } | ||
2842 | if (*pLen < Offset) { | ||
2843 | |||
2844 | *pLen = Offset; | ||
2845 | return (SK_PNMI_ERR_TOO_SHORT); | ||
2846 | } | ||
2847 | break; | ||
2848 | |||
2849 | case OID_SKGE_SENSOR_INDEX: | ||
2850 | case OID_SKGE_SENSOR_TYPE: | ||
2851 | case OID_SKGE_SENSOR_STATUS: | ||
2852 | if (*pLen < Limit - Index) { | ||
2853 | |||
2854 | *pLen = Limit - Index; | ||
2855 | return (SK_PNMI_ERR_TOO_SHORT); | ||
2856 | } | ||
2857 | break; | ||
2858 | |||
2859 | case OID_SKGE_SENSOR_WAR_CTS: | ||
2860 | case OID_SKGE_SENSOR_WAR_TIME: | ||
2861 | case OID_SKGE_SENSOR_ERR_CTS: | ||
2862 | case OID_SKGE_SENSOR_ERR_TIME: | ||
2863 | if (*pLen < (Limit - Index) * sizeof(SK_U64)) { | ||
2864 | |||
2865 | *pLen = (Limit - Index) * sizeof(SK_U64); | ||
2866 | return (SK_PNMI_ERR_TOO_SHORT); | ||
2867 | } | ||
2868 | break; | ||
2869 | |||
2870 | default: | ||
2871 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012, | ||
2872 | SK_PNMI_ERR012MSG); | ||
2873 | |||
2874 | *pLen = 0; | ||
2875 | return (SK_PNMI_ERR_GENERAL); | ||
2876 | |||
2877 | } | ||
2878 | |||
2879 | /* | ||
2880 | * Get value | ||
2881 | */ | ||
2882 | for (Offset = 0; Index < Limit; Index ++) { | ||
2883 | |||
2884 | switch (Id) { | ||
2885 | |||
2886 | case OID_SKGE_SENSOR_INDEX: | ||
2887 | *(pBuf + Offset) = (char)Index; | ||
2888 | Offset += sizeof(char); | ||
2889 | break; | ||
2890 | |||
2891 | case OID_SKGE_SENSOR_DESCR: | ||
2892 | Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc); | ||
2893 | SK_MEMCPY(pBuf + Offset + 1, | ||
2894 | pAC->I2c.SenTable[Index].SenDesc, Len); | ||
2895 | *(pBuf + Offset) = (char)Len; | ||
2896 | Offset += Len + 1; | ||
2897 | break; | ||
2898 | |||
2899 | case OID_SKGE_SENSOR_TYPE: | ||
2900 | *(pBuf + Offset) = | ||
2901 | (char)pAC->I2c.SenTable[Index].SenType; | ||
2902 | Offset += sizeof(char); | ||
2903 | break; | ||
2904 | |||
2905 | case OID_SKGE_SENSOR_VALUE: | ||
2906 | Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue; | ||
2907 | SK_PNMI_STORE_U32(pBuf + Offset, Val32); | ||
2908 | Offset += sizeof(SK_U32); | ||
2909 | break; | ||
2910 | |||
2911 | case OID_SKGE_SENSOR_WAR_THRES_LOW: | ||
2912 | Val32 = (SK_U32)pAC->I2c.SenTable[Index]. | ||
2913 | SenThreWarnLow; | ||
2914 | SK_PNMI_STORE_U32(pBuf + Offset, Val32); | ||
2915 | Offset += sizeof(SK_U32); | ||
2916 | break; | ||
2917 | |||
2918 | case OID_SKGE_SENSOR_WAR_THRES_UPP: | ||
2919 | Val32 = (SK_U32)pAC->I2c.SenTable[Index]. | ||
2920 | SenThreWarnHigh; | ||
2921 | SK_PNMI_STORE_U32(pBuf + Offset, Val32); | ||
2922 | Offset += sizeof(SK_U32); | ||
2923 | break; | ||
2924 | |||
2925 | case OID_SKGE_SENSOR_ERR_THRES_LOW: | ||
2926 | Val32 = (SK_U32)pAC->I2c.SenTable[Index]. | ||
2927 | SenThreErrLow; | ||
2928 | SK_PNMI_STORE_U32(pBuf + Offset, Val32); | ||
2929 | Offset += sizeof(SK_U32); | ||
2930 | break; | ||
2931 | |||
2932 | case OID_SKGE_SENSOR_ERR_THRES_UPP: | ||
2933 | Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh; | ||
2934 | SK_PNMI_STORE_U32(pBuf + Offset, Val32); | ||
2935 | Offset += sizeof(SK_U32); | ||
2936 | break; | ||
2937 | |||
2938 | case OID_SKGE_SENSOR_STATUS: | ||
2939 | *(pBuf + Offset) = | ||
2940 | (char)pAC->I2c.SenTable[Index].SenErrFlag; | ||
2941 | Offset += sizeof(char); | ||
2942 | break; | ||
2943 | |||
2944 | case OID_SKGE_SENSOR_WAR_CTS: | ||
2945 | Val64 = pAC->I2c.SenTable[Index].SenWarnCts; | ||
2946 | SK_PNMI_STORE_U64(pBuf + Offset, Val64); | ||
2947 | Offset += sizeof(SK_U64); | ||
2948 | break; | ||
2949 | |||
2950 | case OID_SKGE_SENSOR_ERR_CTS: | ||
2951 | Val64 = pAC->I2c.SenTable[Index].SenErrCts; | ||
2952 | SK_PNMI_STORE_U64(pBuf + Offset, Val64); | ||
2953 | Offset += sizeof(SK_U64); | ||
2954 | break; | ||
2955 | |||
2956 | case OID_SKGE_SENSOR_WAR_TIME: | ||
2957 | Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index]. | ||
2958 | SenBegWarnTS); | ||
2959 | SK_PNMI_STORE_U64(pBuf + Offset, Val64); | ||
2960 | Offset += sizeof(SK_U64); | ||
2961 | break; | ||
2962 | |||
2963 | case OID_SKGE_SENSOR_ERR_TIME: | ||
2964 | Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index]. | ||
2965 | SenBegErrTS); | ||
2966 | SK_PNMI_STORE_U64(pBuf + Offset, Val64); | ||
2967 | Offset += sizeof(SK_U64); | ||
2968 | break; | ||
2969 | |||
2970 | default: | ||
2971 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, | ||
2972 | ("SensorStat: Unknown OID should be handled before")); | ||
2973 | |||
2974 | return (SK_PNMI_ERR_GENERAL); | ||
2975 | } | ||
2976 | } | ||
2977 | |||
2978 | /* | ||
2979 | * Store used buffer space | ||
2980 | */ | ||
2981 | *pLen = Offset; | ||
2982 | |||
2983 | return (SK_PNMI_ERR_OK); | ||
2984 | } | ||
2985 | |||
2986 | /***************************************************************************** | ||
2987 | * | ||
2988 | * Vpd - OID handler function of OID_SKGE_VPD_XXX | ||
2989 | * | ||
2990 | * Description: | ||
2991 | * Get/preset/set of VPD data. As instance the name of a VPD key | ||
2992 | * can be passed. The Instance parameter is a SK_U32 and can be | ||
2993 | * used as a string buffer for the VPD key, because their maximum | ||
2994 | * length is 4 byte. | ||
2995 | * | ||
2996 | * Returns: | ||
2997 | * SK_PNMI_ERR_OK The request was successfully performed. | ||
2998 | * SK_PNMI_ERR_GENERAL A general severe internal error occured. | ||
2999 | * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain | ||
3000 | * the correct data (e.g. a 32bit value is | ||
3001 | * needed, but a 16 bit value was passed). | ||
3002 | * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid | ||
3003 | * value range. | ||
3004 | * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. | ||
3005 | * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't | ||
3006 | * exist (e.g. port instance 3 on a two port | ||
3007 | * adapter. | ||
3008 | */ | ||
3009 | PNMI_STATIC int Vpd( | ||
3010 | SK_AC *pAC, /* Pointer to adapter context */ | ||
3011 | SK_IOC IoC, /* IO context handle */ | ||
3012 | int Action, /* GET/PRESET/SET action */ | ||
3013 | SK_U32 Id, /* Object ID that is to be processed */ | ||
3014 | char *pBuf, /* Buffer used for the management data transfer */ | ||
3015 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
3016 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
3017 | unsigned int TableIndex, /* Index to the Id table */ | ||
3018 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
3019 | { | ||
3020 | SK_VPD_STATUS *pVpdStatus; | ||
3021 | unsigned int BufLen; | ||
3022 | char Buf[256]; | ||
3023 | char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE]; | ||
3024 | char KeyStr[SK_PNMI_VPD_KEY_SIZE]; | ||
3025 | unsigned int KeyNo; | ||
3026 | unsigned int Offset; | ||
3027 | unsigned int Index; | ||
3028 | unsigned int FirstIndex; | ||
3029 | unsigned int LastIndex; | ||
3030 | unsigned int Len; | ||
3031 | int Ret; | ||
3032 | SK_U32 Val32; | ||
3033 | |||
3034 | /* | ||
3035 | * Get array of all currently stored VPD keys | ||
3036 | */ | ||
3037 | Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &KeyNo); | ||
3038 | if (Ret != SK_PNMI_ERR_OK) { | ||
3039 | *pLen = 0; | ||
3040 | return (Ret); | ||
3041 | } | ||
3042 | |||
3043 | /* | ||
3044 | * If instance is not -1, try to find the requested VPD key for | ||
3045 | * the multiple instance variables. The other OIDs as for example | ||
3046 | * OID VPD_ACTION are single instance variables and must be | ||
3047 | * handled separatly. | ||
3048 | */ | ||
3049 | FirstIndex = 0; | ||
3050 | LastIndex = KeyNo; | ||
3051 | |||
3052 | if ((Instance != (SK_U32)(-1))) { | ||
3053 | |||
3054 | if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE || | ||
3055 | Id == OID_SKGE_VPD_ACCESS) { | ||
3056 | |||
3057 | SK_STRNCPY(KeyStr, (char *)&Instance, 4); | ||
3058 | KeyStr[4] = 0; | ||
3059 | |||
3060 | for (Index = 0; Index < KeyNo; Index ++) { | ||
3061 | |||
3062 | if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) { | ||
3063 | FirstIndex = Index; | ||
3064 | LastIndex = Index+1; | ||
3065 | break; | ||
3066 | } | ||
3067 | } | ||
3068 | if (Index == KeyNo) { | ||
3069 | |||
3070 | *pLen = 0; | ||
3071 | return (SK_PNMI_ERR_UNKNOWN_INST); | ||
3072 | } | ||
3073 | } | ||
3074 | else if (Instance != 1) { | ||
3075 | |||
3076 | *pLen = 0; | ||
3077 | return (SK_PNMI_ERR_UNKNOWN_INST); | ||
3078 | } | ||
3079 | } | ||
3080 | |||
3081 | /* | ||
3082 | * Get value, if a query should be performed | ||
3083 | */ | ||
3084 | if (Action == SK_PNMI_GET) { | ||
3085 | |||
3086 | switch (Id) { | ||
3087 | |||
3088 | case OID_SKGE_VPD_FREE_BYTES: | ||
3089 | /* Check length of buffer */ | ||
3090 | if (*pLen < sizeof(SK_U32)) { | ||
3091 | |||
3092 | *pLen = sizeof(SK_U32); | ||
3093 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3094 | } | ||
3095 | /* Get number of free bytes */ | ||
3096 | pVpdStatus = VpdStat(pAC, IoC); | ||
3097 | if (pVpdStatus == NULL) { | ||
3098 | |||
3099 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017, | ||
3100 | SK_PNMI_ERR017MSG); | ||
3101 | |||
3102 | *pLen = 0; | ||
3103 | return (SK_PNMI_ERR_GENERAL); | ||
3104 | } | ||
3105 | if ((pVpdStatus->vpd_status & VPD_VALID) == 0) { | ||
3106 | |||
3107 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018, | ||
3108 | SK_PNMI_ERR018MSG); | ||
3109 | |||
3110 | *pLen = 0; | ||
3111 | return (SK_PNMI_ERR_GENERAL); | ||
3112 | } | ||
3113 | |||
3114 | Val32 = (SK_U32)pVpdStatus->vpd_free_rw; | ||
3115 | SK_PNMI_STORE_U32(pBuf, Val32); | ||
3116 | *pLen = sizeof(SK_U32); | ||
3117 | break; | ||
3118 | |||
3119 | case OID_SKGE_VPD_ENTRIES_LIST: | ||
3120 | /* Check length */ | ||
3121 | for (Len = 0, Index = 0; Index < KeyNo; Index ++) { | ||
3122 | |||
3123 | Len += SK_STRLEN(KeyArr[Index]) + 1; | ||
3124 | } | ||
3125 | if (*pLen < Len) { | ||
3126 | |||
3127 | *pLen = Len; | ||
3128 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3129 | } | ||
3130 | |||
3131 | /* Get value */ | ||
3132 | *(pBuf) = (char)Len - 1; | ||
3133 | for (Offset = 1, Index = 0; Index < KeyNo; Index ++) { | ||
3134 | |||
3135 | Len = SK_STRLEN(KeyArr[Index]); | ||
3136 | SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len); | ||
3137 | |||
3138 | Offset += Len; | ||
3139 | |||
3140 | if (Index < KeyNo - 1) { | ||
3141 | |||
3142 | *(pBuf + Offset) = ' '; | ||
3143 | Offset ++; | ||
3144 | } | ||
3145 | } | ||
3146 | *pLen = Offset; | ||
3147 | break; | ||
3148 | |||
3149 | case OID_SKGE_VPD_ENTRIES_NUMBER: | ||
3150 | /* Check length */ | ||
3151 | if (*pLen < sizeof(SK_U32)) { | ||
3152 | |||
3153 | *pLen = sizeof(SK_U32); | ||
3154 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3155 | } | ||
3156 | |||
3157 | Val32 = (SK_U32)KeyNo; | ||
3158 | SK_PNMI_STORE_U32(pBuf, Val32); | ||
3159 | *pLen = sizeof(SK_U32); | ||
3160 | break; | ||
3161 | |||
3162 | case OID_SKGE_VPD_KEY: | ||
3163 | /* Check buffer length, if it is large enough */ | ||
3164 | for (Len = 0, Index = FirstIndex; | ||
3165 | Index < LastIndex; Index ++) { | ||
3166 | |||
3167 | Len += SK_STRLEN(KeyArr[Index]) + 1; | ||
3168 | } | ||
3169 | if (*pLen < Len) { | ||
3170 | |||
3171 | *pLen = Len; | ||
3172 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3173 | } | ||
3174 | |||
3175 | /* | ||
3176 | * Get the key to an intermediate buffer, because | ||
3177 | * we have to prepend a length byte. | ||
3178 | */ | ||
3179 | for (Offset = 0, Index = FirstIndex; | ||
3180 | Index < LastIndex; Index ++) { | ||
3181 | |||
3182 | Len = SK_STRLEN(KeyArr[Index]); | ||
3183 | |||
3184 | *(pBuf + Offset) = (char)Len; | ||
3185 | SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index], | ||
3186 | Len); | ||
3187 | Offset += Len + 1; | ||
3188 | } | ||
3189 | *pLen = Offset; | ||
3190 | break; | ||
3191 | |||
3192 | case OID_SKGE_VPD_VALUE: | ||
3193 | /* Check the buffer length if it is large enough */ | ||
3194 | for (Offset = 0, Index = FirstIndex; | ||
3195 | Index < LastIndex; Index ++) { | ||
3196 | |||
3197 | BufLen = 256; | ||
3198 | if (VpdRead(pAC, IoC, KeyArr[Index], Buf, | ||
3199 | (int *)&BufLen) > 0 || | ||
3200 | BufLen >= SK_PNMI_VPD_DATALEN) { | ||
3201 | |||
3202 | SK_ERR_LOG(pAC, SK_ERRCL_SW, | ||
3203 | SK_PNMI_ERR021, | ||
3204 | SK_PNMI_ERR021MSG); | ||
3205 | |||
3206 | return (SK_PNMI_ERR_GENERAL); | ||
3207 | } | ||
3208 | Offset += BufLen + 1; | ||
3209 | } | ||
3210 | if (*pLen < Offset) { | ||
3211 | |||
3212 | *pLen = Offset; | ||
3213 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3214 | } | ||
3215 | |||
3216 | /* | ||
3217 | * Get the value to an intermediate buffer, because | ||
3218 | * we have to prepend a length byte. | ||
3219 | */ | ||
3220 | for (Offset = 0, Index = FirstIndex; | ||
3221 | Index < LastIndex; Index ++) { | ||
3222 | |||
3223 | BufLen = 256; | ||
3224 | if (VpdRead(pAC, IoC, KeyArr[Index], Buf, | ||
3225 | (int *)&BufLen) > 0 || | ||
3226 | BufLen >= SK_PNMI_VPD_DATALEN) { | ||
3227 | |||
3228 | SK_ERR_LOG(pAC, SK_ERRCL_SW, | ||
3229 | SK_PNMI_ERR022, | ||
3230 | SK_PNMI_ERR022MSG); | ||
3231 | |||
3232 | *pLen = 0; | ||
3233 | return (SK_PNMI_ERR_GENERAL); | ||
3234 | } | ||
3235 | |||
3236 | *(pBuf + Offset) = (char)BufLen; | ||
3237 | SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen); | ||
3238 | Offset += BufLen + 1; | ||
3239 | } | ||
3240 | *pLen = Offset; | ||
3241 | break; | ||
3242 | |||
3243 | case OID_SKGE_VPD_ACCESS: | ||
3244 | if (*pLen < LastIndex - FirstIndex) { | ||
3245 | |||
3246 | *pLen = LastIndex - FirstIndex; | ||
3247 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3248 | } | ||
3249 | |||
3250 | for (Offset = 0, Index = FirstIndex; | ||
3251 | Index < LastIndex; Index ++) { | ||
3252 | |||
3253 | if (VpdMayWrite(KeyArr[Index])) { | ||
3254 | |||
3255 | *(pBuf + Offset) = SK_PNMI_VPD_RW; | ||
3256 | } | ||
3257 | else { | ||
3258 | *(pBuf + Offset) = SK_PNMI_VPD_RO; | ||
3259 | } | ||
3260 | Offset ++; | ||
3261 | } | ||
3262 | *pLen = Offset; | ||
3263 | break; | ||
3264 | |||
3265 | case OID_SKGE_VPD_ACTION: | ||
3266 | Offset = LastIndex - FirstIndex; | ||
3267 | if (*pLen < Offset) { | ||
3268 | |||
3269 | *pLen = Offset; | ||
3270 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3271 | } | ||
3272 | SK_MEMSET(pBuf, 0, Offset); | ||
3273 | *pLen = Offset; | ||
3274 | break; | ||
3275 | |||
3276 | default: | ||
3277 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023, | ||
3278 | SK_PNMI_ERR023MSG); | ||
3279 | |||
3280 | *pLen = 0; | ||
3281 | return (SK_PNMI_ERR_GENERAL); | ||
3282 | } | ||
3283 | } | ||
3284 | else { | ||
3285 | /* The only OID which can be set is VPD_ACTION */ | ||
3286 | if (Id != OID_SKGE_VPD_ACTION) { | ||
3287 | |||
3288 | if (Id == OID_SKGE_VPD_FREE_BYTES || | ||
3289 | Id == OID_SKGE_VPD_ENTRIES_LIST || | ||
3290 | Id == OID_SKGE_VPD_ENTRIES_NUMBER || | ||
3291 | Id == OID_SKGE_VPD_KEY || | ||
3292 | Id == OID_SKGE_VPD_VALUE || | ||
3293 | Id == OID_SKGE_VPD_ACCESS) { | ||
3294 | |||
3295 | *pLen = 0; | ||
3296 | return (SK_PNMI_ERR_READ_ONLY); | ||
3297 | } | ||
3298 | |||
3299 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024, | ||
3300 | SK_PNMI_ERR024MSG); | ||
3301 | |||
3302 | *pLen = 0; | ||
3303 | return (SK_PNMI_ERR_GENERAL); | ||
3304 | } | ||
3305 | |||
3306 | /* | ||
3307 | * From this point we handle VPD_ACTION. Check the buffer | ||
3308 | * length. It should at least have the size of one byte. | ||
3309 | */ | ||
3310 | if (*pLen < 1) { | ||
3311 | |||
3312 | *pLen = 1; | ||
3313 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3314 | } | ||
3315 | |||
3316 | /* | ||
3317 | * The first byte contains the VPD action type we should | ||
3318 | * perform. | ||
3319 | */ | ||
3320 | switch (*pBuf) { | ||
3321 | |||
3322 | case SK_PNMI_VPD_IGNORE: | ||
3323 | /* Nothing to do */ | ||
3324 | break; | ||
3325 | |||
3326 | case SK_PNMI_VPD_CREATE: | ||
3327 | /* | ||
3328 | * We have to create a new VPD entry or we modify | ||
3329 | * an existing one. Check first the buffer length. | ||
3330 | */ | ||
3331 | if (*pLen < 4) { | ||
3332 | |||
3333 | *pLen = 4; | ||
3334 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3335 | } | ||
3336 | KeyStr[0] = pBuf[1]; | ||
3337 | KeyStr[1] = pBuf[2]; | ||
3338 | KeyStr[2] = 0; | ||
3339 | |||
3340 | /* | ||
3341 | * Is the entry writable or does it belong to the | ||
3342 | * read-only area? | ||
3343 | */ | ||
3344 | if (!VpdMayWrite(KeyStr)) { | ||
3345 | |||
3346 | *pLen = 0; | ||
3347 | return (SK_PNMI_ERR_BAD_VALUE); | ||
3348 | } | ||
3349 | |||
3350 | Offset = (int)pBuf[3] & 0xFF; | ||
3351 | |||
3352 | SK_MEMCPY(Buf, pBuf + 4, Offset); | ||
3353 | Buf[Offset] = 0; | ||
3354 | |||
3355 | /* A preset ends here */ | ||
3356 | if (Action == SK_PNMI_PRESET) { | ||
3357 | |||
3358 | return (SK_PNMI_ERR_OK); | ||
3359 | } | ||
3360 | |||
3361 | /* Write the new entry or modify an existing one */ | ||
3362 | Ret = VpdWrite(pAC, IoC, KeyStr, Buf); | ||
3363 | if (Ret == SK_PNMI_VPD_NOWRITE ) { | ||
3364 | |||
3365 | *pLen = 0; | ||
3366 | return (SK_PNMI_ERR_BAD_VALUE); | ||
3367 | } | ||
3368 | else if (Ret != SK_PNMI_VPD_OK) { | ||
3369 | |||
3370 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025, | ||
3371 | SK_PNMI_ERR025MSG); | ||
3372 | |||
3373 | *pLen = 0; | ||
3374 | return (SK_PNMI_ERR_GENERAL); | ||
3375 | } | ||
3376 | |||
3377 | /* | ||
3378 | * Perform an update of the VPD data. This is | ||
3379 | * not mandantory, but just to be sure. | ||
3380 | */ | ||
3381 | Ret = VpdUpdate(pAC, IoC); | ||
3382 | if (Ret != SK_PNMI_VPD_OK) { | ||
3383 | |||
3384 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026, | ||
3385 | SK_PNMI_ERR026MSG); | ||
3386 | |||
3387 | *pLen = 0; | ||
3388 | return (SK_PNMI_ERR_GENERAL); | ||
3389 | } | ||
3390 | break; | ||
3391 | |||
3392 | case SK_PNMI_VPD_DELETE: | ||
3393 | /* Check if the buffer size is plausible */ | ||
3394 | if (*pLen < 3) { | ||
3395 | |||
3396 | *pLen = 3; | ||
3397 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3398 | } | ||
3399 | if (*pLen > 3) { | ||
3400 | |||
3401 | *pLen = 0; | ||
3402 | return (SK_PNMI_ERR_BAD_VALUE); | ||
3403 | } | ||
3404 | KeyStr[0] = pBuf[1]; | ||
3405 | KeyStr[1] = pBuf[2]; | ||
3406 | KeyStr[2] = 0; | ||
3407 | |||
3408 | /* Find the passed key in the array */ | ||
3409 | for (Index = 0; Index < KeyNo; Index ++) { | ||
3410 | |||
3411 | if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) { | ||
3412 | |||
3413 | break; | ||
3414 | } | ||
3415 | } | ||
3416 | /* | ||
3417 | * If we cannot find the key it is wrong, so we | ||
3418 | * return an appropriate error value. | ||
3419 | */ | ||
3420 | if (Index == KeyNo) { | ||
3421 | |||
3422 | *pLen = 0; | ||
3423 | return (SK_PNMI_ERR_BAD_VALUE); | ||
3424 | } | ||
3425 | |||
3426 | if (Action == SK_PNMI_PRESET) { | ||
3427 | |||
3428 | return (SK_PNMI_ERR_OK); | ||
3429 | } | ||
3430 | |||
3431 | /* Ok, you wanted it and you will get it */ | ||
3432 | Ret = VpdDelete(pAC, IoC, KeyStr); | ||
3433 | if (Ret != SK_PNMI_VPD_OK) { | ||
3434 | |||
3435 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027, | ||
3436 | SK_PNMI_ERR027MSG); | ||
3437 | |||
3438 | *pLen = 0; | ||
3439 | return (SK_PNMI_ERR_GENERAL); | ||
3440 | } | ||
3441 | |||
3442 | /* | ||
3443 | * Perform an update of the VPD data. This is | ||
3444 | * not mandantory, but just to be sure. | ||
3445 | */ | ||
3446 | Ret = VpdUpdate(pAC, IoC); | ||
3447 | if (Ret != SK_PNMI_VPD_OK) { | ||
3448 | |||
3449 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028, | ||
3450 | SK_PNMI_ERR028MSG); | ||
3451 | |||
3452 | *pLen = 0; | ||
3453 | return (SK_PNMI_ERR_GENERAL); | ||
3454 | } | ||
3455 | break; | ||
3456 | |||
3457 | default: | ||
3458 | *pLen = 0; | ||
3459 | return (SK_PNMI_ERR_BAD_VALUE); | ||
3460 | } | ||
3461 | } | ||
3462 | |||
3463 | return (SK_PNMI_ERR_OK); | ||
3464 | } | ||
3465 | |||
3466 | /***************************************************************************** | ||
3467 | * | ||
3468 | * General - OID handler function of various single instance OIDs | ||
3469 | * | ||
3470 | * Description: | ||
3471 | * The code is simple. No description necessary. | ||
3472 | * | ||
3473 | * Returns: | ||
3474 | * SK_PNMI_ERR_OK The request was successfully performed. | ||
3475 | * SK_PNMI_ERR_GENERAL A general severe internal error occured. | ||
3476 | * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain | ||
3477 | * the correct data (e.g. a 32bit value is | ||
3478 | * needed, but a 16 bit value was passed). | ||
3479 | * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't | ||
3480 | * exist (e.g. port instance 3 on a two port | ||
3481 | * adapter. | ||
3482 | */ | ||
3483 | PNMI_STATIC int General( | ||
3484 | SK_AC *pAC, /* Pointer to adapter context */ | ||
3485 | SK_IOC IoC, /* IO context handle */ | ||
3486 | int Action, /* GET/PRESET/SET action */ | ||
3487 | SK_U32 Id, /* Object ID that is to be processed */ | ||
3488 | char *pBuf, /* Buffer used for the management data transfer */ | ||
3489 | unsigned int *pLen, /* On call: buffer length. On return: used buffer */ | ||
3490 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
3491 | unsigned int TableIndex, /* Index to the Id table */ | ||
3492 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
3493 | { | ||
3494 | int Ret; | ||
3495 | unsigned int Index; | ||
3496 | unsigned int Len; | ||
3497 | unsigned int Offset; | ||
3498 | unsigned int Val; | ||
3499 | SK_U8 Val8; | ||
3500 | SK_U16 Val16; | ||
3501 | SK_U32 Val32; | ||
3502 | SK_U64 Val64; | ||
3503 | SK_U64 Val64RxHwErrs = 0; | ||
3504 | SK_U64 Val64TxHwErrs = 0; | ||
3505 | SK_BOOL Is64BitReq = SK_FALSE; | ||
3506 | char Buf[256]; | ||
3507 | int MacType; | ||
3508 | |||
3509 | /* | ||
3510 | * Check instance. We only handle single instance variables. | ||
3511 | */ | ||
3512 | if (Instance != (SK_U32)(-1) && Instance != 1) { | ||
3513 | |||
3514 | *pLen = 0; | ||
3515 | return (SK_PNMI_ERR_UNKNOWN_INST); | ||
3516 | } | ||
3517 | |||
3518 | /* | ||
3519 | * Check action. We only allow get requests. | ||
3520 | */ | ||
3521 | if (Action != SK_PNMI_GET) { | ||
3522 | |||
3523 | *pLen = 0; | ||
3524 | return (SK_PNMI_ERR_READ_ONLY); | ||
3525 | } | ||
3526 | |||
3527 | MacType = pAC->GIni.GIMacType; | ||
3528 | |||
3529 | /* | ||
3530 | * Check length for the various supported OIDs | ||
3531 | */ | ||
3532 | switch (Id) { | ||
3533 | |||
3534 | case OID_GEN_XMIT_ERROR: | ||
3535 | case OID_GEN_RCV_ERROR: | ||
3536 | case OID_GEN_RCV_NO_BUFFER: | ||
3537 | #ifndef SK_NDIS_64BIT_CTR | ||
3538 | if (*pLen < sizeof(SK_U32)) { | ||
3539 | *pLen = sizeof(SK_U32); | ||
3540 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3541 | } | ||
3542 | |||
3543 | #else /* SK_NDIS_64BIT_CTR */ | ||
3544 | |||
3545 | /* | ||
3546 | * for compatibility, at least 32bit are required for oid | ||
3547 | */ | ||
3548 | if (*pLen < sizeof(SK_U32)) { | ||
3549 | /* | ||
3550 | * but indicate handling for 64bit values, | ||
3551 | * if insufficient space is provided | ||
3552 | */ | ||
3553 | *pLen = sizeof(SK_U64); | ||
3554 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3555 | } | ||
3556 | |||
3557 | Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE; | ||
3558 | #endif /* SK_NDIS_64BIT_CTR */ | ||
3559 | break; | ||
3560 | |||
3561 | case OID_SKGE_PORT_NUMBER: | ||
3562 | case OID_SKGE_DEVICE_TYPE: | ||
3563 | case OID_SKGE_RESULT: | ||
3564 | case OID_SKGE_RLMT_MONITOR_NUMBER: | ||
3565 | case OID_GEN_TRANSMIT_QUEUE_LENGTH: | ||
3566 | case OID_SKGE_TRAP_NUMBER: | ||
3567 | case OID_SKGE_MDB_VERSION: | ||
3568 | case OID_SKGE_BOARDLEVEL: | ||
3569 | case OID_SKGE_CHIPID: | ||
3570 | case OID_SKGE_RAMSIZE: | ||
3571 | if (*pLen < sizeof(SK_U32)) { | ||
3572 | |||
3573 | *pLen = sizeof(SK_U32); | ||
3574 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3575 | } | ||
3576 | break; | ||
3577 | |||
3578 | case OID_SKGE_CHIPSET: | ||
3579 | if (*pLen < sizeof(SK_U16)) { | ||
3580 | |||
3581 | *pLen = sizeof(SK_U16); | ||
3582 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3583 | } | ||
3584 | break; | ||
3585 | |||
3586 | case OID_SKGE_BUS_TYPE: | ||
3587 | case OID_SKGE_BUS_SPEED: | ||
3588 | case OID_SKGE_BUS_WIDTH: | ||
3589 | case OID_SKGE_SENSOR_NUMBER: | ||
3590 | case OID_SKGE_CHKSM_NUMBER: | ||
3591 | case OID_SKGE_VAUXAVAIL: | ||
3592 | if (*pLen < sizeof(SK_U8)) { | ||
3593 | |||
3594 | *pLen = sizeof(SK_U8); | ||
3595 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3596 | } | ||
3597 | break; | ||
3598 | |||
3599 | case OID_SKGE_TX_SW_QUEUE_LEN: | ||
3600 | case OID_SKGE_TX_SW_QUEUE_MAX: | ||
3601 | case OID_SKGE_TX_RETRY: | ||
3602 | case OID_SKGE_RX_INTR_CTS: | ||
3603 | case OID_SKGE_TX_INTR_CTS: | ||
3604 | case OID_SKGE_RX_NO_BUF_CTS: | ||
3605 | case OID_SKGE_TX_NO_BUF_CTS: | ||
3606 | case OID_SKGE_TX_USED_DESCR_NO: | ||
3607 | case OID_SKGE_RX_DELIVERED_CTS: | ||
3608 | case OID_SKGE_RX_OCTETS_DELIV_CTS: | ||
3609 | case OID_SKGE_RX_HW_ERROR_CTS: | ||
3610 | case OID_SKGE_TX_HW_ERROR_CTS: | ||
3611 | case OID_SKGE_IN_ERRORS_CTS: | ||
3612 | case OID_SKGE_OUT_ERROR_CTS: | ||
3613 | case OID_SKGE_ERR_RECOVERY_CTS: | ||
3614 | case OID_SKGE_SYSUPTIME: | ||
3615 | if (*pLen < sizeof(SK_U64)) { | ||
3616 | |||
3617 | *pLen = sizeof(SK_U64); | ||
3618 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3619 | } | ||
3620 | break; | ||
3621 | |||
3622 | default: | ||
3623 | /* Checked later */ | ||
3624 | break; | ||
3625 | } | ||
3626 | |||
3627 | /* Update statistic */ | ||
3628 | if (Id == OID_SKGE_RX_HW_ERROR_CTS || | ||
3629 | Id == OID_SKGE_TX_HW_ERROR_CTS || | ||
3630 | Id == OID_SKGE_IN_ERRORS_CTS || | ||
3631 | Id == OID_SKGE_OUT_ERROR_CTS || | ||
3632 | Id == OID_GEN_XMIT_ERROR || | ||
3633 | Id == OID_GEN_RCV_ERROR) { | ||
3634 | |||
3635 | /* Force the XMAC to update its statistic counters and | ||
3636 | * Increment semaphore to indicate that an update was | ||
3637 | * already done. | ||
3638 | */ | ||
3639 | Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1); | ||
3640 | if (Ret != SK_PNMI_ERR_OK) { | ||
3641 | |||
3642 | *pLen = 0; | ||
3643 | return (Ret); | ||
3644 | } | ||
3645 | pAC->Pnmi.MacUpdatedFlag ++; | ||
3646 | |||
3647 | /* | ||
3648 | * Some OIDs consist of multiple hardware counters. Those | ||
3649 | * values which are contained in all of them will be added | ||
3650 | * now. | ||
3651 | */ | ||
3652 | switch (Id) { | ||
3653 | |||
3654 | case OID_SKGE_RX_HW_ERROR_CTS: | ||
3655 | case OID_SKGE_IN_ERRORS_CTS: | ||
3656 | case OID_GEN_RCV_ERROR: | ||
3657 | Val64RxHwErrs = | ||
3658 | GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) + | ||
3659 | GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) + | ||
3660 | GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex) + | ||
3661 | GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) + | ||
3662 | GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) + | ||
3663 | GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex) + | ||
3664 | GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) + | ||
3665 | GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) + | ||
3666 | GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) + | ||
3667 | GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) + | ||
3668 | GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) + | ||
3669 | GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex); | ||
3670 | break; | ||
3671 | |||
3672 | case OID_SKGE_TX_HW_ERROR_CTS: | ||
3673 | case OID_SKGE_OUT_ERROR_CTS: | ||
3674 | case OID_GEN_XMIT_ERROR: | ||
3675 | Val64TxHwErrs = | ||
3676 | GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) + | ||
3677 | GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex) + | ||
3678 | GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex) + | ||
3679 | GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex); | ||
3680 | break; | ||
3681 | } | ||
3682 | } | ||
3683 | |||
3684 | /* | ||
3685 | * Retrieve value | ||
3686 | */ | ||
3687 | switch (Id) { | ||
3688 | |||
3689 | case OID_SKGE_SUPPORTED_LIST: | ||
3690 | Len = ID_TABLE_SIZE * sizeof(SK_U32); | ||
3691 | if (*pLen < Len) { | ||
3692 | |||
3693 | *pLen = Len; | ||
3694 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3695 | } | ||
3696 | for (Offset = 0, Index = 0; Offset < Len; | ||
3697 | Offset += sizeof(SK_U32), Index ++) { | ||
3698 | |||
3699 | Val32 = (SK_U32)IdTable[Index].Id; | ||
3700 | SK_PNMI_STORE_U32(pBuf + Offset, Val32); | ||
3701 | } | ||
3702 | *pLen = Len; | ||
3703 | break; | ||
3704 | |||
3705 | case OID_SKGE_BOARDLEVEL: | ||
3706 | Val32 = (SK_U32)pAC->GIni.GILevel; | ||
3707 | SK_PNMI_STORE_U32(pBuf, Val32); | ||
3708 | *pLen = sizeof(SK_U32); | ||
3709 | break; | ||
3710 | |||
3711 | case OID_SKGE_PORT_NUMBER: | ||
3712 | Val32 = (SK_U32)pAC->GIni.GIMacsFound; | ||
3713 | SK_PNMI_STORE_U32(pBuf, Val32); | ||
3714 | *pLen = sizeof(SK_U32); | ||
3715 | break; | ||
3716 | |||
3717 | case OID_SKGE_DEVICE_TYPE: | ||
3718 | Val32 = (SK_U32)pAC->Pnmi.DeviceType; | ||
3719 | SK_PNMI_STORE_U32(pBuf, Val32); | ||
3720 | *pLen = sizeof(SK_U32); | ||
3721 | break; | ||
3722 | |||
3723 | case OID_SKGE_DRIVER_DESCR: | ||
3724 | if (pAC->Pnmi.pDriverDescription == NULL) { | ||
3725 | |||
3726 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007, | ||
3727 | SK_PNMI_ERR007MSG); | ||
3728 | |||
3729 | *pLen = 0; | ||
3730 | return (SK_PNMI_ERR_GENERAL); | ||
3731 | } | ||
3732 | |||
3733 | Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1; | ||
3734 | if (Len > SK_PNMI_STRINGLEN1) { | ||
3735 | |||
3736 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029, | ||
3737 | SK_PNMI_ERR029MSG); | ||
3738 | |||
3739 | *pLen = 0; | ||
3740 | return (SK_PNMI_ERR_GENERAL); | ||
3741 | } | ||
3742 | |||
3743 | if (*pLen < Len) { | ||
3744 | |||
3745 | *pLen = Len; | ||
3746 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3747 | } | ||
3748 | *pBuf = (char)(Len - 1); | ||
3749 | SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1); | ||
3750 | *pLen = Len; | ||
3751 | break; | ||
3752 | |||
3753 | case OID_SKGE_DRIVER_VERSION: | ||
3754 | if (pAC->Pnmi.pDriverVersion == NULL) { | ||
3755 | |||
3756 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030, | ||
3757 | SK_PNMI_ERR030MSG); | ||
3758 | |||
3759 | *pLen = 0; | ||
3760 | return (SK_PNMI_ERR_GENERAL); | ||
3761 | } | ||
3762 | |||
3763 | Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1; | ||
3764 | if (Len > SK_PNMI_STRINGLEN1) { | ||
3765 | |||
3766 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031, | ||
3767 | SK_PNMI_ERR031MSG); | ||
3768 | |||
3769 | *pLen = 0; | ||
3770 | return (SK_PNMI_ERR_GENERAL); | ||
3771 | } | ||
3772 | |||
3773 | if (*pLen < Len) { | ||
3774 | |||
3775 | *pLen = Len; | ||
3776 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3777 | } | ||
3778 | *pBuf = (char)(Len - 1); | ||
3779 | SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1); | ||
3780 | *pLen = Len; | ||
3781 | break; | ||
3782 | |||
3783 | case OID_SKGE_DRIVER_RELDATE: | ||
3784 | if (pAC->Pnmi.pDriverReleaseDate == NULL) { | ||
3785 | |||
3786 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030, | ||
3787 | SK_PNMI_ERR053MSG); | ||
3788 | |||
3789 | *pLen = 0; | ||
3790 | return (SK_PNMI_ERR_GENERAL); | ||
3791 | } | ||
3792 | |||
3793 | Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1; | ||
3794 | if (Len > SK_PNMI_STRINGLEN1) { | ||
3795 | |||
3796 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031, | ||
3797 | SK_PNMI_ERR054MSG); | ||
3798 | |||
3799 | *pLen = 0; | ||
3800 | return (SK_PNMI_ERR_GENERAL); | ||
3801 | } | ||
3802 | |||
3803 | if (*pLen < Len) { | ||
3804 | |||
3805 | *pLen = Len; | ||
3806 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3807 | } | ||
3808 | *pBuf = (char)(Len - 1); | ||
3809 | SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverReleaseDate, Len - 1); | ||
3810 | *pLen = Len; | ||
3811 | break; | ||
3812 | |||
3813 | case OID_SKGE_DRIVER_FILENAME: | ||
3814 | if (pAC->Pnmi.pDriverFileName == NULL) { | ||
3815 | |||
3816 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030, | ||
3817 | SK_PNMI_ERR055MSG); | ||
3818 | |||
3819 | *pLen = 0; | ||
3820 | return (SK_PNMI_ERR_GENERAL); | ||
3821 | } | ||
3822 | |||
3823 | Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1; | ||
3824 | if (Len > SK_PNMI_STRINGLEN1) { | ||
3825 | |||
3826 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031, | ||
3827 | SK_PNMI_ERR056MSG); | ||
3828 | |||
3829 | *pLen = 0; | ||
3830 | return (SK_PNMI_ERR_GENERAL); | ||
3831 | } | ||
3832 | |||
3833 | if (*pLen < Len) { | ||
3834 | |||
3835 | *pLen = Len; | ||
3836 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3837 | } | ||
3838 | *pBuf = (char)(Len - 1); | ||
3839 | SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverFileName, Len - 1); | ||
3840 | *pLen = Len; | ||
3841 | break; | ||
3842 | |||
3843 | case OID_SKGE_HW_DESCR: | ||
3844 | /* | ||
3845 | * The hardware description is located in the VPD. This | ||
3846 | * query may move to the initialisation routine. But | ||
3847 | * the VPD data is cached and therefore a call here | ||
3848 | * will not make much difference. | ||
3849 | */ | ||
3850 | Len = 256; | ||
3851 | if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) { | ||
3852 | |||
3853 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032, | ||
3854 | SK_PNMI_ERR032MSG); | ||
3855 | |||
3856 | *pLen = 0; | ||
3857 | return (SK_PNMI_ERR_GENERAL); | ||
3858 | } | ||
3859 | Len ++; | ||
3860 | if (Len > SK_PNMI_STRINGLEN1) { | ||
3861 | |||
3862 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033, | ||
3863 | SK_PNMI_ERR033MSG); | ||
3864 | |||
3865 | *pLen = 0; | ||
3866 | return (SK_PNMI_ERR_GENERAL); | ||
3867 | } | ||
3868 | if (*pLen < Len) { | ||
3869 | |||
3870 | *pLen = Len; | ||
3871 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3872 | } | ||
3873 | *pBuf = (char)(Len - 1); | ||
3874 | SK_MEMCPY(pBuf + 1, Buf, Len - 1); | ||
3875 | *pLen = Len; | ||
3876 | break; | ||
3877 | |||
3878 | case OID_SKGE_HW_VERSION: | ||
3879 | /* Oh, I love to do some string manipulation */ | ||
3880 | if (*pLen < 5) { | ||
3881 | |||
3882 | *pLen = 5; | ||
3883 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3884 | } | ||
3885 | Val8 = (SK_U8)pAC->GIni.GIPciHwRev; | ||
3886 | pBuf[0] = 4; | ||
3887 | pBuf[1] = 'v'; | ||
3888 | pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F)); | ||
3889 | pBuf[3] = '.'; | ||
3890 | pBuf[4] = (char)(0x30 | (Val8 & 0x0F)); | ||
3891 | *pLen = 5; | ||
3892 | break; | ||
3893 | |||
3894 | case OID_SKGE_CHIPSET: | ||
3895 | Val16 = pAC->Pnmi.Chipset; | ||
3896 | SK_PNMI_STORE_U16(pBuf, Val16); | ||
3897 | *pLen = sizeof(SK_U16); | ||
3898 | break; | ||
3899 | |||
3900 | case OID_SKGE_CHIPID: | ||
3901 | Val32 = pAC->GIni.GIChipId; | ||
3902 | SK_PNMI_STORE_U32(pBuf, Val32); | ||
3903 | *pLen = sizeof(SK_U32); | ||
3904 | break; | ||
3905 | |||
3906 | case OID_SKGE_RAMSIZE: | ||
3907 | Val32 = pAC->GIni.GIRamSize; | ||
3908 | SK_PNMI_STORE_U32(pBuf, Val32); | ||
3909 | *pLen = sizeof(SK_U32); | ||
3910 | break; | ||
3911 | |||
3912 | case OID_SKGE_VAUXAVAIL: | ||
3913 | *pBuf = (char) pAC->GIni.GIVauxAvail; | ||
3914 | *pLen = sizeof(char); | ||
3915 | break; | ||
3916 | |||
3917 | case OID_SKGE_BUS_TYPE: | ||
3918 | *pBuf = (char) SK_PNMI_BUS_PCI; | ||
3919 | *pLen = sizeof(char); | ||
3920 | break; | ||
3921 | |||
3922 | case OID_SKGE_BUS_SPEED: | ||
3923 | *pBuf = pAC->Pnmi.PciBusSpeed; | ||
3924 | *pLen = sizeof(char); | ||
3925 | break; | ||
3926 | |||
3927 | case OID_SKGE_BUS_WIDTH: | ||
3928 | *pBuf = pAC->Pnmi.PciBusWidth; | ||
3929 | *pLen = sizeof(char); | ||
3930 | break; | ||
3931 | |||
3932 | case OID_SKGE_RESULT: | ||
3933 | Val32 = pAC->Pnmi.TestResult; | ||
3934 | SK_PNMI_STORE_U32(pBuf, Val32); | ||
3935 | *pLen = sizeof(SK_U32); | ||
3936 | break; | ||
3937 | |||
3938 | case OID_SKGE_SENSOR_NUMBER: | ||
3939 | *pBuf = (char)pAC->I2c.MaxSens; | ||
3940 | *pLen = sizeof(char); | ||
3941 | break; | ||
3942 | |||
3943 | case OID_SKGE_CHKSM_NUMBER: | ||
3944 | *pBuf = SKCS_NUM_PROTOCOLS; | ||
3945 | *pLen = sizeof(char); | ||
3946 | break; | ||
3947 | |||
3948 | case OID_SKGE_TRAP_NUMBER: | ||
3949 | GetTrapQueueLen(pAC, &Len, &Val); | ||
3950 | Val32 = (SK_U32)Val; | ||
3951 | SK_PNMI_STORE_U32(pBuf, Val32); | ||
3952 | *pLen = sizeof(SK_U32); | ||
3953 | break; | ||
3954 | |||
3955 | case OID_SKGE_TRAP: | ||
3956 | GetTrapQueueLen(pAC, &Len, &Val); | ||
3957 | if (*pLen < Len) { | ||
3958 | |||
3959 | *pLen = Len; | ||
3960 | return (SK_PNMI_ERR_TOO_SHORT); | ||
3961 | } | ||
3962 | CopyTrapQueue(pAC, pBuf); | ||
3963 | *pLen = Len; | ||
3964 | break; | ||
3965 | |||
3966 | case OID_SKGE_RLMT_MONITOR_NUMBER: | ||
3967 | /* XXX Not yet implemented by RLMT therefore we return zero elements */ | ||
3968 | Val32 = 0; | ||
3969 | SK_PNMI_STORE_U32(pBuf, Val32); | ||
3970 | *pLen = sizeof(SK_U32); | ||
3971 | break; | ||
3972 | |||
3973 | case OID_SKGE_TX_SW_QUEUE_LEN: | ||
3974 | /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ | ||
3975 | if (MacType == SK_MAC_XMAC) { | ||
3976 | /* Dual net mode */ | ||
3977 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
3978 | Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen; | ||
3979 | } | ||
3980 | /* Single net mode */ | ||
3981 | else { | ||
3982 | Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen + | ||
3983 | pAC->Pnmi.BufPort[1].TxSwQueueLen; | ||
3984 | } | ||
3985 | } | ||
3986 | else { | ||
3987 | /* Dual net mode */ | ||
3988 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
3989 | Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen; | ||
3990 | } | ||
3991 | /* Single net mode */ | ||
3992 | else { | ||
3993 | Val64 = pAC->Pnmi.Port[0].TxSwQueueLen + | ||
3994 | pAC->Pnmi.Port[1].TxSwQueueLen; | ||
3995 | } | ||
3996 | } | ||
3997 | SK_PNMI_STORE_U64(pBuf, Val64); | ||
3998 | *pLen = sizeof(SK_U64); | ||
3999 | break; | ||
4000 | |||
4001 | |||
4002 | case OID_SKGE_TX_SW_QUEUE_MAX: | ||
4003 | /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ | ||
4004 | if (MacType == SK_MAC_XMAC) { | ||
4005 | /* Dual net mode */ | ||
4006 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4007 | Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax; | ||
4008 | } | ||
4009 | /* Single net mode */ | ||
4010 | else { | ||
4011 | Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax + | ||
4012 | pAC->Pnmi.BufPort[1].TxSwQueueMax; | ||
4013 | } | ||
4014 | } | ||
4015 | else { | ||
4016 | /* Dual net mode */ | ||
4017 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4018 | Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax; | ||
4019 | } | ||
4020 | /* Single net mode */ | ||
4021 | else { | ||
4022 | Val64 = pAC->Pnmi.Port[0].TxSwQueueMax + | ||
4023 | pAC->Pnmi.Port[1].TxSwQueueMax; | ||
4024 | } | ||
4025 | } | ||
4026 | SK_PNMI_STORE_U64(pBuf, Val64); | ||
4027 | *pLen = sizeof(SK_U64); | ||
4028 | break; | ||
4029 | |||
4030 | case OID_SKGE_TX_RETRY: | ||
4031 | /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ | ||
4032 | if (MacType == SK_MAC_XMAC) { | ||
4033 | /* Dual net mode */ | ||
4034 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4035 | Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts; | ||
4036 | } | ||
4037 | /* Single net mode */ | ||
4038 | else { | ||
4039 | Val64 = pAC->Pnmi.BufPort[0].TxRetryCts + | ||
4040 | pAC->Pnmi.BufPort[1].TxRetryCts; | ||
4041 | } | ||
4042 | } | ||
4043 | else { | ||
4044 | /* Dual net mode */ | ||
4045 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4046 | Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts; | ||
4047 | } | ||
4048 | /* Single net mode */ | ||
4049 | else { | ||
4050 | Val64 = pAC->Pnmi.Port[0].TxRetryCts + | ||
4051 | pAC->Pnmi.Port[1].TxRetryCts; | ||
4052 | } | ||
4053 | } | ||
4054 | SK_PNMI_STORE_U64(pBuf, Val64); | ||
4055 | *pLen = sizeof(SK_U64); | ||
4056 | break; | ||
4057 | |||
4058 | case OID_SKGE_RX_INTR_CTS: | ||
4059 | /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ | ||
4060 | if (MacType == SK_MAC_XMAC) { | ||
4061 | /* Dual net mode */ | ||
4062 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4063 | Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts; | ||
4064 | } | ||
4065 | /* Single net mode */ | ||
4066 | else { | ||
4067 | Val64 = pAC->Pnmi.BufPort[0].RxIntrCts + | ||
4068 | pAC->Pnmi.BufPort[1].RxIntrCts; | ||
4069 | } | ||
4070 | } | ||
4071 | else { | ||
4072 | /* Dual net mode */ | ||
4073 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4074 | Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts; | ||
4075 | } | ||
4076 | /* Single net mode */ | ||
4077 | else { | ||
4078 | Val64 = pAC->Pnmi.Port[0].RxIntrCts + | ||
4079 | pAC->Pnmi.Port[1].RxIntrCts; | ||
4080 | } | ||
4081 | } | ||
4082 | SK_PNMI_STORE_U64(pBuf, Val64); | ||
4083 | *pLen = sizeof(SK_U64); | ||
4084 | break; | ||
4085 | |||
4086 | case OID_SKGE_TX_INTR_CTS: | ||
4087 | /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ | ||
4088 | if (MacType == SK_MAC_XMAC) { | ||
4089 | /* Dual net mode */ | ||
4090 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4091 | Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts; | ||
4092 | } | ||
4093 | /* Single net mode */ | ||
4094 | else { | ||
4095 | Val64 = pAC->Pnmi.BufPort[0].TxIntrCts + | ||
4096 | pAC->Pnmi.BufPort[1].TxIntrCts; | ||
4097 | } | ||
4098 | } | ||
4099 | else { | ||
4100 | /* Dual net mode */ | ||
4101 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4102 | Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts; | ||
4103 | } | ||
4104 | /* Single net mode */ | ||
4105 | else { | ||
4106 | Val64 = pAC->Pnmi.Port[0].TxIntrCts + | ||
4107 | pAC->Pnmi.Port[1].TxIntrCts; | ||
4108 | } | ||
4109 | } | ||
4110 | SK_PNMI_STORE_U64(pBuf, Val64); | ||
4111 | *pLen = sizeof(SK_U64); | ||
4112 | break; | ||
4113 | |||
4114 | case OID_SKGE_RX_NO_BUF_CTS: | ||
4115 | /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ | ||
4116 | if (MacType == SK_MAC_XMAC) { | ||
4117 | /* Dual net mode */ | ||
4118 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4119 | Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; | ||
4120 | } | ||
4121 | /* Single net mode */ | ||
4122 | else { | ||
4123 | Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts + | ||
4124 | pAC->Pnmi.BufPort[1].RxNoBufCts; | ||
4125 | } | ||
4126 | } | ||
4127 | else { | ||
4128 | /* Dual net mode */ | ||
4129 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4130 | Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts; | ||
4131 | } | ||
4132 | /* Single net mode */ | ||
4133 | else { | ||
4134 | Val64 = pAC->Pnmi.Port[0].RxNoBufCts + | ||
4135 | pAC->Pnmi.Port[1].RxNoBufCts; | ||
4136 | } | ||
4137 | } | ||
4138 | SK_PNMI_STORE_U64(pBuf, Val64); | ||
4139 | *pLen = sizeof(SK_U64); | ||
4140 | break; | ||
4141 | |||
4142 | case OID_SKGE_TX_NO_BUF_CTS: | ||
4143 | /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ | ||
4144 | if (MacType == SK_MAC_XMAC) { | ||
4145 | /* Dual net mode */ | ||
4146 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4147 | Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts; | ||
4148 | } | ||
4149 | /* Single net mode */ | ||
4150 | else { | ||
4151 | Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts + | ||
4152 | pAC->Pnmi.BufPort[1].TxNoBufCts; | ||
4153 | } | ||
4154 | } | ||
4155 | else { | ||
4156 | /* Dual net mode */ | ||
4157 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4158 | Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts; | ||
4159 | } | ||
4160 | /* Single net mode */ | ||
4161 | else { | ||
4162 | Val64 = pAC->Pnmi.Port[0].TxNoBufCts + | ||
4163 | pAC->Pnmi.Port[1].TxNoBufCts; | ||
4164 | } | ||
4165 | } | ||
4166 | SK_PNMI_STORE_U64(pBuf, Val64); | ||
4167 | *pLen = sizeof(SK_U64); | ||
4168 | break; | ||
4169 | |||
4170 | case OID_SKGE_TX_USED_DESCR_NO: | ||
4171 | /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ | ||
4172 | if (MacType == SK_MAC_XMAC) { | ||
4173 | /* Dual net mode */ | ||
4174 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4175 | Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo; | ||
4176 | } | ||
4177 | /* Single net mode */ | ||
4178 | else { | ||
4179 | Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo + | ||
4180 | pAC->Pnmi.BufPort[1].TxUsedDescrNo; | ||
4181 | } | ||
4182 | } | ||
4183 | else { | ||
4184 | /* Dual net mode */ | ||
4185 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4186 | Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo; | ||
4187 | } | ||
4188 | /* Single net mode */ | ||
4189 | else { | ||
4190 | Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo + | ||
4191 | pAC->Pnmi.Port[1].TxUsedDescrNo; | ||
4192 | } | ||
4193 | } | ||
4194 | SK_PNMI_STORE_U64(pBuf, Val64); | ||
4195 | *pLen = sizeof(SK_U64); | ||
4196 | break; | ||
4197 | |||
4198 | case OID_SKGE_RX_DELIVERED_CTS: | ||
4199 | /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ | ||
4200 | if (MacType == SK_MAC_XMAC) { | ||
4201 | /* Dual net mode */ | ||
4202 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4203 | Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts; | ||
4204 | } | ||
4205 | /* Single net mode */ | ||
4206 | else { | ||
4207 | Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts + | ||
4208 | pAC->Pnmi.BufPort[1].RxDeliveredCts; | ||
4209 | } | ||
4210 | } | ||
4211 | else { | ||
4212 | /* Dual net mode */ | ||
4213 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4214 | Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts; | ||
4215 | } | ||
4216 | /* Single net mode */ | ||
4217 | else { | ||
4218 | Val64 = pAC->Pnmi.Port[0].RxDeliveredCts + | ||
4219 | pAC->Pnmi.Port[1].RxDeliveredCts; | ||
4220 | } | ||
4221 | } | ||
4222 | SK_PNMI_STORE_U64(pBuf, Val64); | ||
4223 | *pLen = sizeof(SK_U64); | ||
4224 | break; | ||
4225 | |||
4226 | case OID_SKGE_RX_OCTETS_DELIV_CTS: | ||
4227 | /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ | ||
4228 | if (MacType == SK_MAC_XMAC) { | ||
4229 | /* Dual net mode */ | ||
4230 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4231 | Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts; | ||
4232 | } | ||
4233 | /* Single net mode */ | ||
4234 | else { | ||
4235 | Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts + | ||
4236 | pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts; | ||
4237 | } | ||
4238 | } | ||
4239 | else { | ||
4240 | /* Dual net mode */ | ||
4241 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4242 | Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts; | ||
4243 | } | ||
4244 | /* Single net mode */ | ||
4245 | else { | ||
4246 | Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts + | ||
4247 | pAC->Pnmi.Port[1].RxOctetsDeliveredCts; | ||
4248 | } | ||
4249 | } | ||
4250 | SK_PNMI_STORE_U64(pBuf, Val64); | ||
4251 | *pLen = sizeof(SK_U64); | ||
4252 | break; | ||
4253 | |||
4254 | case OID_SKGE_RX_HW_ERROR_CTS: | ||
4255 | SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs); | ||
4256 | *pLen = sizeof(SK_U64); | ||
4257 | break; | ||
4258 | |||
4259 | case OID_SKGE_TX_HW_ERROR_CTS: | ||
4260 | SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs); | ||
4261 | *pLen = sizeof(SK_U64); | ||
4262 | break; | ||
4263 | |||
4264 | case OID_SKGE_IN_ERRORS_CTS: | ||
4265 | /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ | ||
4266 | if (MacType == SK_MAC_XMAC) { | ||
4267 | /* Dual net mode */ | ||
4268 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4269 | Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; | ||
4270 | } | ||
4271 | /* Single net mode */ | ||
4272 | else { | ||
4273 | Val64 = Val64RxHwErrs + | ||
4274 | pAC->Pnmi.BufPort[0].RxNoBufCts + | ||
4275 | pAC->Pnmi.BufPort[1].RxNoBufCts; | ||
4276 | } | ||
4277 | } | ||
4278 | else { | ||
4279 | /* Dual net mode */ | ||
4280 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4281 | Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts; | ||
4282 | } | ||
4283 | /* Single net mode */ | ||
4284 | else { | ||
4285 | Val64 = Val64RxHwErrs + | ||
4286 | pAC->Pnmi.Port[0].RxNoBufCts + | ||
4287 | pAC->Pnmi.Port[1].RxNoBufCts; | ||
4288 | } | ||
4289 | } | ||
4290 | SK_PNMI_STORE_U64(pBuf, Val64); | ||
4291 | *pLen = sizeof(SK_U64); | ||
4292 | break; | ||
4293 | |||
4294 | case OID_SKGE_OUT_ERROR_CTS: | ||
4295 | /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ | ||
4296 | if (MacType == SK_MAC_XMAC) { | ||
4297 | /* Dual net mode */ | ||
4298 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4299 | Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts; | ||
4300 | } | ||
4301 | /* Single net mode */ | ||
4302 | else { | ||
4303 | Val64 = Val64TxHwErrs + | ||
4304 | pAC->Pnmi.BufPort[0].TxNoBufCts + | ||
4305 | pAC->Pnmi.BufPort[1].TxNoBufCts; | ||
4306 | } | ||
4307 | } | ||
4308 | else { | ||
4309 | /* Dual net mode */ | ||
4310 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4311 | Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts; | ||
4312 | } | ||
4313 | /* Single net mode */ | ||
4314 | else { | ||
4315 | Val64 = Val64TxHwErrs + | ||
4316 | pAC->Pnmi.Port[0].TxNoBufCts + | ||
4317 | pAC->Pnmi.Port[1].TxNoBufCts; | ||
4318 | } | ||
4319 | } | ||
4320 | SK_PNMI_STORE_U64(pBuf, Val64); | ||
4321 | *pLen = sizeof(SK_U64); | ||
4322 | break; | ||
4323 | |||
4324 | case OID_SKGE_ERR_RECOVERY_CTS: | ||
4325 | /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ | ||
4326 | if (MacType == SK_MAC_XMAC) { | ||
4327 | /* Dual net mode */ | ||
4328 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4329 | Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts; | ||
4330 | } | ||
4331 | /* Single net mode */ | ||
4332 | else { | ||
4333 | Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts + | ||
4334 | pAC->Pnmi.BufPort[1].ErrRecoveryCts; | ||
4335 | } | ||
4336 | } | ||
4337 | else { | ||
4338 | /* Dual net mode */ | ||
4339 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4340 | Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts; | ||
4341 | } | ||
4342 | /* Single net mode */ | ||
4343 | else { | ||
4344 | Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts + | ||
4345 | pAC->Pnmi.Port[1].ErrRecoveryCts; | ||
4346 | } | ||
4347 | } | ||
4348 | SK_PNMI_STORE_U64(pBuf, Val64); | ||
4349 | *pLen = sizeof(SK_U64); | ||
4350 | break; | ||
4351 | |||
4352 | case OID_SKGE_SYSUPTIME: | ||
4353 | Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC)); | ||
4354 | Val64 -= pAC->Pnmi.StartUpTime; | ||
4355 | SK_PNMI_STORE_U64(pBuf, Val64); | ||
4356 | *pLen = sizeof(SK_U64); | ||
4357 | break; | ||
4358 | |||
4359 | case OID_SKGE_MDB_VERSION: | ||
4360 | Val32 = SK_PNMI_MDB_VERSION; | ||
4361 | SK_PNMI_STORE_U32(pBuf, Val32); | ||
4362 | *pLen = sizeof(SK_U32); | ||
4363 | break; | ||
4364 | |||
4365 | case OID_GEN_RCV_ERROR: | ||
4366 | /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ | ||
4367 | if (MacType == SK_MAC_XMAC) { | ||
4368 | Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; | ||
4369 | } | ||
4370 | else { | ||
4371 | Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts; | ||
4372 | } | ||
4373 | |||
4374 | /* | ||
4375 | * by default 32bit values are evaluated | ||
4376 | */ | ||
4377 | if (!Is64BitReq) { | ||
4378 | Val32 = (SK_U32)Val64; | ||
4379 | SK_PNMI_STORE_U32(pBuf, Val32); | ||
4380 | *pLen = sizeof(SK_U32); | ||
4381 | } | ||
4382 | else { | ||
4383 | SK_PNMI_STORE_U64(pBuf, Val64); | ||
4384 | *pLen = sizeof(SK_U64); | ||
4385 | } | ||
4386 | break; | ||
4387 | |||
4388 | case OID_GEN_XMIT_ERROR: | ||
4389 | /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ | ||
4390 | if (MacType == SK_MAC_XMAC) { | ||
4391 | Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts; | ||
4392 | } | ||
4393 | else { | ||
4394 | Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts; | ||
4395 | } | ||
4396 | |||
4397 | /* | ||
4398 | * by default 32bit values are evaluated | ||
4399 | */ | ||
4400 | if (!Is64BitReq) { | ||
4401 | Val32 = (SK_U32)Val64; | ||
4402 | SK_PNMI_STORE_U32(pBuf, Val32); | ||
4403 | *pLen = sizeof(SK_U32); | ||
4404 | } | ||
4405 | else { | ||
4406 | SK_PNMI_STORE_U64(pBuf, Val64); | ||
4407 | *pLen = sizeof(SK_U64); | ||
4408 | } | ||
4409 | break; | ||
4410 | |||
4411 | case OID_GEN_RCV_NO_BUFFER: | ||
4412 | /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ | ||
4413 | if (MacType == SK_MAC_XMAC) { | ||
4414 | Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; | ||
4415 | } | ||
4416 | else { | ||
4417 | Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts; | ||
4418 | } | ||
4419 | |||
4420 | /* | ||
4421 | * by default 32bit values are evaluated | ||
4422 | */ | ||
4423 | if (!Is64BitReq) { | ||
4424 | Val32 = (SK_U32)Val64; | ||
4425 | SK_PNMI_STORE_U32(pBuf, Val32); | ||
4426 | *pLen = sizeof(SK_U32); | ||
4427 | } | ||
4428 | else { | ||
4429 | SK_PNMI_STORE_U64(pBuf, Val64); | ||
4430 | *pLen = sizeof(SK_U64); | ||
4431 | } | ||
4432 | break; | ||
4433 | |||
4434 | case OID_GEN_TRANSMIT_QUEUE_LENGTH: | ||
4435 | Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen; | ||
4436 | SK_PNMI_STORE_U32(pBuf, Val32); | ||
4437 | *pLen = sizeof(SK_U32); | ||
4438 | break; | ||
4439 | |||
4440 | default: | ||
4441 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034, | ||
4442 | SK_PNMI_ERR034MSG); | ||
4443 | |||
4444 | *pLen = 0; | ||
4445 | return (SK_PNMI_ERR_GENERAL); | ||
4446 | } | ||
4447 | |||
4448 | if (Id == OID_SKGE_RX_HW_ERROR_CTS || | ||
4449 | Id == OID_SKGE_TX_HW_ERROR_CTS || | ||
4450 | Id == OID_SKGE_IN_ERRORS_CTS || | ||
4451 | Id == OID_SKGE_OUT_ERROR_CTS || | ||
4452 | Id == OID_GEN_XMIT_ERROR || | ||
4453 | Id == OID_GEN_RCV_ERROR) { | ||
4454 | |||
4455 | pAC->Pnmi.MacUpdatedFlag --; | ||
4456 | } | ||
4457 | |||
4458 | return (SK_PNMI_ERR_OK); | ||
4459 | } | ||
4460 | |||
4461 | /***************************************************************************** | ||
4462 | * | ||
4463 | * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance. | ||
4464 | * | ||
4465 | * Description: | ||
4466 | * Get/Presets/Sets the RLMT OIDs. | ||
4467 | * | ||
4468 | * Returns: | ||
4469 | * SK_PNMI_ERR_OK The request was successfully performed. | ||
4470 | * SK_PNMI_ERR_GENERAL A general severe internal error occured. | ||
4471 | * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain | ||
4472 | * the correct data (e.g. a 32bit value is | ||
4473 | * needed, but a 16 bit value was passed). | ||
4474 | * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid | ||
4475 | * value range. | ||
4476 | * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. | ||
4477 | * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't | ||
4478 | * exist (e.g. port instance 3 on a two port | ||
4479 | * adapter. | ||
4480 | */ | ||
4481 | PNMI_STATIC int Rlmt( | ||
4482 | SK_AC *pAC, /* Pointer to adapter context */ | ||
4483 | SK_IOC IoC, /* IO context handle */ | ||
4484 | int Action, /* GET/PRESET/SET action */ | ||
4485 | SK_U32 Id, /* Object ID that is to be processed */ | ||
4486 | char *pBuf, /* Buffer used for the management data transfer */ | ||
4487 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
4488 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
4489 | unsigned int TableIndex, /* Index to the Id table */ | ||
4490 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
4491 | { | ||
4492 | int Ret; | ||
4493 | unsigned int PhysPortIndex; | ||
4494 | unsigned int PhysPortMax; | ||
4495 | SK_EVPARA EventParam; | ||
4496 | SK_U32 Val32; | ||
4497 | SK_U64 Val64; | ||
4498 | |||
4499 | |||
4500 | /* | ||
4501 | * Check instance. Only single instance OIDs are allowed here. | ||
4502 | */ | ||
4503 | if (Instance != (SK_U32)(-1) && Instance != 1) { | ||
4504 | |||
4505 | *pLen = 0; | ||
4506 | return (SK_PNMI_ERR_UNKNOWN_INST); | ||
4507 | } | ||
4508 | |||
4509 | /* | ||
4510 | * Perform the requested action. | ||
4511 | */ | ||
4512 | if (Action == SK_PNMI_GET) { | ||
4513 | |||
4514 | /* | ||
4515 | * Check if the buffer length is large enough. | ||
4516 | */ | ||
4517 | |||
4518 | switch (Id) { | ||
4519 | |||
4520 | case OID_SKGE_RLMT_MODE: | ||
4521 | case OID_SKGE_RLMT_PORT_ACTIVE: | ||
4522 | case OID_SKGE_RLMT_PORT_PREFERRED: | ||
4523 | if (*pLen < sizeof(SK_U8)) { | ||
4524 | |||
4525 | *pLen = sizeof(SK_U8); | ||
4526 | return (SK_PNMI_ERR_TOO_SHORT); | ||
4527 | } | ||
4528 | break; | ||
4529 | |||
4530 | case OID_SKGE_RLMT_PORT_NUMBER: | ||
4531 | if (*pLen < sizeof(SK_U32)) { | ||
4532 | |||
4533 | *pLen = sizeof(SK_U32); | ||
4534 | return (SK_PNMI_ERR_TOO_SHORT); | ||
4535 | } | ||
4536 | break; | ||
4537 | |||
4538 | case OID_SKGE_RLMT_CHANGE_CTS: | ||
4539 | case OID_SKGE_RLMT_CHANGE_TIME: | ||
4540 | case OID_SKGE_RLMT_CHANGE_ESTIM: | ||
4541 | case OID_SKGE_RLMT_CHANGE_THRES: | ||
4542 | if (*pLen < sizeof(SK_U64)) { | ||
4543 | |||
4544 | *pLen = sizeof(SK_U64); | ||
4545 | return (SK_PNMI_ERR_TOO_SHORT); | ||
4546 | } | ||
4547 | break; | ||
4548 | |||
4549 | default: | ||
4550 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035, | ||
4551 | SK_PNMI_ERR035MSG); | ||
4552 | |||
4553 | *pLen = 0; | ||
4554 | return (SK_PNMI_ERR_GENERAL); | ||
4555 | } | ||
4556 | |||
4557 | /* | ||
4558 | * Update RLMT statistic and increment semaphores to indicate | ||
4559 | * that an update was already done. Maybe RLMT will hold its | ||
4560 | * statistic always up to date some time. Then we can | ||
4561 | * remove this type of call. | ||
4562 | */ | ||
4563 | if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) { | ||
4564 | |||
4565 | *pLen = 0; | ||
4566 | return (Ret); | ||
4567 | } | ||
4568 | pAC->Pnmi.RlmtUpdatedFlag ++; | ||
4569 | |||
4570 | /* | ||
4571 | * Retrieve Value | ||
4572 | */ | ||
4573 | switch (Id) { | ||
4574 | |||
4575 | case OID_SKGE_RLMT_MODE: | ||
4576 | *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode; | ||
4577 | *pLen = sizeof(char); | ||
4578 | break; | ||
4579 | |||
4580 | case OID_SKGE_RLMT_PORT_NUMBER: | ||
4581 | Val32 = (SK_U32)pAC->GIni.GIMacsFound; | ||
4582 | SK_PNMI_STORE_U32(pBuf, Val32); | ||
4583 | *pLen = sizeof(SK_U32); | ||
4584 | break; | ||
4585 | |||
4586 | case OID_SKGE_RLMT_PORT_ACTIVE: | ||
4587 | *pBuf = 0; | ||
4588 | /* | ||
4589 | * If multiple ports may become active this OID | ||
4590 | * doesn't make sense any more. A new variable in | ||
4591 | * the port structure should be created. However, | ||
4592 | * for this variable the first active port is | ||
4593 | * returned. | ||
4594 | */ | ||
4595 | PhysPortMax = pAC->GIni.GIMacsFound; | ||
4596 | |||
4597 | for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; | ||
4598 | PhysPortIndex ++) { | ||
4599 | |||
4600 | if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { | ||
4601 | |||
4602 | *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex); | ||
4603 | break; | ||
4604 | } | ||
4605 | } | ||
4606 | *pLen = sizeof(char); | ||
4607 | break; | ||
4608 | |||
4609 | case OID_SKGE_RLMT_PORT_PREFERRED: | ||
4610 | *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference); | ||
4611 | *pLen = sizeof(char); | ||
4612 | break; | ||
4613 | |||
4614 | case OID_SKGE_RLMT_CHANGE_CTS: | ||
4615 | Val64 = pAC->Pnmi.RlmtChangeCts; | ||
4616 | SK_PNMI_STORE_U64(pBuf, Val64); | ||
4617 | *pLen = sizeof(SK_U64); | ||
4618 | break; | ||
4619 | |||
4620 | case OID_SKGE_RLMT_CHANGE_TIME: | ||
4621 | Val64 = pAC->Pnmi.RlmtChangeTime; | ||
4622 | SK_PNMI_STORE_U64(pBuf, Val64); | ||
4623 | *pLen = sizeof(SK_U64); | ||
4624 | break; | ||
4625 | |||
4626 | case OID_SKGE_RLMT_CHANGE_ESTIM: | ||
4627 | Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate; | ||
4628 | SK_PNMI_STORE_U64(pBuf, Val64); | ||
4629 | *pLen = sizeof(SK_U64); | ||
4630 | break; | ||
4631 | |||
4632 | case OID_SKGE_RLMT_CHANGE_THRES: | ||
4633 | Val64 = pAC->Pnmi.RlmtChangeThreshold; | ||
4634 | SK_PNMI_STORE_U64(pBuf, Val64); | ||
4635 | *pLen = sizeof(SK_U64); | ||
4636 | break; | ||
4637 | |||
4638 | default: | ||
4639 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, | ||
4640 | ("Rlmt: Unknown OID should be handled before")); | ||
4641 | |||
4642 | pAC->Pnmi.RlmtUpdatedFlag --; | ||
4643 | *pLen = 0; | ||
4644 | return (SK_PNMI_ERR_GENERAL); | ||
4645 | } | ||
4646 | |||
4647 | pAC->Pnmi.RlmtUpdatedFlag --; | ||
4648 | } | ||
4649 | else { | ||
4650 | /* Perform a preset or set */ | ||
4651 | switch (Id) { | ||
4652 | |||
4653 | case OID_SKGE_RLMT_MODE: | ||
4654 | /* Check if the buffer length is plausible */ | ||
4655 | if (*pLen < sizeof(char)) { | ||
4656 | |||
4657 | *pLen = sizeof(char); | ||
4658 | return (SK_PNMI_ERR_TOO_SHORT); | ||
4659 | } | ||
4660 | /* Check if the value range is correct */ | ||
4661 | if (*pLen != sizeof(char) || | ||
4662 | (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 || | ||
4663 | *(SK_U8 *)pBuf > 15) { | ||
4664 | |||
4665 | *pLen = 0; | ||
4666 | return (SK_PNMI_ERR_BAD_VALUE); | ||
4667 | } | ||
4668 | /* The preset ends here */ | ||
4669 | if (Action == SK_PNMI_PRESET) { | ||
4670 | |||
4671 | *pLen = 0; | ||
4672 | return (SK_PNMI_ERR_OK); | ||
4673 | } | ||
4674 | /* Send an event to RLMT to change the mode */ | ||
4675 | SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); | ||
4676 | EventParam.Para32[0] |= (SK_U32)(*pBuf); | ||
4677 | EventParam.Para32[1] = 0; | ||
4678 | if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE, | ||
4679 | EventParam) > 0) { | ||
4680 | |||
4681 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037, | ||
4682 | SK_PNMI_ERR037MSG); | ||
4683 | |||
4684 | *pLen = 0; | ||
4685 | return (SK_PNMI_ERR_GENERAL); | ||
4686 | } | ||
4687 | break; | ||
4688 | |||
4689 | case OID_SKGE_RLMT_PORT_PREFERRED: | ||
4690 | /* Check if the buffer length is plausible */ | ||
4691 | if (*pLen < sizeof(char)) { | ||
4692 | |||
4693 | *pLen = sizeof(char); | ||
4694 | return (SK_PNMI_ERR_TOO_SHORT); | ||
4695 | } | ||
4696 | /* Check if the value range is correct */ | ||
4697 | if (*pLen != sizeof(char) || *(SK_U8 *)pBuf > | ||
4698 | (SK_U8)pAC->GIni.GIMacsFound) { | ||
4699 | |||
4700 | *pLen = 0; | ||
4701 | return (SK_PNMI_ERR_BAD_VALUE); | ||
4702 | } | ||
4703 | /* The preset ends here */ | ||
4704 | if (Action == SK_PNMI_PRESET) { | ||
4705 | |||
4706 | *pLen = 0; | ||
4707 | return (SK_PNMI_ERR_OK); | ||
4708 | } | ||
4709 | |||
4710 | /* | ||
4711 | * Send an event to RLMT change the preferred port. | ||
4712 | * A param of -1 means automatic mode. RLMT will | ||
4713 | * make the decision which is the preferred port. | ||
4714 | */ | ||
4715 | SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); | ||
4716 | EventParam.Para32[0] = (SK_U32)(*pBuf) - 1; | ||
4717 | EventParam.Para32[1] = NetIndex; | ||
4718 | if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE, | ||
4719 | EventParam) > 0) { | ||
4720 | |||
4721 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038, | ||
4722 | SK_PNMI_ERR038MSG); | ||
4723 | |||
4724 | *pLen = 0; | ||
4725 | return (SK_PNMI_ERR_GENERAL); | ||
4726 | } | ||
4727 | break; | ||
4728 | |||
4729 | case OID_SKGE_RLMT_CHANGE_THRES: | ||
4730 | /* Check if the buffer length is plausible */ | ||
4731 | if (*pLen < sizeof(SK_U64)) { | ||
4732 | |||
4733 | *pLen = sizeof(SK_U64); | ||
4734 | return (SK_PNMI_ERR_TOO_SHORT); | ||
4735 | } | ||
4736 | /* | ||
4737 | * There are not many restrictions to the | ||
4738 | * value range. | ||
4739 | */ | ||
4740 | if (*pLen != sizeof(SK_U64)) { | ||
4741 | |||
4742 | *pLen = 0; | ||
4743 | return (SK_PNMI_ERR_BAD_VALUE); | ||
4744 | } | ||
4745 | /* A preset ends here */ | ||
4746 | if (Action == SK_PNMI_PRESET) { | ||
4747 | |||
4748 | *pLen = 0; | ||
4749 | return (SK_PNMI_ERR_OK); | ||
4750 | } | ||
4751 | /* | ||
4752 | * Store the new threshold, which will be taken | ||
4753 | * on the next timer event. | ||
4754 | */ | ||
4755 | SK_PNMI_READ_U64(pBuf, Val64); | ||
4756 | pAC->Pnmi.RlmtChangeThreshold = Val64; | ||
4757 | break; | ||
4758 | |||
4759 | default: | ||
4760 | /* The other OIDs are not be able for set */ | ||
4761 | *pLen = 0; | ||
4762 | return (SK_PNMI_ERR_READ_ONLY); | ||
4763 | } | ||
4764 | } | ||
4765 | |||
4766 | return (SK_PNMI_ERR_OK); | ||
4767 | } | ||
4768 | |||
4769 | /***************************************************************************** | ||
4770 | * | ||
4771 | * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance. | ||
4772 | * | ||
4773 | * Description: | ||
4774 | * Performs get requests on multiple instance variables. | ||
4775 | * | ||
4776 | * Returns: | ||
4777 | * SK_PNMI_ERR_OK The request was successfully performed. | ||
4778 | * SK_PNMI_ERR_GENERAL A general severe internal error occured. | ||
4779 | * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain | ||
4780 | * the correct data (e.g. a 32bit value is | ||
4781 | * needed, but a 16 bit value was passed). | ||
4782 | * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't | ||
4783 | * exist (e.g. port instance 3 on a two port | ||
4784 | * adapter. | ||
4785 | */ | ||
4786 | PNMI_STATIC int RlmtStat( | ||
4787 | SK_AC *pAC, /* Pointer to adapter context */ | ||
4788 | SK_IOC IoC, /* IO context handle */ | ||
4789 | int Action, /* GET/PRESET/SET action */ | ||
4790 | SK_U32 Id, /* Object ID that is to be processed */ | ||
4791 | char *pBuf, /* Buffer used for the management data transfer */ | ||
4792 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
4793 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
4794 | unsigned int TableIndex, /* Index to the Id table */ | ||
4795 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
4796 | { | ||
4797 | unsigned int PhysPortMax; | ||
4798 | unsigned int PhysPortIndex; | ||
4799 | unsigned int Limit; | ||
4800 | unsigned int Offset; | ||
4801 | int Ret; | ||
4802 | SK_U32 Val32; | ||
4803 | SK_U64 Val64; | ||
4804 | |||
4805 | /* | ||
4806 | * Calculate the port indexes from the instance. | ||
4807 | */ | ||
4808 | PhysPortMax = pAC->GIni.GIMacsFound; | ||
4809 | |||
4810 | if ((Instance != (SK_U32)(-1))) { | ||
4811 | /* Check instance range */ | ||
4812 | if ((Instance < 1) || (Instance > PhysPortMax)) { | ||
4813 | |||
4814 | *pLen = 0; | ||
4815 | return (SK_PNMI_ERR_UNKNOWN_INST); | ||
4816 | } | ||
4817 | |||
4818 | /* Single net mode */ | ||
4819 | PhysPortIndex = Instance - 1; | ||
4820 | |||
4821 | /* Dual net mode */ | ||
4822 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4823 | PhysPortIndex = NetIndex; | ||
4824 | } | ||
4825 | |||
4826 | /* Both net modes */ | ||
4827 | Limit = PhysPortIndex + 1; | ||
4828 | } | ||
4829 | else { | ||
4830 | /* Single net mode */ | ||
4831 | PhysPortIndex = 0; | ||
4832 | Limit = PhysPortMax; | ||
4833 | |||
4834 | /* Dual net mode */ | ||
4835 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
4836 | PhysPortIndex = NetIndex; | ||
4837 | Limit = PhysPortIndex + 1; | ||
4838 | } | ||
4839 | } | ||
4840 | |||
4841 | /* | ||
4842 | * Currently only get requests are allowed. | ||
4843 | */ | ||
4844 | if (Action != SK_PNMI_GET) { | ||
4845 | |||
4846 | *pLen = 0; | ||
4847 | return (SK_PNMI_ERR_READ_ONLY); | ||
4848 | } | ||
4849 | |||
4850 | /* | ||
4851 | * Check if the buffer length is large enough. | ||
4852 | */ | ||
4853 | switch (Id) { | ||
4854 | |||
4855 | case OID_SKGE_RLMT_PORT_INDEX: | ||
4856 | case OID_SKGE_RLMT_STATUS: | ||
4857 | if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) { | ||
4858 | |||
4859 | *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32); | ||
4860 | return (SK_PNMI_ERR_TOO_SHORT); | ||
4861 | } | ||
4862 | break; | ||
4863 | |||
4864 | case OID_SKGE_RLMT_TX_HELLO_CTS: | ||
4865 | case OID_SKGE_RLMT_RX_HELLO_CTS: | ||
4866 | case OID_SKGE_RLMT_TX_SP_REQ_CTS: | ||
4867 | case OID_SKGE_RLMT_RX_SP_CTS: | ||
4868 | if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) { | ||
4869 | |||
4870 | *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64); | ||
4871 | return (SK_PNMI_ERR_TOO_SHORT); | ||
4872 | } | ||
4873 | break; | ||
4874 | |||
4875 | default: | ||
4876 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039, | ||
4877 | SK_PNMI_ERR039MSG); | ||
4878 | |||
4879 | *pLen = 0; | ||
4880 | return (SK_PNMI_ERR_GENERAL); | ||
4881 | |||
4882 | } | ||
4883 | |||
4884 | /* | ||
4885 | * Update statistic and increment semaphores to indicate that | ||
4886 | * an update was already done. | ||
4887 | */ | ||
4888 | if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) { | ||
4889 | |||
4890 | *pLen = 0; | ||
4891 | return (Ret); | ||
4892 | } | ||
4893 | pAC->Pnmi.RlmtUpdatedFlag ++; | ||
4894 | |||
4895 | /* | ||
4896 | * Get value | ||
4897 | */ | ||
4898 | Offset = 0; | ||
4899 | for (; PhysPortIndex < Limit; PhysPortIndex ++) { | ||
4900 | |||
4901 | switch (Id) { | ||
4902 | |||
4903 | case OID_SKGE_RLMT_PORT_INDEX: | ||
4904 | Val32 = PhysPortIndex; | ||
4905 | SK_PNMI_STORE_U32(pBuf + Offset, Val32); | ||
4906 | Offset += sizeof(SK_U32); | ||
4907 | break; | ||
4908 | |||
4909 | case OID_SKGE_RLMT_STATUS: | ||
4910 | if (pAC->Rlmt.Port[PhysPortIndex].PortState == | ||
4911 | SK_RLMT_PS_INIT || | ||
4912 | pAC->Rlmt.Port[PhysPortIndex].PortState == | ||
4913 | SK_RLMT_PS_DOWN) { | ||
4914 | |||
4915 | Val32 = SK_PNMI_RLMT_STATUS_ERROR; | ||
4916 | } | ||
4917 | else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { | ||
4918 | |||
4919 | Val32 = SK_PNMI_RLMT_STATUS_ACTIVE; | ||
4920 | } | ||
4921 | else { | ||
4922 | Val32 = SK_PNMI_RLMT_STATUS_STANDBY; | ||
4923 | } | ||
4924 | SK_PNMI_STORE_U32(pBuf + Offset, Val32); | ||
4925 | Offset += sizeof(SK_U32); | ||
4926 | break; | ||
4927 | |||
4928 | case OID_SKGE_RLMT_TX_HELLO_CTS: | ||
4929 | Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts; | ||
4930 | SK_PNMI_STORE_U64(pBuf + Offset, Val64); | ||
4931 | Offset += sizeof(SK_U64); | ||
4932 | break; | ||
4933 | |||
4934 | case OID_SKGE_RLMT_RX_HELLO_CTS: | ||
4935 | Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts; | ||
4936 | SK_PNMI_STORE_U64(pBuf + Offset, Val64); | ||
4937 | Offset += sizeof(SK_U64); | ||
4938 | break; | ||
4939 | |||
4940 | case OID_SKGE_RLMT_TX_SP_REQ_CTS: | ||
4941 | Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts; | ||
4942 | SK_PNMI_STORE_U64(pBuf + Offset, Val64); | ||
4943 | Offset += sizeof(SK_U64); | ||
4944 | break; | ||
4945 | |||
4946 | case OID_SKGE_RLMT_RX_SP_CTS: | ||
4947 | Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts; | ||
4948 | SK_PNMI_STORE_U64(pBuf + Offset, Val64); | ||
4949 | Offset += sizeof(SK_U64); | ||
4950 | break; | ||
4951 | |||
4952 | default: | ||
4953 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, | ||
4954 | ("RlmtStat: Unknown OID should be errored before")); | ||
4955 | |||
4956 | pAC->Pnmi.RlmtUpdatedFlag --; | ||
4957 | *pLen = 0; | ||
4958 | return (SK_PNMI_ERR_GENERAL); | ||
4959 | } | ||
4960 | } | ||
4961 | *pLen = Offset; | ||
4962 | |||
4963 | pAC->Pnmi.RlmtUpdatedFlag --; | ||
4964 | |||
4965 | return (SK_PNMI_ERR_OK); | ||
4966 | } | ||
4967 | |||
4968 | /***************************************************************************** | ||
4969 | * | ||
4970 | * MacPrivateConf - OID handler function of OIDs concerning the configuration | ||
4971 | * | ||
4972 | * Description: | ||
4973 | * Get/Presets/Sets the OIDs concerning the configuration. | ||
4974 | * | ||
4975 | * Returns: | ||
4976 | * SK_PNMI_ERR_OK The request was successfully performed. | ||
4977 | * SK_PNMI_ERR_GENERAL A general severe internal error occured. | ||
4978 | * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain | ||
4979 | * the correct data (e.g. a 32bit value is | ||
4980 | * needed, but a 16 bit value was passed). | ||
4981 | * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid | ||
4982 | * value range. | ||
4983 | * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. | ||
4984 | * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't | ||
4985 | * exist (e.g. port instance 3 on a two port | ||
4986 | * adapter. | ||
4987 | */ | ||
4988 | PNMI_STATIC int MacPrivateConf( | ||
4989 | SK_AC *pAC, /* Pointer to adapter context */ | ||
4990 | SK_IOC IoC, /* IO context handle */ | ||
4991 | int Action, /* GET/PRESET/SET action */ | ||
4992 | SK_U32 Id, /* Object ID that is to be processed */ | ||
4993 | char *pBuf, /* Buffer used for the management data transfer */ | ||
4994 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
4995 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
4996 | unsigned int TableIndex, /* Index to the Id table */ | ||
4997 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
4998 | { | ||
4999 | unsigned int PhysPortMax; | ||
5000 | unsigned int PhysPortIndex; | ||
5001 | unsigned int LogPortMax; | ||
5002 | unsigned int LogPortIndex; | ||
5003 | unsigned int Limit; | ||
5004 | unsigned int Offset; | ||
5005 | char Val8; | ||
5006 | char *pBufPtr; | ||
5007 | int Ret; | ||
5008 | SK_EVPARA EventParam; | ||
5009 | SK_U32 Val32; | ||
5010 | |||
5011 | /* | ||
5012 | * Calculate instance if wished. MAC index 0 is the virtual MAC. | ||
5013 | */ | ||
5014 | PhysPortMax = pAC->GIni.GIMacsFound; | ||
5015 | LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); | ||
5016 | |||
5017 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */ | ||
5018 | LogPortMax--; | ||
5019 | } | ||
5020 | |||
5021 | if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */ | ||
5022 | /* Check instance range */ | ||
5023 | if ((Instance < 1) || (Instance > LogPortMax)) { | ||
5024 | |||
5025 | *pLen = 0; | ||
5026 | return (SK_PNMI_ERR_UNKNOWN_INST); | ||
5027 | } | ||
5028 | LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance); | ||
5029 | Limit = LogPortIndex + 1; | ||
5030 | } | ||
5031 | |||
5032 | else { /* Instance == (SK_U32)(-1), get all Instances of that OID */ | ||
5033 | |||
5034 | LogPortIndex = 0; | ||
5035 | Limit = LogPortMax; | ||
5036 | } | ||
5037 | |||
5038 | /* | ||
5039 | * Perform action | ||
5040 | */ | ||
5041 | if (Action == SK_PNMI_GET) { | ||
5042 | |||
5043 | /* Check length */ | ||
5044 | switch (Id) { | ||
5045 | |||
5046 | case OID_SKGE_PMD: | ||
5047 | case OID_SKGE_CONNECTOR: | ||
5048 | case OID_SKGE_LINK_CAP: | ||
5049 | case OID_SKGE_LINK_MODE: | ||
5050 | case OID_SKGE_LINK_MODE_STATUS: | ||
5051 | case OID_SKGE_LINK_STATUS: | ||
5052 | case OID_SKGE_FLOWCTRL_CAP: | ||
5053 | case OID_SKGE_FLOWCTRL_MODE: | ||
5054 | case OID_SKGE_FLOWCTRL_STATUS: | ||
5055 | case OID_SKGE_PHY_OPERATION_CAP: | ||
5056 | case OID_SKGE_PHY_OPERATION_MODE: | ||
5057 | case OID_SKGE_PHY_OPERATION_STATUS: | ||
5058 | case OID_SKGE_SPEED_CAP: | ||
5059 | case OID_SKGE_SPEED_MODE: | ||
5060 | case OID_SKGE_SPEED_STATUS: | ||
5061 | if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) { | ||
5062 | |||
5063 | *pLen = (Limit - LogPortIndex) * sizeof(SK_U8); | ||
5064 | return (SK_PNMI_ERR_TOO_SHORT); | ||
5065 | } | ||
5066 | break; | ||
5067 | |||
5068 | case OID_SKGE_MTU: | ||
5069 | case OID_SKGE_PHY_TYPE: | ||
5070 | if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) { | ||
5071 | |||
5072 | *pLen = (Limit - LogPortIndex) * sizeof(SK_U32); | ||
5073 | return (SK_PNMI_ERR_TOO_SHORT); | ||
5074 | } | ||
5075 | break; | ||
5076 | |||
5077 | default: | ||
5078 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041, | ||
5079 | SK_PNMI_ERR041MSG); | ||
5080 | *pLen = 0; | ||
5081 | return (SK_PNMI_ERR_GENERAL); | ||
5082 | } | ||
5083 | |||
5084 | /* | ||
5085 | * Update statistic and increment semaphore to indicate | ||
5086 | * that an update was already done. | ||
5087 | */ | ||
5088 | if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) { | ||
5089 | |||
5090 | *pLen = 0; | ||
5091 | return (Ret); | ||
5092 | } | ||
5093 | pAC->Pnmi.SirqUpdatedFlag ++; | ||
5094 | |||
5095 | /* | ||
5096 | * Get value | ||
5097 | */ | ||
5098 | Offset = 0; | ||
5099 | for (; LogPortIndex < Limit; LogPortIndex ++) { | ||
5100 | |||
5101 | pBufPtr = pBuf + Offset; | ||
5102 | |||
5103 | switch (Id) { | ||
5104 | |||
5105 | case OID_SKGE_PMD: | ||
5106 | *pBufPtr = pAC->Pnmi.PMD; | ||
5107 | Offset += sizeof(char); | ||
5108 | break; | ||
5109 | |||
5110 | case OID_SKGE_CONNECTOR: | ||
5111 | *pBufPtr = pAC->Pnmi.Connector; | ||
5112 | Offset += sizeof(char); | ||
5113 | break; | ||
5114 | |||
5115 | case OID_SKGE_PHY_TYPE: | ||
5116 | if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ | ||
5117 | if (LogPortIndex == 0) { | ||
5118 | continue; | ||
5119 | } | ||
5120 | else { | ||
5121 | /* Get value for physical ports */ | ||
5122 | PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( | ||
5123 | pAC, LogPortIndex); | ||
5124 | Val32 = pAC->GIni.GP[PhysPortIndex].PhyType; | ||
5125 | SK_PNMI_STORE_U32(pBufPtr, Val32); | ||
5126 | } | ||
5127 | } | ||
5128 | else { /* DualNetMode */ | ||
5129 | |||
5130 | Val32 = pAC->GIni.GP[NetIndex].PhyType; | ||
5131 | SK_PNMI_STORE_U32(pBufPtr, Val32); | ||
5132 | } | ||
5133 | Offset += sizeof(SK_U32); | ||
5134 | break; | ||
5135 | |||
5136 | case OID_SKGE_LINK_CAP: | ||
5137 | if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ | ||
5138 | if (LogPortIndex == 0) { | ||
5139 | /* Get value for virtual port */ | ||
5140 | VirtualConf(pAC, IoC, Id, pBufPtr); | ||
5141 | } | ||
5142 | else { | ||
5143 | /* Get value for physical ports */ | ||
5144 | PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( | ||
5145 | pAC, LogPortIndex); | ||
5146 | |||
5147 | *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkCap; | ||
5148 | } | ||
5149 | } | ||
5150 | else { /* DualNetMode */ | ||
5151 | |||
5152 | *pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap; | ||
5153 | } | ||
5154 | Offset += sizeof(char); | ||
5155 | break; | ||
5156 | |||
5157 | case OID_SKGE_LINK_MODE: | ||
5158 | if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ | ||
5159 | if (LogPortIndex == 0) { | ||
5160 | /* Get value for virtual port */ | ||
5161 | VirtualConf(pAC, IoC, Id, pBufPtr); | ||
5162 | } | ||
5163 | else { | ||
5164 | /* Get value for physical ports */ | ||
5165 | PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( | ||
5166 | pAC, LogPortIndex); | ||
5167 | |||
5168 | *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkModeConf; | ||
5169 | } | ||
5170 | } | ||
5171 | else { /* DualNetMode */ | ||
5172 | |||
5173 | *pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf; | ||
5174 | } | ||
5175 | Offset += sizeof(char); | ||
5176 | break; | ||
5177 | |||
5178 | case OID_SKGE_LINK_MODE_STATUS: | ||
5179 | if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ | ||
5180 | if (LogPortIndex == 0) { | ||
5181 | /* Get value for virtual port */ | ||
5182 | VirtualConf(pAC, IoC, Id, pBufPtr); | ||
5183 | } | ||
5184 | else { | ||
5185 | /* Get value for physical port */ | ||
5186 | PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( | ||
5187 | pAC, LogPortIndex); | ||
5188 | |||
5189 | *pBufPtr = | ||
5190 | CalculateLinkModeStatus(pAC, IoC, PhysPortIndex); | ||
5191 | } | ||
5192 | } | ||
5193 | else { /* DualNetMode */ | ||
5194 | |||
5195 | *pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex); | ||
5196 | } | ||
5197 | Offset += sizeof(char); | ||
5198 | break; | ||
5199 | |||
5200 | case OID_SKGE_LINK_STATUS: | ||
5201 | if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ | ||
5202 | if (LogPortIndex == 0) { | ||
5203 | /* Get value for virtual port */ | ||
5204 | VirtualConf(pAC, IoC, Id, pBufPtr); | ||
5205 | } | ||
5206 | else { | ||
5207 | /* Get value for physical ports */ | ||
5208 | PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( | ||
5209 | pAC, LogPortIndex); | ||
5210 | |||
5211 | *pBufPtr = CalculateLinkStatus(pAC, IoC, PhysPortIndex); | ||
5212 | } | ||
5213 | } | ||
5214 | else { /* DualNetMode */ | ||
5215 | |||
5216 | *pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex); | ||
5217 | } | ||
5218 | Offset += sizeof(char); | ||
5219 | break; | ||
5220 | |||
5221 | case OID_SKGE_FLOWCTRL_CAP: | ||
5222 | if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ | ||
5223 | if (LogPortIndex == 0) { | ||
5224 | /* Get value for virtual port */ | ||
5225 | VirtualConf(pAC, IoC, Id, pBufPtr); | ||
5226 | } | ||
5227 | else { | ||
5228 | /* Get value for physical ports */ | ||
5229 | PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( | ||
5230 | pAC, LogPortIndex); | ||
5231 | |||
5232 | *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap; | ||
5233 | } | ||
5234 | } | ||
5235 | else { /* DualNetMode */ | ||
5236 | |||
5237 | *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap; | ||
5238 | } | ||
5239 | Offset += sizeof(char); | ||
5240 | break; | ||
5241 | |||
5242 | case OID_SKGE_FLOWCTRL_MODE: | ||
5243 | if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ | ||
5244 | if (LogPortIndex == 0) { | ||
5245 | /* Get value for virtual port */ | ||
5246 | VirtualConf(pAC, IoC, Id, pBufPtr); | ||
5247 | } | ||
5248 | else { | ||
5249 | /* Get value for physical port */ | ||
5250 | PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( | ||
5251 | pAC, LogPortIndex); | ||
5252 | |||
5253 | *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode; | ||
5254 | } | ||
5255 | } | ||
5256 | else { /* DualNetMode */ | ||
5257 | |||
5258 | *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode; | ||
5259 | } | ||
5260 | Offset += sizeof(char); | ||
5261 | break; | ||
5262 | |||
5263 | case OID_SKGE_FLOWCTRL_STATUS: | ||
5264 | if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ | ||
5265 | if (LogPortIndex == 0) { | ||
5266 | /* Get value for virtual port */ | ||
5267 | VirtualConf(pAC, IoC, Id, pBufPtr); | ||
5268 | } | ||
5269 | else { | ||
5270 | /* Get value for physical port */ | ||
5271 | PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( | ||
5272 | pAC, LogPortIndex); | ||
5273 | |||
5274 | *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus; | ||
5275 | } | ||
5276 | } | ||
5277 | else { /* DualNetMode */ | ||
5278 | |||
5279 | *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus; | ||
5280 | } | ||
5281 | Offset += sizeof(char); | ||
5282 | break; | ||
5283 | |||
5284 | case OID_SKGE_PHY_OPERATION_CAP: | ||
5285 | if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ | ||
5286 | if (LogPortIndex == 0) { | ||
5287 | /* Get value for virtual port */ | ||
5288 | VirtualConf(pAC, IoC, Id, pBufPtr); | ||
5289 | } | ||
5290 | else { | ||
5291 | /* Get value for physical ports */ | ||
5292 | PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( | ||
5293 | pAC, LogPortIndex); | ||
5294 | |||
5295 | *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSCap; | ||
5296 | } | ||
5297 | } | ||
5298 | else { /* DualNetMode */ | ||
5299 | |||
5300 | *pBufPtr = pAC->GIni.GP[NetIndex].PMSCap; | ||
5301 | } | ||
5302 | Offset += sizeof(char); | ||
5303 | break; | ||
5304 | |||
5305 | case OID_SKGE_PHY_OPERATION_MODE: | ||
5306 | if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ | ||
5307 | if (LogPortIndex == 0) { | ||
5308 | /* Get value for virtual port */ | ||
5309 | VirtualConf(pAC, IoC, Id, pBufPtr); | ||
5310 | } | ||
5311 | else { | ||
5312 | /* Get value for physical port */ | ||
5313 | PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( | ||
5314 | pAC, LogPortIndex); | ||
5315 | |||
5316 | *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSMode; | ||
5317 | } | ||
5318 | } | ||
5319 | else { /* DualNetMode */ | ||
5320 | |||
5321 | *pBufPtr = pAC->GIni.GP[NetIndex].PMSMode; | ||
5322 | } | ||
5323 | Offset += sizeof(char); | ||
5324 | break; | ||
5325 | |||
5326 | case OID_SKGE_PHY_OPERATION_STATUS: | ||
5327 | if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ | ||
5328 | if (LogPortIndex == 0) { | ||
5329 | /* Get value for virtual port */ | ||
5330 | VirtualConf(pAC, IoC, Id, pBufPtr); | ||
5331 | } | ||
5332 | else { | ||
5333 | /* Get value for physical port */ | ||
5334 | PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( | ||
5335 | pAC, LogPortIndex); | ||
5336 | |||
5337 | *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSStatus; | ||
5338 | } | ||
5339 | } | ||
5340 | else { | ||
5341 | |||
5342 | *pBufPtr = pAC->GIni.GP[NetIndex].PMSStatus; | ||
5343 | } | ||
5344 | Offset += sizeof(char); | ||
5345 | break; | ||
5346 | |||
5347 | case OID_SKGE_SPEED_CAP: | ||
5348 | if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ | ||
5349 | if (LogPortIndex == 0) { | ||
5350 | /* Get value for virtual port */ | ||
5351 | VirtualConf(pAC, IoC, Id, pBufPtr); | ||
5352 | } | ||
5353 | else { | ||
5354 | /* Get value for physical ports */ | ||
5355 | PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( | ||
5356 | pAC, LogPortIndex); | ||
5357 | |||
5358 | *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedCap; | ||
5359 | } | ||
5360 | } | ||
5361 | else { /* DualNetMode */ | ||
5362 | |||
5363 | *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap; | ||
5364 | } | ||
5365 | Offset += sizeof(char); | ||
5366 | break; | ||
5367 | |||
5368 | case OID_SKGE_SPEED_MODE: | ||
5369 | if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ | ||
5370 | if (LogPortIndex == 0) { | ||
5371 | /* Get value for virtual port */ | ||
5372 | VirtualConf(pAC, IoC, Id, pBufPtr); | ||
5373 | } | ||
5374 | else { | ||
5375 | /* Get value for physical port */ | ||
5376 | PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( | ||
5377 | pAC, LogPortIndex); | ||
5378 | |||
5379 | *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeed; | ||
5380 | } | ||
5381 | } | ||
5382 | else { /* DualNetMode */ | ||
5383 | |||
5384 | *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed; | ||
5385 | } | ||
5386 | Offset += sizeof(char); | ||
5387 | break; | ||
5388 | |||
5389 | case OID_SKGE_SPEED_STATUS: | ||
5390 | if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ | ||
5391 | if (LogPortIndex == 0) { | ||
5392 | /* Get value for virtual port */ | ||
5393 | VirtualConf(pAC, IoC, Id, pBufPtr); | ||
5394 | } | ||
5395 | else { | ||
5396 | /* Get value for physical port */ | ||
5397 | PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( | ||
5398 | pAC, LogPortIndex); | ||
5399 | |||
5400 | *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed; | ||
5401 | } | ||
5402 | } | ||
5403 | else { /* DualNetMode */ | ||
5404 | |||
5405 | *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed; | ||
5406 | } | ||
5407 | Offset += sizeof(char); | ||
5408 | break; | ||
5409 | |||
5410 | case OID_SKGE_MTU: | ||
5411 | Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex); | ||
5412 | SK_PNMI_STORE_U32(pBufPtr, Val32); | ||
5413 | Offset += sizeof(SK_U32); | ||
5414 | break; | ||
5415 | |||
5416 | default: | ||
5417 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, | ||
5418 | ("MacPrivateConf: Unknown OID should be handled before")); | ||
5419 | |||
5420 | pAC->Pnmi.SirqUpdatedFlag --; | ||
5421 | return (SK_PNMI_ERR_GENERAL); | ||
5422 | } | ||
5423 | } | ||
5424 | *pLen = Offset; | ||
5425 | pAC->Pnmi.SirqUpdatedFlag --; | ||
5426 | |||
5427 | return (SK_PNMI_ERR_OK); | ||
5428 | } | ||
5429 | |||
5430 | /* | ||
5431 | * From here SET or PRESET action. Check if the passed | ||
5432 | * buffer length is plausible. | ||
5433 | */ | ||
5434 | switch (Id) { | ||
5435 | |||
5436 | case OID_SKGE_LINK_MODE: | ||
5437 | case OID_SKGE_FLOWCTRL_MODE: | ||
5438 | case OID_SKGE_PHY_OPERATION_MODE: | ||
5439 | case OID_SKGE_SPEED_MODE: | ||
5440 | if (*pLen < Limit - LogPortIndex) { | ||
5441 | |||
5442 | *pLen = Limit - LogPortIndex; | ||
5443 | return (SK_PNMI_ERR_TOO_SHORT); | ||
5444 | } | ||
5445 | if (*pLen != Limit - LogPortIndex) { | ||
5446 | |||
5447 | *pLen = 0; | ||
5448 | return (SK_PNMI_ERR_BAD_VALUE); | ||
5449 | } | ||
5450 | break; | ||
5451 | |||
5452 | case OID_SKGE_MTU: | ||
5453 | if (*pLen < sizeof(SK_U32)) { | ||
5454 | |||
5455 | *pLen = sizeof(SK_U32); | ||
5456 | return (SK_PNMI_ERR_TOO_SHORT); | ||
5457 | } | ||
5458 | if (*pLen != sizeof(SK_U32)) { | ||
5459 | |||
5460 | *pLen = 0; | ||
5461 | return (SK_PNMI_ERR_BAD_VALUE); | ||
5462 | } | ||
5463 | break; | ||
5464 | |||
5465 | default: | ||
5466 | *pLen = 0; | ||
5467 | return (SK_PNMI_ERR_READ_ONLY); | ||
5468 | } | ||
5469 | |||
5470 | /* | ||
5471 | * Perform preset or set | ||
5472 | */ | ||
5473 | Offset = 0; | ||
5474 | for (; LogPortIndex < Limit; LogPortIndex ++) { | ||
5475 | |||
5476 | switch (Id) { | ||
5477 | |||
5478 | case OID_SKGE_LINK_MODE: | ||
5479 | /* Check the value range */ | ||
5480 | Val8 = *(pBuf + Offset); | ||
5481 | if (Val8 == 0) { | ||
5482 | |||
5483 | Offset += sizeof(char); | ||
5484 | break; | ||
5485 | } | ||
5486 | if (Val8 < SK_LMODE_HALF || | ||
5487 | (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) || | ||
5488 | (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) { | ||
5489 | |||
5490 | *pLen = 0; | ||
5491 | return (SK_PNMI_ERR_BAD_VALUE); | ||
5492 | } | ||
5493 | |||
5494 | /* The preset ends here */ | ||
5495 | if (Action == SK_PNMI_PRESET) { | ||
5496 | |||
5497 | return (SK_PNMI_ERR_OK); | ||
5498 | } | ||
5499 | |||
5500 | if (LogPortIndex == 0) { | ||
5501 | |||
5502 | /* | ||
5503 | * The virtual port consists of all currently | ||
5504 | * active ports. Find them and send an event | ||
5505 | * with the new link mode to SIRQ. | ||
5506 | */ | ||
5507 | for (PhysPortIndex = 0; | ||
5508 | PhysPortIndex < PhysPortMax; | ||
5509 | PhysPortIndex ++) { | ||
5510 | |||
5511 | if (!pAC->Pnmi.Port[PhysPortIndex]. | ||
5512 | ActiveFlag) { | ||
5513 | |||
5514 | continue; | ||
5515 | } | ||
5516 | |||
5517 | EventParam.Para32[0] = PhysPortIndex; | ||
5518 | EventParam.Para32[1] = (SK_U32)Val8; | ||
5519 | if (SkGeSirqEvent(pAC, IoC, | ||
5520 | SK_HWEV_SET_LMODE, | ||
5521 | EventParam) > 0) { | ||
5522 | |||
5523 | SK_ERR_LOG(pAC, SK_ERRCL_SW, | ||
5524 | SK_PNMI_ERR043, | ||
5525 | SK_PNMI_ERR043MSG); | ||
5526 | |||
5527 | *pLen = 0; | ||
5528 | return (SK_PNMI_ERR_GENERAL); | ||
5529 | } | ||
5530 | } | ||
5531 | } | ||
5532 | else { | ||
5533 | /* | ||
5534 | * Send an event with the new link mode to | ||
5535 | * the SIRQ module. | ||
5536 | */ | ||
5537 | EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( | ||
5538 | pAC, LogPortIndex); | ||
5539 | EventParam.Para32[1] = (SK_U32)Val8; | ||
5540 | if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE, | ||
5541 | EventParam) > 0) { | ||
5542 | |||
5543 | SK_ERR_LOG(pAC, SK_ERRCL_SW, | ||
5544 | SK_PNMI_ERR043, | ||
5545 | SK_PNMI_ERR043MSG); | ||
5546 | |||
5547 | *pLen = 0; | ||
5548 | return (SK_PNMI_ERR_GENERAL); | ||
5549 | } | ||
5550 | } | ||
5551 | Offset += sizeof(char); | ||
5552 | break; | ||
5553 | |||
5554 | case OID_SKGE_FLOWCTRL_MODE: | ||
5555 | /* Check the value range */ | ||
5556 | Val8 = *(pBuf + Offset); | ||
5557 | if (Val8 == 0) { | ||
5558 | |||
5559 | Offset += sizeof(char); | ||
5560 | break; | ||
5561 | } | ||
5562 | if (Val8 < SK_FLOW_MODE_NONE || | ||
5563 | (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) || | ||
5564 | (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) { | ||
5565 | |||
5566 | *pLen = 0; | ||
5567 | return (SK_PNMI_ERR_BAD_VALUE); | ||
5568 | } | ||
5569 | |||
5570 | /* The preset ends here */ | ||
5571 | if (Action == SK_PNMI_PRESET) { | ||
5572 | |||
5573 | return (SK_PNMI_ERR_OK); | ||
5574 | } | ||
5575 | |||
5576 | if (LogPortIndex == 0) { | ||
5577 | |||
5578 | /* | ||
5579 | * The virtual port consists of all currently | ||
5580 | * active ports. Find them and send an event | ||
5581 | * with the new flow control mode to SIRQ. | ||
5582 | */ | ||
5583 | for (PhysPortIndex = 0; | ||
5584 | PhysPortIndex < PhysPortMax; | ||
5585 | PhysPortIndex ++) { | ||
5586 | |||
5587 | if (!pAC->Pnmi.Port[PhysPortIndex]. | ||
5588 | ActiveFlag) { | ||
5589 | |||
5590 | continue; | ||
5591 | } | ||
5592 | |||
5593 | EventParam.Para32[0] = PhysPortIndex; | ||
5594 | EventParam.Para32[1] = (SK_U32)Val8; | ||
5595 | if (SkGeSirqEvent(pAC, IoC, | ||
5596 | SK_HWEV_SET_FLOWMODE, | ||
5597 | EventParam) > 0) { | ||
5598 | |||
5599 | SK_ERR_LOG(pAC, SK_ERRCL_SW, | ||
5600 | SK_PNMI_ERR044, | ||
5601 | SK_PNMI_ERR044MSG); | ||
5602 | |||
5603 | *pLen = 0; | ||
5604 | return (SK_PNMI_ERR_GENERAL); | ||
5605 | } | ||
5606 | } | ||
5607 | } | ||
5608 | else { | ||
5609 | /* | ||
5610 | * Send an event with the new flow control | ||
5611 | * mode to the SIRQ module. | ||
5612 | */ | ||
5613 | EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( | ||
5614 | pAC, LogPortIndex); | ||
5615 | EventParam.Para32[1] = (SK_U32)Val8; | ||
5616 | if (SkGeSirqEvent(pAC, IoC, | ||
5617 | SK_HWEV_SET_FLOWMODE, EventParam) | ||
5618 | > 0) { | ||
5619 | |||
5620 | SK_ERR_LOG(pAC, SK_ERRCL_SW, | ||
5621 | SK_PNMI_ERR044, | ||
5622 | SK_PNMI_ERR044MSG); | ||
5623 | |||
5624 | *pLen = 0; | ||
5625 | return (SK_PNMI_ERR_GENERAL); | ||
5626 | } | ||
5627 | } | ||
5628 | Offset += sizeof(char); | ||
5629 | break; | ||
5630 | |||
5631 | case OID_SKGE_PHY_OPERATION_MODE : | ||
5632 | /* Check the value range */ | ||
5633 | Val8 = *(pBuf + Offset); | ||
5634 | if (Val8 == 0) { | ||
5635 | /* mode of this port remains unchanged */ | ||
5636 | Offset += sizeof(char); | ||
5637 | break; | ||
5638 | } | ||
5639 | if (Val8 < SK_MS_MODE_AUTO || | ||
5640 | (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) || | ||
5641 | (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) { | ||
5642 | |||
5643 | *pLen = 0; | ||
5644 | return (SK_PNMI_ERR_BAD_VALUE); | ||
5645 | } | ||
5646 | |||
5647 | /* The preset ends here */ | ||
5648 | if (Action == SK_PNMI_PRESET) { | ||
5649 | |||
5650 | return (SK_PNMI_ERR_OK); | ||
5651 | } | ||
5652 | |||
5653 | if (LogPortIndex == 0) { | ||
5654 | |||
5655 | /* | ||
5656 | * The virtual port consists of all currently | ||
5657 | * active ports. Find them and send an event | ||
5658 | * with new master/slave (role) mode to SIRQ. | ||
5659 | */ | ||
5660 | for (PhysPortIndex = 0; | ||
5661 | PhysPortIndex < PhysPortMax; | ||
5662 | PhysPortIndex ++) { | ||
5663 | |||
5664 | if (!pAC->Pnmi.Port[PhysPortIndex]. | ||
5665 | ActiveFlag) { | ||
5666 | |||
5667 | continue; | ||
5668 | } | ||
5669 | |||
5670 | EventParam.Para32[0] = PhysPortIndex; | ||
5671 | EventParam.Para32[1] = (SK_U32)Val8; | ||
5672 | if (SkGeSirqEvent(pAC, IoC, | ||
5673 | SK_HWEV_SET_ROLE, | ||
5674 | EventParam) > 0) { | ||
5675 | |||
5676 | SK_ERR_LOG(pAC, SK_ERRCL_SW, | ||
5677 | SK_PNMI_ERR042, | ||
5678 | SK_PNMI_ERR042MSG); | ||
5679 | |||
5680 | *pLen = 0; | ||
5681 | return (SK_PNMI_ERR_GENERAL); | ||
5682 | } | ||
5683 | } | ||
5684 | } | ||
5685 | else { | ||
5686 | /* | ||
5687 | * Send an event with the new master/slave | ||
5688 | * (role) mode to the SIRQ module. | ||
5689 | */ | ||
5690 | EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( | ||
5691 | pAC, LogPortIndex); | ||
5692 | EventParam.Para32[1] = (SK_U32)Val8; | ||
5693 | if (SkGeSirqEvent(pAC, IoC, | ||
5694 | SK_HWEV_SET_ROLE, EventParam) > 0) { | ||
5695 | |||
5696 | SK_ERR_LOG(pAC, SK_ERRCL_SW, | ||
5697 | SK_PNMI_ERR042, | ||
5698 | SK_PNMI_ERR042MSG); | ||
5699 | |||
5700 | *pLen = 0; | ||
5701 | return (SK_PNMI_ERR_GENERAL); | ||
5702 | } | ||
5703 | } | ||
5704 | |||
5705 | Offset += sizeof(char); | ||
5706 | break; | ||
5707 | |||
5708 | case OID_SKGE_SPEED_MODE: | ||
5709 | /* Check the value range */ | ||
5710 | Val8 = *(pBuf + Offset); | ||
5711 | if (Val8 == 0) { | ||
5712 | |||
5713 | Offset += sizeof(char); | ||
5714 | break; | ||
5715 | } | ||
5716 | if (Val8 < (SK_LSPEED_AUTO) || | ||
5717 | (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) || | ||
5718 | (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) { | ||
5719 | |||
5720 | *pLen = 0; | ||
5721 | return (SK_PNMI_ERR_BAD_VALUE); | ||
5722 | } | ||
5723 | |||
5724 | /* The preset ends here */ | ||
5725 | if (Action == SK_PNMI_PRESET) { | ||
5726 | |||
5727 | return (SK_PNMI_ERR_OK); | ||
5728 | } | ||
5729 | |||
5730 | if (LogPortIndex == 0) { | ||
5731 | |||
5732 | /* | ||
5733 | * The virtual port consists of all currently | ||
5734 | * active ports. Find them and send an event | ||
5735 | * with the new flow control mode to SIRQ. | ||
5736 | */ | ||
5737 | for (PhysPortIndex = 0; | ||
5738 | PhysPortIndex < PhysPortMax; | ||
5739 | PhysPortIndex ++) { | ||
5740 | |||
5741 | if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { | ||
5742 | |||
5743 | continue; | ||
5744 | } | ||
5745 | |||
5746 | EventParam.Para32[0] = PhysPortIndex; | ||
5747 | EventParam.Para32[1] = (SK_U32)Val8; | ||
5748 | if (SkGeSirqEvent(pAC, IoC, | ||
5749 | SK_HWEV_SET_SPEED, | ||
5750 | EventParam) > 0) { | ||
5751 | |||
5752 | SK_ERR_LOG(pAC, SK_ERRCL_SW, | ||
5753 | SK_PNMI_ERR045, | ||
5754 | SK_PNMI_ERR045MSG); | ||
5755 | |||
5756 | *pLen = 0; | ||
5757 | return (SK_PNMI_ERR_GENERAL); | ||
5758 | } | ||
5759 | } | ||
5760 | } | ||
5761 | else { | ||
5762 | /* | ||
5763 | * Send an event with the new flow control | ||
5764 | * mode to the SIRQ module. | ||
5765 | */ | ||
5766 | EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( | ||
5767 | pAC, LogPortIndex); | ||
5768 | EventParam.Para32[1] = (SK_U32)Val8; | ||
5769 | if (SkGeSirqEvent(pAC, IoC, | ||
5770 | SK_HWEV_SET_SPEED, | ||
5771 | EventParam) > 0) { | ||
5772 | |||
5773 | SK_ERR_LOG(pAC, SK_ERRCL_SW, | ||
5774 | SK_PNMI_ERR045, | ||
5775 | SK_PNMI_ERR045MSG); | ||
5776 | |||
5777 | *pLen = 0; | ||
5778 | return (SK_PNMI_ERR_GENERAL); | ||
5779 | } | ||
5780 | } | ||
5781 | Offset += sizeof(char); | ||
5782 | break; | ||
5783 | |||
5784 | case OID_SKGE_MTU : | ||
5785 | /* Check the value range */ | ||
5786 | Val32 = *(SK_U32*)(pBuf + Offset); | ||
5787 | if (Val32 == 0) { | ||
5788 | /* mtu of this port remains unchanged */ | ||
5789 | Offset += sizeof(SK_U32); | ||
5790 | break; | ||
5791 | } | ||
5792 | if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) { | ||
5793 | *pLen = 0; | ||
5794 | return (SK_PNMI_ERR_BAD_VALUE); | ||
5795 | } | ||
5796 | |||
5797 | /* The preset ends here */ | ||
5798 | if (Action == SK_PNMI_PRESET) { | ||
5799 | return (SK_PNMI_ERR_OK); | ||
5800 | } | ||
5801 | |||
5802 | if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) { | ||
5803 | return (SK_PNMI_ERR_GENERAL); | ||
5804 | } | ||
5805 | |||
5806 | Offset += sizeof(SK_U32); | ||
5807 | break; | ||
5808 | |||
5809 | default: | ||
5810 | SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, | ||
5811 | ("MacPrivateConf: Unknown OID should be handled before set")); | ||
5812 | |||
5813 | *pLen = 0; | ||
5814 | return (SK_PNMI_ERR_GENERAL); | ||
5815 | } | ||
5816 | } | ||
5817 | |||
5818 | return (SK_PNMI_ERR_OK); | ||
5819 | } | ||
5820 | |||
5821 | /***************************************************************************** | ||
5822 | * | ||
5823 | * Monitor - OID handler function for RLMT_MONITOR_XXX | ||
5824 | * | ||
5825 | * Description: | ||
5826 | * Because RLMT currently does not support the monitoring of | ||
5827 | * remote adapter cards, we return always an empty table. | ||
5828 | * | ||
5829 | * Returns: | ||
5830 | * SK_PNMI_ERR_OK The request was successfully performed. | ||
5831 | * SK_PNMI_ERR_GENERAL A general severe internal error occured. | ||
5832 | * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain | ||
5833 | * the correct data (e.g. a 32bit value is | ||
5834 | * needed, but a 16 bit value was passed). | ||
5835 | * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid | ||
5836 | * value range. | ||
5837 | * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. | ||
5838 | * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't | ||
5839 | * exist (e.g. port instance 3 on a two port | ||
5840 | * adapter. | ||
5841 | */ | ||
5842 | PNMI_STATIC int Monitor( | ||
5843 | SK_AC *pAC, /* Pointer to adapter context */ | ||
5844 | SK_IOC IoC, /* IO context handle */ | ||
5845 | int Action, /* GET/PRESET/SET action */ | ||
5846 | SK_U32 Id, /* Object ID that is to be processed */ | ||
5847 | char *pBuf, /* Buffer used for the management data transfer */ | ||
5848 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
5849 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
5850 | unsigned int TableIndex, /* Index to the Id table */ | ||
5851 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
5852 | { | ||
5853 | unsigned int Index; | ||
5854 | unsigned int Limit; | ||
5855 | unsigned int Offset; | ||
5856 | unsigned int Entries; | ||
5857 | |||
5858 | |||
5859 | /* | ||
5860 | * Calculate instance if wished. | ||
5861 | */ | ||
5862 | /* XXX Not yet implemented. Return always an empty table. */ | ||
5863 | Entries = 0; | ||
5864 | |||
5865 | if ((Instance != (SK_U32)(-1))) { | ||
5866 | |||
5867 | if ((Instance < 1) || (Instance > Entries)) { | ||
5868 | |||
5869 | *pLen = 0; | ||
5870 | return (SK_PNMI_ERR_UNKNOWN_INST); | ||
5871 | } | ||
5872 | |||
5873 | Index = (unsigned int)Instance - 1; | ||
5874 | Limit = (unsigned int)Instance; | ||
5875 | } | ||
5876 | else { | ||
5877 | Index = 0; | ||
5878 | Limit = Entries; | ||
5879 | } | ||
5880 | |||
5881 | /* | ||
5882 | * Get/Set value | ||
5883 | */ | ||
5884 | if (Action == SK_PNMI_GET) { | ||
5885 | |||
5886 | for (Offset=0; Index < Limit; Index ++) { | ||
5887 | |||
5888 | switch (Id) { | ||
5889 | |||
5890 | case OID_SKGE_RLMT_MONITOR_INDEX: | ||
5891 | case OID_SKGE_RLMT_MONITOR_ADDR: | ||
5892 | case OID_SKGE_RLMT_MONITOR_ERRS: | ||
5893 | case OID_SKGE_RLMT_MONITOR_TIMESTAMP: | ||
5894 | case OID_SKGE_RLMT_MONITOR_ADMIN: | ||
5895 | break; | ||
5896 | |||
5897 | default: | ||
5898 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046, | ||
5899 | SK_PNMI_ERR046MSG); | ||
5900 | |||
5901 | *pLen = 0; | ||
5902 | return (SK_PNMI_ERR_GENERAL); | ||
5903 | } | ||
5904 | } | ||
5905 | *pLen = Offset; | ||
5906 | } | ||
5907 | else { | ||
5908 | /* Only MONITOR_ADMIN can be set */ | ||
5909 | if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) { | ||
5910 | |||
5911 | *pLen = 0; | ||
5912 | return (SK_PNMI_ERR_READ_ONLY); | ||
5913 | } | ||
5914 | |||
5915 | /* Check if the length is plausible */ | ||
5916 | if (*pLen < (Limit - Index)) { | ||
5917 | |||
5918 | return (SK_PNMI_ERR_TOO_SHORT); | ||
5919 | } | ||
5920 | /* Okay, we have a wide value range */ | ||
5921 | if (*pLen != (Limit - Index)) { | ||
5922 | |||
5923 | *pLen = 0; | ||
5924 | return (SK_PNMI_ERR_BAD_VALUE); | ||
5925 | } | ||
5926 | /* | ||
5927 | for (Offset=0; Index < Limit; Index ++) { | ||
5928 | } | ||
5929 | */ | ||
5930 | /* | ||
5931 | * XXX Not yet implemented. Return always BAD_VALUE, because the table | ||
5932 | * is empty. | ||
5933 | */ | ||
5934 | *pLen = 0; | ||
5935 | return (SK_PNMI_ERR_BAD_VALUE); | ||
5936 | } | ||
5937 | |||
5938 | return (SK_PNMI_ERR_OK); | ||
5939 | } | ||
5940 | |||
5941 | /***************************************************************************** | ||
5942 | * | ||
5943 | * VirtualConf - Calculates the values of configuration OIDs for virtual port | ||
5944 | * | ||
5945 | * Description: | ||
5946 | * We handle here the get of the configuration group OIDs, which are | ||
5947 | * a little bit complicated. The virtual port consists of all currently | ||
5948 | * active physical ports. If multiple ports are active and configured | ||
5949 | * differently we get in some trouble to return a single value. So we | ||
5950 | * get the value of the first active port and compare it with that of | ||
5951 | * the other active ports. If they are not the same, we return a value | ||
5952 | * that indicates that the state is indeterminated. | ||
5953 | * | ||
5954 | * Returns: | ||
5955 | * Nothing | ||
5956 | */ | ||
5957 | PNMI_STATIC void VirtualConf( | ||
5958 | SK_AC *pAC, /* Pointer to adapter context */ | ||
5959 | SK_IOC IoC, /* IO context handle */ | ||
5960 | SK_U32 Id, /* Object ID that is to be processed */ | ||
5961 | char *pBuf) /* Buffer used for the management data transfer */ | ||
5962 | { | ||
5963 | unsigned int PhysPortMax; | ||
5964 | unsigned int PhysPortIndex; | ||
5965 | SK_U8 Val8; | ||
5966 | SK_U32 Val32; | ||
5967 | SK_BOOL PortActiveFlag; | ||
5968 | SK_GEPORT *pPrt; | ||
5969 | |||
5970 | *pBuf = 0; | ||
5971 | PortActiveFlag = SK_FALSE; | ||
5972 | PhysPortMax = pAC->GIni.GIMacsFound; | ||
5973 | |||
5974 | for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; | ||
5975 | PhysPortIndex ++) { | ||
5976 | |||
5977 | pPrt = &pAC->GIni.GP[PhysPortIndex]; | ||
5978 | |||
5979 | /* Check if the physical port is active */ | ||
5980 | if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { | ||
5981 | |||
5982 | continue; | ||
5983 | } | ||
5984 | |||
5985 | PortActiveFlag = SK_TRUE; | ||
5986 | |||
5987 | switch (Id) { | ||
5988 | |||
5989 | case OID_SKGE_PHY_TYPE: | ||
5990 | /* Check if it is the first active port */ | ||
5991 | if (*pBuf == 0) { | ||
5992 | Val32 = pPrt->PhyType; | ||
5993 | SK_PNMI_STORE_U32(pBuf, Val32); | ||
5994 | continue; | ||
5995 | } | ||
5996 | |||
5997 | case OID_SKGE_LINK_CAP: | ||
5998 | |||
5999 | /* | ||
6000 | * Different capabilities should not happen, but | ||
6001 | * in the case of the cases OR them all together. | ||
6002 | * From a curious point of view the virtual port | ||
6003 | * is capable of all found capabilities. | ||
6004 | */ | ||
6005 | *pBuf |= pPrt->PLinkCap; | ||
6006 | break; | ||
6007 | |||
6008 | case OID_SKGE_LINK_MODE: | ||
6009 | /* Check if it is the first active port */ | ||
6010 | if (*pBuf == 0) { | ||
6011 | |||
6012 | *pBuf = pPrt->PLinkModeConf; | ||
6013 | continue; | ||
6014 | } | ||
6015 | |||
6016 | /* | ||
6017 | * If we find an active port with a different link | ||
6018 | * mode than the first one we return a value that | ||
6019 | * indicates that the link mode is indeterminated. | ||
6020 | */ | ||
6021 | if (*pBuf != pPrt->PLinkModeConf) { | ||
6022 | |||
6023 | *pBuf = SK_LMODE_INDETERMINATED; | ||
6024 | } | ||
6025 | break; | ||
6026 | |||
6027 | case OID_SKGE_LINK_MODE_STATUS: | ||
6028 | /* Get the link mode of the physical port */ | ||
6029 | Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex); | ||
6030 | |||
6031 | /* Check if it is the first active port */ | ||
6032 | if (*pBuf == 0) { | ||
6033 | |||
6034 | *pBuf = Val8; | ||
6035 | continue; | ||
6036 | } | ||
6037 | |||
6038 | /* | ||
6039 | * If we find an active port with a different link | ||
6040 | * mode status than the first one we return a value | ||
6041 | * that indicates that the link mode status is | ||
6042 | * indeterminated. | ||
6043 | */ | ||
6044 | if (*pBuf != Val8) { | ||
6045 | |||
6046 | *pBuf = SK_LMODE_STAT_INDETERMINATED; | ||
6047 | } | ||
6048 | break; | ||
6049 | |||
6050 | case OID_SKGE_LINK_STATUS: | ||
6051 | /* Get the link status of the physical port */ | ||
6052 | Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex); | ||
6053 | |||
6054 | /* Check if it is the first active port */ | ||
6055 | if (*pBuf == 0) { | ||
6056 | |||
6057 | *pBuf = Val8; | ||
6058 | continue; | ||
6059 | } | ||
6060 | |||
6061 | /* | ||
6062 | * If we find an active port with a different link | ||
6063 | * status than the first one, we return a value | ||
6064 | * that indicates that the link status is | ||
6065 | * indeterminated. | ||
6066 | */ | ||
6067 | if (*pBuf != Val8) { | ||
6068 | |||
6069 | *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED; | ||
6070 | } | ||
6071 | break; | ||
6072 | |||
6073 | case OID_SKGE_FLOWCTRL_CAP: | ||
6074 | /* Check if it is the first active port */ | ||
6075 | if (*pBuf == 0) { | ||
6076 | |||
6077 | *pBuf = pPrt->PFlowCtrlCap; | ||
6078 | continue; | ||
6079 | } | ||
6080 | |||
6081 | /* | ||
6082 | * From a curious point of view the virtual port | ||
6083 | * is capable of all found capabilities. | ||
6084 | */ | ||
6085 | *pBuf |= pPrt->PFlowCtrlCap; | ||
6086 | break; | ||
6087 | |||
6088 | case OID_SKGE_FLOWCTRL_MODE: | ||
6089 | /* Check if it is the first active port */ | ||
6090 | if (*pBuf == 0) { | ||
6091 | |||
6092 | *pBuf = pPrt->PFlowCtrlMode; | ||
6093 | continue; | ||
6094 | } | ||
6095 | |||
6096 | /* | ||
6097 | * If we find an active port with a different flow | ||
6098 | * control mode than the first one, we return a value | ||
6099 | * that indicates that the mode is indeterminated. | ||
6100 | */ | ||
6101 | if (*pBuf != pPrt->PFlowCtrlMode) { | ||
6102 | |||
6103 | *pBuf = SK_FLOW_MODE_INDETERMINATED; | ||
6104 | } | ||
6105 | break; | ||
6106 | |||
6107 | case OID_SKGE_FLOWCTRL_STATUS: | ||
6108 | /* Check if it is the first active port */ | ||
6109 | if (*pBuf == 0) { | ||
6110 | |||
6111 | *pBuf = pPrt->PFlowCtrlStatus; | ||
6112 | continue; | ||
6113 | } | ||
6114 | |||
6115 | /* | ||
6116 | * If we find an active port with a different flow | ||
6117 | * control status than the first one, we return a | ||
6118 | * value that indicates that the status is | ||
6119 | * indeterminated. | ||
6120 | */ | ||
6121 | if (*pBuf != pPrt->PFlowCtrlStatus) { | ||
6122 | |||
6123 | *pBuf = SK_FLOW_STAT_INDETERMINATED; | ||
6124 | } | ||
6125 | break; | ||
6126 | |||
6127 | case OID_SKGE_PHY_OPERATION_CAP: | ||
6128 | /* Check if it is the first active port */ | ||
6129 | if (*pBuf == 0) { | ||
6130 | |||
6131 | *pBuf = pPrt->PMSCap; | ||
6132 | continue; | ||
6133 | } | ||
6134 | |||
6135 | /* | ||
6136 | * From a curious point of view the virtual port | ||
6137 | * is capable of all found capabilities. | ||
6138 | */ | ||
6139 | *pBuf |= pPrt->PMSCap; | ||
6140 | break; | ||
6141 | |||
6142 | case OID_SKGE_PHY_OPERATION_MODE: | ||
6143 | /* Check if it is the first active port */ | ||
6144 | if (*pBuf == 0) { | ||
6145 | |||
6146 | *pBuf = pPrt->PMSMode; | ||
6147 | continue; | ||
6148 | } | ||
6149 | |||
6150 | /* | ||
6151 | * If we find an active port with a different master/ | ||
6152 | * slave mode than the first one, we return a value | ||
6153 | * that indicates that the mode is indeterminated. | ||
6154 | */ | ||
6155 | if (*pBuf != pPrt->PMSMode) { | ||
6156 | |||
6157 | *pBuf = SK_MS_MODE_INDETERMINATED; | ||
6158 | } | ||
6159 | break; | ||
6160 | |||
6161 | case OID_SKGE_PHY_OPERATION_STATUS: | ||
6162 | /* Check if it is the first active port */ | ||
6163 | if (*pBuf == 0) { | ||
6164 | |||
6165 | *pBuf = pPrt->PMSStatus; | ||
6166 | continue; | ||
6167 | } | ||
6168 | |||
6169 | /* | ||
6170 | * If we find an active port with a different master/ | ||
6171 | * slave status than the first one, we return a | ||
6172 | * value that indicates that the status is | ||
6173 | * indeterminated. | ||
6174 | */ | ||
6175 | if (*pBuf != pPrt->PMSStatus) { | ||
6176 | |||
6177 | *pBuf = SK_MS_STAT_INDETERMINATED; | ||
6178 | } | ||
6179 | break; | ||
6180 | |||
6181 | case OID_SKGE_SPEED_MODE: | ||
6182 | /* Check if it is the first active port */ | ||
6183 | if (*pBuf == 0) { | ||
6184 | |||
6185 | *pBuf = pPrt->PLinkSpeed; | ||
6186 | continue; | ||
6187 | } | ||
6188 | |||
6189 | /* | ||
6190 | * If we find an active port with a different flow | ||
6191 | * control mode than the first one, we return a value | ||
6192 | * that indicates that the mode is indeterminated. | ||
6193 | */ | ||
6194 | if (*pBuf != pPrt->PLinkSpeed) { | ||
6195 | |||
6196 | *pBuf = SK_LSPEED_INDETERMINATED; | ||
6197 | } | ||
6198 | break; | ||
6199 | |||
6200 | case OID_SKGE_SPEED_STATUS: | ||
6201 | /* Check if it is the first active port */ | ||
6202 | if (*pBuf == 0) { | ||
6203 | |||
6204 | *pBuf = pPrt->PLinkSpeedUsed; | ||
6205 | continue; | ||
6206 | } | ||
6207 | |||
6208 | /* | ||
6209 | * If we find an active port with a different flow | ||
6210 | * control status than the first one, we return a | ||
6211 | * value that indicates that the status is | ||
6212 | * indeterminated. | ||
6213 | */ | ||
6214 | if (*pBuf != pPrt->PLinkSpeedUsed) { | ||
6215 | |||
6216 | *pBuf = SK_LSPEED_STAT_INDETERMINATED; | ||
6217 | } | ||
6218 | break; | ||
6219 | } | ||
6220 | } | ||
6221 | |||
6222 | /* | ||
6223 | * If no port is active return an indeterminated answer | ||
6224 | */ | ||
6225 | if (!PortActiveFlag) { | ||
6226 | |||
6227 | switch (Id) { | ||
6228 | |||
6229 | case OID_SKGE_LINK_CAP: | ||
6230 | *pBuf = SK_LMODE_CAP_INDETERMINATED; | ||
6231 | break; | ||
6232 | |||
6233 | case OID_SKGE_LINK_MODE: | ||
6234 | *pBuf = SK_LMODE_INDETERMINATED; | ||
6235 | break; | ||
6236 | |||
6237 | case OID_SKGE_LINK_MODE_STATUS: | ||
6238 | *pBuf = SK_LMODE_STAT_INDETERMINATED; | ||
6239 | break; | ||
6240 | |||
6241 | case OID_SKGE_LINK_STATUS: | ||
6242 | *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED; | ||
6243 | break; | ||
6244 | |||
6245 | case OID_SKGE_FLOWCTRL_CAP: | ||
6246 | case OID_SKGE_FLOWCTRL_MODE: | ||
6247 | *pBuf = SK_FLOW_MODE_INDETERMINATED; | ||
6248 | break; | ||
6249 | |||
6250 | case OID_SKGE_FLOWCTRL_STATUS: | ||
6251 | *pBuf = SK_FLOW_STAT_INDETERMINATED; | ||
6252 | break; | ||
6253 | |||
6254 | case OID_SKGE_PHY_OPERATION_CAP: | ||
6255 | *pBuf = SK_MS_CAP_INDETERMINATED; | ||
6256 | break; | ||
6257 | |||
6258 | case OID_SKGE_PHY_OPERATION_MODE: | ||
6259 | *pBuf = SK_MS_MODE_INDETERMINATED; | ||
6260 | break; | ||
6261 | |||
6262 | case OID_SKGE_PHY_OPERATION_STATUS: | ||
6263 | *pBuf = SK_MS_STAT_INDETERMINATED; | ||
6264 | break; | ||
6265 | case OID_SKGE_SPEED_CAP: | ||
6266 | *pBuf = SK_LSPEED_CAP_INDETERMINATED; | ||
6267 | break; | ||
6268 | |||
6269 | case OID_SKGE_SPEED_MODE: | ||
6270 | *pBuf = SK_LSPEED_INDETERMINATED; | ||
6271 | break; | ||
6272 | |||
6273 | case OID_SKGE_SPEED_STATUS: | ||
6274 | *pBuf = SK_LSPEED_STAT_INDETERMINATED; | ||
6275 | break; | ||
6276 | } | ||
6277 | } | ||
6278 | } | ||
6279 | |||
6280 | /***************************************************************************** | ||
6281 | * | ||
6282 | * CalculateLinkStatus - Determins the link status of a physical port | ||
6283 | * | ||
6284 | * Description: | ||
6285 | * Determins the link status the following way: | ||
6286 | * LSTAT_PHY_DOWN: Link is down | ||
6287 | * LSTAT_AUTONEG: Auto-negotiation failed | ||
6288 | * LSTAT_LOG_DOWN: Link is up but RLMT did not yet put the port | ||
6289 | * logically up. | ||
6290 | * LSTAT_LOG_UP: RLMT marked the port as up | ||
6291 | * | ||
6292 | * Returns: | ||
6293 | * Link status of physical port | ||
6294 | */ | ||
6295 | PNMI_STATIC SK_U8 CalculateLinkStatus( | ||
6296 | SK_AC *pAC, /* Pointer to adapter context */ | ||
6297 | SK_IOC IoC, /* IO context handle */ | ||
6298 | unsigned int PhysPortIndex) /* Physical port index */ | ||
6299 | { | ||
6300 | SK_U8 Result; | ||
6301 | |||
6302 | if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) { | ||
6303 | |||
6304 | Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN; | ||
6305 | } | ||
6306 | else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) { | ||
6307 | |||
6308 | Result = SK_PNMI_RLMT_LSTAT_AUTONEG; | ||
6309 | } | ||
6310 | else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) { | ||
6311 | |||
6312 | Result = SK_PNMI_RLMT_LSTAT_LOG_UP; | ||
6313 | } | ||
6314 | else { | ||
6315 | Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN; | ||
6316 | } | ||
6317 | |||
6318 | return (Result); | ||
6319 | } | ||
6320 | |||
6321 | /***************************************************************************** | ||
6322 | * | ||
6323 | * CalculateLinkModeStatus - Determins the link mode status of a phys. port | ||
6324 | * | ||
6325 | * Description: | ||
6326 | * The COMMON module only tells us if the mode is half or full duplex. | ||
6327 | * But in the decade of auto sensing it is useful for the user to | ||
6328 | * know if the mode was negotiated or forced. Therefore we have a | ||
6329 | * look to the mode, which was last used by the negotiation process. | ||
6330 | * | ||
6331 | * Returns: | ||
6332 | * The link mode status | ||
6333 | */ | ||
6334 | PNMI_STATIC SK_U8 CalculateLinkModeStatus( | ||
6335 | SK_AC *pAC, /* Pointer to adapter context */ | ||
6336 | SK_IOC IoC, /* IO context handle */ | ||
6337 | unsigned int PhysPortIndex) /* Physical port index */ | ||
6338 | { | ||
6339 | SK_U8 Result; | ||
6340 | |||
6341 | /* Get the current mode, which can be full or half duplex */ | ||
6342 | Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus; | ||
6343 | |||
6344 | /* Check if no valid mode could be found (link is down) */ | ||
6345 | if (Result < SK_LMODE_STAT_HALF) { | ||
6346 | |||
6347 | Result = SK_LMODE_STAT_UNKNOWN; | ||
6348 | } | ||
6349 | else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) { | ||
6350 | |||
6351 | /* | ||
6352 | * Auto-negotiation was used to bring up the link. Change | ||
6353 | * the already found duplex status that it indicates | ||
6354 | * auto-negotiation was involved. | ||
6355 | */ | ||
6356 | if (Result == SK_LMODE_STAT_HALF) { | ||
6357 | |||
6358 | Result = SK_LMODE_STAT_AUTOHALF; | ||
6359 | } | ||
6360 | else if (Result == SK_LMODE_STAT_FULL) { | ||
6361 | |||
6362 | Result = SK_LMODE_STAT_AUTOFULL; | ||
6363 | } | ||
6364 | } | ||
6365 | |||
6366 | return (Result); | ||
6367 | } | ||
6368 | |||
6369 | /***************************************************************************** | ||
6370 | * | ||
6371 | * GetVpdKeyArr - Obtain an array of VPD keys | ||
6372 | * | ||
6373 | * Description: | ||
6374 | * Read the VPD keys and build an array of VPD keys, which are | ||
6375 | * easy to access. | ||
6376 | * | ||
6377 | * Returns: | ||
6378 | * SK_PNMI_ERR_OK Task successfully performed. | ||
6379 | * SK_PNMI_ERR_GENERAL Something went wrong. | ||
6380 | */ | ||
6381 | PNMI_STATIC int GetVpdKeyArr( | ||
6382 | SK_AC *pAC, /* Pointer to adapter context */ | ||
6383 | SK_IOC IoC, /* IO context handle */ | ||
6384 | char *pKeyArr, /* Ptr KeyArray */ | ||
6385 | unsigned int KeyArrLen, /* Length of array in bytes */ | ||
6386 | unsigned int *pKeyNo) /* Number of keys */ | ||
6387 | { | ||
6388 | unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE; | ||
6389 | char BufKeys[SK_PNMI_VPD_BUFSIZE]; | ||
6390 | unsigned int StartOffset; | ||
6391 | unsigned int Offset; | ||
6392 | int Index; | ||
6393 | int Ret; | ||
6394 | |||
6395 | |||
6396 | SK_MEMSET(pKeyArr, 0, KeyArrLen); | ||
6397 | |||
6398 | /* | ||
6399 | * Get VPD key list | ||
6400 | */ | ||
6401 | Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen, | ||
6402 | (int *)pKeyNo); | ||
6403 | if (Ret > 0) { | ||
6404 | |||
6405 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014, | ||
6406 | SK_PNMI_ERR014MSG); | ||
6407 | |||
6408 | return (SK_PNMI_ERR_GENERAL); | ||
6409 | } | ||
6410 | /* If no keys are available return now */ | ||
6411 | if (*pKeyNo == 0 || BufKeysLen == 0) { | ||
6412 | |||
6413 | return (SK_PNMI_ERR_OK); | ||
6414 | } | ||
6415 | /* | ||
6416 | * If the key list is too long for us trunc it and give a | ||
6417 | * errorlog notification. This case should not happen because | ||
6418 | * the maximum number of keys is limited due to RAM limitations | ||
6419 | */ | ||
6420 | if (*pKeyNo > SK_PNMI_VPD_ENTRIES) { | ||
6421 | |||
6422 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015, | ||
6423 | SK_PNMI_ERR015MSG); | ||
6424 | |||
6425 | *pKeyNo = SK_PNMI_VPD_ENTRIES; | ||
6426 | } | ||
6427 | |||
6428 | /* | ||
6429 | * Now build an array of fixed string length size and copy | ||
6430 | * the keys together. | ||
6431 | */ | ||
6432 | for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen; | ||
6433 | Offset ++) { | ||
6434 | |||
6435 | if (BufKeys[Offset] != 0) { | ||
6436 | |||
6437 | continue; | ||
6438 | } | ||
6439 | |||
6440 | if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) { | ||
6441 | |||
6442 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016, | ||
6443 | SK_PNMI_ERR016MSG); | ||
6444 | return (SK_PNMI_ERR_GENERAL); | ||
6445 | } | ||
6446 | |||
6447 | SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE, | ||
6448 | &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE); | ||
6449 | |||
6450 | Index ++; | ||
6451 | StartOffset = Offset + 1; | ||
6452 | } | ||
6453 | |||
6454 | /* Last key not zero terminated? Get it anyway */ | ||
6455 | if (StartOffset < Offset) { | ||
6456 | |||
6457 | SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE, | ||
6458 | &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE); | ||
6459 | } | ||
6460 | |||
6461 | return (SK_PNMI_ERR_OK); | ||
6462 | } | ||
6463 | |||
6464 | /***************************************************************************** | ||
6465 | * | ||
6466 | * SirqUpdate - Let the SIRQ update its internal values | ||
6467 | * | ||
6468 | * Description: | ||
6469 | * Just to be sure that the SIRQ module holds its internal data | ||
6470 | * structures up to date, we send an update event before we make | ||
6471 | * any access. | ||
6472 | * | ||
6473 | * Returns: | ||
6474 | * SK_PNMI_ERR_OK Task successfully performed. | ||
6475 | * SK_PNMI_ERR_GENERAL Something went wrong. | ||
6476 | */ | ||
6477 | PNMI_STATIC int SirqUpdate( | ||
6478 | SK_AC *pAC, /* Pointer to adapter context */ | ||
6479 | SK_IOC IoC) /* IO context handle */ | ||
6480 | { | ||
6481 | SK_EVPARA EventParam; | ||
6482 | |||
6483 | |||
6484 | /* Was the module already updated during the current PNMI call? */ | ||
6485 | if (pAC->Pnmi.SirqUpdatedFlag > 0) { | ||
6486 | |||
6487 | return (SK_PNMI_ERR_OK); | ||
6488 | } | ||
6489 | |||
6490 | /* Send an synchronuous update event to the module */ | ||
6491 | SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); | ||
6492 | if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) { | ||
6493 | |||
6494 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047, | ||
6495 | SK_PNMI_ERR047MSG); | ||
6496 | |||
6497 | return (SK_PNMI_ERR_GENERAL); | ||
6498 | } | ||
6499 | |||
6500 | return (SK_PNMI_ERR_OK); | ||
6501 | } | ||
6502 | |||
6503 | /***************************************************************************** | ||
6504 | * | ||
6505 | * RlmtUpdate - Let the RLMT update its internal values | ||
6506 | * | ||
6507 | * Description: | ||
6508 | * Just to be sure that the RLMT module holds its internal data | ||
6509 | * structures up to date, we send an update event before we make | ||
6510 | * any access. | ||
6511 | * | ||
6512 | * Returns: | ||
6513 | * SK_PNMI_ERR_OK Task successfully performed. | ||
6514 | * SK_PNMI_ERR_GENERAL Something went wrong. | ||
6515 | */ | ||
6516 | PNMI_STATIC int RlmtUpdate( | ||
6517 | SK_AC *pAC, /* Pointer to adapter context */ | ||
6518 | SK_IOC IoC, /* IO context handle */ | ||
6519 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ | ||
6520 | { | ||
6521 | SK_EVPARA EventParam; | ||
6522 | |||
6523 | |||
6524 | /* Was the module already updated during the current PNMI call? */ | ||
6525 | if (pAC->Pnmi.RlmtUpdatedFlag > 0) { | ||
6526 | |||
6527 | return (SK_PNMI_ERR_OK); | ||
6528 | } | ||
6529 | |||
6530 | /* Send an synchronuous update event to the module */ | ||
6531 | SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); | ||
6532 | EventParam.Para32[0] = NetIndex; | ||
6533 | EventParam.Para32[1] = (SK_U32)-1; | ||
6534 | if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) { | ||
6535 | |||
6536 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048, | ||
6537 | SK_PNMI_ERR048MSG); | ||
6538 | |||
6539 | return (SK_PNMI_ERR_GENERAL); | ||
6540 | } | ||
6541 | |||
6542 | return (SK_PNMI_ERR_OK); | ||
6543 | } | ||
6544 | |||
6545 | /***************************************************************************** | ||
6546 | * | ||
6547 | * MacUpdate - Force the XMAC to output the current statistic | ||
6548 | * | ||
6549 | * Description: | ||
6550 | * The XMAC holds its statistic internally. To obtain the current | ||
6551 | * values we must send a command so that the statistic data will | ||
6552 | * be written to a predefined memory area on the adapter. | ||
6553 | * | ||
6554 | * Returns: | ||
6555 | * SK_PNMI_ERR_OK Task successfully performed. | ||
6556 | * SK_PNMI_ERR_GENERAL Something went wrong. | ||
6557 | */ | ||
6558 | PNMI_STATIC int MacUpdate( | ||
6559 | SK_AC *pAC, /* Pointer to adapter context */ | ||
6560 | SK_IOC IoC, /* IO context handle */ | ||
6561 | unsigned int FirstMac, /* Index of the first Mac to be updated */ | ||
6562 | unsigned int LastMac) /* Index of the last Mac to be updated */ | ||
6563 | { | ||
6564 | unsigned int MacIndex; | ||
6565 | |||
6566 | /* | ||
6567 | * Were the statistics already updated during the | ||
6568 | * current PNMI call? | ||
6569 | */ | ||
6570 | if (pAC->Pnmi.MacUpdatedFlag > 0) { | ||
6571 | |||
6572 | return (SK_PNMI_ERR_OK); | ||
6573 | } | ||
6574 | |||
6575 | /* Send an update command to all MACs specified */ | ||
6576 | for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) { | ||
6577 | |||
6578 | /* | ||
6579 | * 2002-09-13 pweber: Freeze the current SW counters. | ||
6580 | * (That should be done as close as | ||
6581 | * possible to the update of the | ||
6582 | * HW counters) | ||
6583 | */ | ||
6584 | if (pAC->GIni.GIMacType == SK_MAC_XMAC) { | ||
6585 | pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex]; | ||
6586 | } | ||
6587 | |||
6588 | /* 2002-09-13 pweber: Update the HW counter */ | ||
6589 | if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) { | ||
6590 | |||
6591 | return (SK_PNMI_ERR_GENERAL); | ||
6592 | } | ||
6593 | } | ||
6594 | |||
6595 | return (SK_PNMI_ERR_OK); | ||
6596 | } | ||
6597 | |||
6598 | /***************************************************************************** | ||
6599 | * | ||
6600 | * GetStatVal - Retrieve an XMAC statistic counter | ||
6601 | * | ||
6602 | * Description: | ||
6603 | * Retrieves the statistic counter of a virtual or physical port. The | ||
6604 | * virtual port is identified by the index 0. It consists of all | ||
6605 | * currently active ports. To obtain the counter value for this port | ||
6606 | * we must add the statistic counter of all active ports. To grant | ||
6607 | * continuous counter values for the virtual port even when port | ||
6608 | * switches occur we must additionally add a delta value, which was | ||
6609 | * calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event. | ||
6610 | * | ||
6611 | * Returns: | ||
6612 | * Requested statistic value | ||
6613 | */ | ||
6614 | PNMI_STATIC SK_U64 GetStatVal( | ||
6615 | SK_AC *pAC, /* Pointer to adapter context */ | ||
6616 | SK_IOC IoC, /* IO context handle */ | ||
6617 | unsigned int LogPortIndex, /* Index of the logical Port to be processed */ | ||
6618 | unsigned int StatIndex, /* Index to statistic value */ | ||
6619 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ | ||
6620 | { | ||
6621 | unsigned int PhysPortIndex; | ||
6622 | unsigned int PhysPortMax; | ||
6623 | SK_U64 Val = 0; | ||
6624 | |||
6625 | |||
6626 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */ | ||
6627 | |||
6628 | PhysPortIndex = NetIndex; | ||
6629 | |||
6630 | Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex); | ||
6631 | } | ||
6632 | else { /* Single Net mode */ | ||
6633 | |||
6634 | if (LogPortIndex == 0) { | ||
6635 | |||
6636 | PhysPortMax = pAC->GIni.GIMacsFound; | ||
6637 | |||
6638 | /* Add counter of all active ports */ | ||
6639 | for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; | ||
6640 | PhysPortIndex ++) { | ||
6641 | |||
6642 | if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { | ||
6643 | |||
6644 | Val += GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex); | ||
6645 | } | ||
6646 | } | ||
6647 | |||
6648 | /* Correct value because of port switches */ | ||
6649 | Val += pAC->Pnmi.VirtualCounterOffset[StatIndex]; | ||
6650 | } | ||
6651 | else { | ||
6652 | /* Get counter value of physical port */ | ||
6653 | PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); | ||
6654 | |||
6655 | Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex); | ||
6656 | } | ||
6657 | } | ||
6658 | return (Val); | ||
6659 | } | ||
6660 | |||
6661 | /***************************************************************************** | ||
6662 | * | ||
6663 | * GetPhysStatVal - Get counter value for physical port | ||
6664 | * | ||
6665 | * Description: | ||
6666 | * Builds a 64bit counter value. Except for the octet counters | ||
6667 | * the lower 32bit are counted in hardware and the upper 32bit | ||
6668 | * in software by monitoring counter overflow interrupts in the | ||
6669 | * event handler. To grant continous counter values during XMAC | ||
6670 | * resets (caused by a workaround) we must add a delta value. | ||
6671 | * The delta was calculated in the event handler when a | ||
6672 | * SK_PNMI_EVT_XMAC_RESET was received. | ||
6673 | * | ||
6674 | * Returns: | ||
6675 | * Counter value | ||
6676 | */ | ||
6677 | PNMI_STATIC SK_U64 GetPhysStatVal( | ||
6678 | SK_AC *pAC, /* Pointer to adapter context */ | ||
6679 | SK_IOC IoC, /* IO context handle */ | ||
6680 | unsigned int PhysPortIndex, /* Index of the logical Port to be processed */ | ||
6681 | unsigned int StatIndex) /* Index to statistic value */ | ||
6682 | { | ||
6683 | SK_U64 Val = 0; | ||
6684 | SK_U32 LowVal = 0; | ||
6685 | SK_U32 HighVal = 0; | ||
6686 | SK_U16 Word; | ||
6687 | int MacType; | ||
6688 | unsigned int HelpIndex; | ||
6689 | SK_GEPORT *pPrt; | ||
6690 | |||
6691 | SK_PNMI_PORT *pPnmiPrt; | ||
6692 | SK_GEMACFUNC *pFnMac; | ||
6693 | |||
6694 | pPrt = &pAC->GIni.GP[PhysPortIndex]; | ||
6695 | |||
6696 | MacType = pAC->GIni.GIMacType; | ||
6697 | |||
6698 | /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ | ||
6699 | if (MacType == SK_MAC_XMAC) { | ||
6700 | pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex]; | ||
6701 | } | ||
6702 | else { | ||
6703 | pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex]; | ||
6704 | } | ||
6705 | |||
6706 | pFnMac = &pAC->GIni.GIFunc; | ||
6707 | |||
6708 | switch (StatIndex) { | ||
6709 | case SK_PNMI_HTX: | ||
6710 | if (MacType == SK_MAC_GMAC) { | ||
6711 | (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
6712 | StatAddr[SK_PNMI_HTX_BROADCAST][MacType].Reg, | ||
6713 | &LowVal); | ||
6714 | (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
6715 | StatAddr[SK_PNMI_HTX_MULTICAST][MacType].Reg, | ||
6716 | &HighVal); | ||
6717 | LowVal += HighVal; | ||
6718 | (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
6719 | StatAddr[SK_PNMI_HTX_UNICAST][MacType].Reg, | ||
6720 | &HighVal); | ||
6721 | LowVal += HighVal; | ||
6722 | } | ||
6723 | else { | ||
6724 | (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
6725 | StatAddr[StatIndex][MacType].Reg, | ||
6726 | &LowVal); | ||
6727 | } | ||
6728 | HighVal = pPnmiPrt->CounterHigh[StatIndex]; | ||
6729 | break; | ||
6730 | |||
6731 | case SK_PNMI_HRX: | ||
6732 | if (MacType == SK_MAC_GMAC) { | ||
6733 | (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
6734 | StatAddr[SK_PNMI_HRX_BROADCAST][MacType].Reg, | ||
6735 | &LowVal); | ||
6736 | (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
6737 | StatAddr[SK_PNMI_HRX_MULTICAST][MacType].Reg, | ||
6738 | &HighVal); | ||
6739 | LowVal += HighVal; | ||
6740 | (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
6741 | StatAddr[SK_PNMI_HRX_UNICAST][MacType].Reg, | ||
6742 | &HighVal); | ||
6743 | LowVal += HighVal; | ||
6744 | } | ||
6745 | else { | ||
6746 | (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
6747 | StatAddr[StatIndex][MacType].Reg, | ||
6748 | &LowVal); | ||
6749 | } | ||
6750 | HighVal = pPnmiPrt->CounterHigh[StatIndex]; | ||
6751 | break; | ||
6752 | |||
6753 | case SK_PNMI_HTX_OCTET: | ||
6754 | case SK_PNMI_HRX_OCTET: | ||
6755 | (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
6756 | StatAddr[StatIndex][MacType].Reg, | ||
6757 | &HighVal); | ||
6758 | (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
6759 | StatAddr[StatIndex + 1][MacType].Reg, | ||
6760 | &LowVal); | ||
6761 | break; | ||
6762 | |||
6763 | case SK_PNMI_HTX_BURST: | ||
6764 | case SK_PNMI_HTX_EXCESS_DEF: | ||
6765 | case SK_PNMI_HTX_CARRIER: | ||
6766 | /* Not supported by GMAC */ | ||
6767 | if (MacType == SK_MAC_GMAC) { | ||
6768 | return (Val); | ||
6769 | } | ||
6770 | |||
6771 | (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
6772 | StatAddr[StatIndex][MacType].Reg, | ||
6773 | &LowVal); | ||
6774 | HighVal = pPnmiPrt->CounterHigh[StatIndex]; | ||
6775 | break; | ||
6776 | |||
6777 | case SK_PNMI_HTX_MACC: | ||
6778 | /* GMAC only supports PAUSE MAC control frames */ | ||
6779 | if (MacType == SK_MAC_GMAC) { | ||
6780 | HelpIndex = SK_PNMI_HTX_PMACC; | ||
6781 | } | ||
6782 | else { | ||
6783 | HelpIndex = StatIndex; | ||
6784 | } | ||
6785 | |||
6786 | (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
6787 | StatAddr[HelpIndex][MacType].Reg, | ||
6788 | &LowVal); | ||
6789 | |||
6790 | HighVal = pPnmiPrt->CounterHigh[StatIndex]; | ||
6791 | break; | ||
6792 | |||
6793 | case SK_PNMI_HTX_COL: | ||
6794 | case SK_PNMI_HRX_UNDERSIZE: | ||
6795 | /* Not supported by XMAC */ | ||
6796 | if (MacType == SK_MAC_XMAC) { | ||
6797 | return (Val); | ||
6798 | } | ||
6799 | |||
6800 | (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
6801 | StatAddr[StatIndex][MacType].Reg, | ||
6802 | &LowVal); | ||
6803 | HighVal = pPnmiPrt->CounterHigh[StatIndex]; | ||
6804 | break; | ||
6805 | |||
6806 | case SK_PNMI_HTX_DEFFERAL: | ||
6807 | /* Not supported by GMAC */ | ||
6808 | if (MacType == SK_MAC_GMAC) { | ||
6809 | return (Val); | ||
6810 | } | ||
6811 | |||
6812 | /* | ||
6813 | * XMAC counts frames with deferred transmission | ||
6814 | * even in full-duplex mode. | ||
6815 | * | ||
6816 | * In full-duplex mode the counter remains constant! | ||
6817 | */ | ||
6818 | if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) || | ||
6819 | (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL)) { | ||
6820 | |||
6821 | LowVal = 0; | ||
6822 | HighVal = 0; | ||
6823 | } | ||
6824 | else { | ||
6825 | /* Otherwise get contents of hardware register */ | ||
6826 | (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
6827 | StatAddr[StatIndex][MacType].Reg, | ||
6828 | &LowVal); | ||
6829 | HighVal = pPnmiPrt->CounterHigh[StatIndex]; | ||
6830 | } | ||
6831 | break; | ||
6832 | |||
6833 | case SK_PNMI_HRX_BADOCTET: | ||
6834 | /* Not supported by XMAC */ | ||
6835 | if (MacType == SK_MAC_XMAC) { | ||
6836 | return (Val); | ||
6837 | } | ||
6838 | |||
6839 | (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
6840 | StatAddr[StatIndex][MacType].Reg, | ||
6841 | &HighVal); | ||
6842 | (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
6843 | StatAddr[StatIndex + 1][MacType].Reg, | ||
6844 | &LowVal); | ||
6845 | break; | ||
6846 | |||
6847 | case SK_PNMI_HTX_OCTETLOW: | ||
6848 | case SK_PNMI_HRX_OCTETLOW: | ||
6849 | case SK_PNMI_HRX_BADOCTETLOW: | ||
6850 | return (Val); | ||
6851 | |||
6852 | case SK_PNMI_HRX_LONGFRAMES: | ||
6853 | /* For XMAC the SW counter is managed by PNMI */ | ||
6854 | if (MacType == SK_MAC_XMAC) { | ||
6855 | return (pPnmiPrt->StatRxLongFrameCts); | ||
6856 | } | ||
6857 | |||
6858 | (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
6859 | StatAddr[StatIndex][MacType].Reg, | ||
6860 | &LowVal); | ||
6861 | HighVal = pPnmiPrt->CounterHigh[StatIndex]; | ||
6862 | break; | ||
6863 | |||
6864 | case SK_PNMI_HRX_TOO_LONG: | ||
6865 | (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
6866 | StatAddr[StatIndex][MacType].Reg, | ||
6867 | &LowVal); | ||
6868 | HighVal = pPnmiPrt->CounterHigh[StatIndex]; | ||
6869 | |||
6870 | Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal); | ||
6871 | |||
6872 | if (MacType == SK_MAC_GMAC) { | ||
6873 | /* For GMAC the SW counter is additionally managed by PNMI */ | ||
6874 | Val += pPnmiPrt->StatRxFrameTooLongCts; | ||
6875 | } | ||
6876 | else { | ||
6877 | /* | ||
6878 | * Frames longer than IEEE 802.3 frame max size are counted | ||
6879 | * by XMAC in frame_too_long counter even reception of long | ||
6880 | * frames was enabled and the frame was correct. | ||
6881 | * So correct the value by subtracting RxLongFrame counter. | ||
6882 | */ | ||
6883 | Val -= pPnmiPrt->StatRxLongFrameCts; | ||
6884 | } | ||
6885 | |||
6886 | LowVal = (SK_U32)Val; | ||
6887 | HighVal = (SK_U32)(Val >> 32); | ||
6888 | break; | ||
6889 | |||
6890 | case SK_PNMI_HRX_SHORTS: | ||
6891 | /* Not supported by GMAC */ | ||
6892 | if (MacType == SK_MAC_GMAC) { | ||
6893 | /* GM_RXE_FRAG?? */ | ||
6894 | return (Val); | ||
6895 | } | ||
6896 | |||
6897 | /* | ||
6898 | * XMAC counts short frame errors even if link down (#10620) | ||
6899 | * | ||
6900 | * If link-down the counter remains constant | ||
6901 | */ | ||
6902 | if (pPrt->PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) { | ||
6903 | |||
6904 | /* Otherwise get incremental difference */ | ||
6905 | (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
6906 | StatAddr[StatIndex][MacType].Reg, | ||
6907 | &LowVal); | ||
6908 | HighVal = pPnmiPrt->CounterHigh[StatIndex]; | ||
6909 | |||
6910 | Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal); | ||
6911 | Val -= pPnmiPrt->RxShortZeroMark; | ||
6912 | |||
6913 | LowVal = (SK_U32)Val; | ||
6914 | HighVal = (SK_U32)(Val >> 32); | ||
6915 | } | ||
6916 | break; | ||
6917 | |||
6918 | case SK_PNMI_HRX_MACC: | ||
6919 | case SK_PNMI_HRX_MACC_UNKWN: | ||
6920 | case SK_PNMI_HRX_BURST: | ||
6921 | case SK_PNMI_HRX_MISSED: | ||
6922 | case SK_PNMI_HRX_FRAMING: | ||
6923 | case SK_PNMI_HRX_CARRIER: | ||
6924 | case SK_PNMI_HRX_IRLENGTH: | ||
6925 | case SK_PNMI_HRX_SYMBOL: | ||
6926 | case SK_PNMI_HRX_CEXT: | ||
6927 | /* Not supported by GMAC */ | ||
6928 | if (MacType == SK_MAC_GMAC) { | ||
6929 | return (Val); | ||
6930 | } | ||
6931 | |||
6932 | (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
6933 | StatAddr[StatIndex][MacType].Reg, | ||
6934 | &LowVal); | ||
6935 | HighVal = pPnmiPrt->CounterHigh[StatIndex]; | ||
6936 | break; | ||
6937 | |||
6938 | case SK_PNMI_HRX_PMACC_ERR: | ||
6939 | /* For GMAC the SW counter is managed by PNMI */ | ||
6940 | if (MacType == SK_MAC_GMAC) { | ||
6941 | return (pPnmiPrt->StatRxPMaccErr); | ||
6942 | } | ||
6943 | |||
6944 | (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
6945 | StatAddr[StatIndex][MacType].Reg, | ||
6946 | &LowVal); | ||
6947 | HighVal = pPnmiPrt->CounterHigh[StatIndex]; | ||
6948 | break; | ||
6949 | |||
6950 | /* SW counter managed by PNMI */ | ||
6951 | case SK_PNMI_HTX_SYNC: | ||
6952 | LowVal = (SK_U32)pPnmiPrt->StatSyncCts; | ||
6953 | HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32); | ||
6954 | break; | ||
6955 | |||
6956 | /* SW counter managed by PNMI */ | ||
6957 | case SK_PNMI_HTX_SYNC_OCTET: | ||
6958 | LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts; | ||
6959 | HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32); | ||
6960 | break; | ||
6961 | |||
6962 | case SK_PNMI_HRX_FCS: | ||
6963 | /* | ||
6964 | * Broadcom filters FCS errors and counts it in | ||
6965 | * Receive Error Counter register | ||
6966 | */ | ||
6967 | if (pPrt->PhyType == SK_PHY_BCOM) { | ||
6968 | /* do not read while not initialized (PHY_READ hangs!)*/ | ||
6969 | if (pPrt->PState != SK_PRT_RESET) { | ||
6970 | SkXmPhyRead(pAC, IoC, PhysPortIndex, PHY_BCOM_RE_CTR, &Word); | ||
6971 | |||
6972 | LowVal = Word; | ||
6973 | } | ||
6974 | HighVal = pPnmiPrt->CounterHigh[StatIndex]; | ||
6975 | } | ||
6976 | else { | ||
6977 | (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
6978 | StatAddr[StatIndex][MacType].Reg, | ||
6979 | &LowVal); | ||
6980 | HighVal = pPnmiPrt->CounterHigh[StatIndex]; | ||
6981 | } | ||
6982 | break; | ||
6983 | |||
6984 | default: | ||
6985 | (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, | ||
6986 | StatAddr[StatIndex][MacType].Reg, | ||
6987 | &LowVal); | ||
6988 | HighVal = pPnmiPrt->CounterHigh[StatIndex]; | ||
6989 | break; | ||
6990 | } | ||
6991 | |||
6992 | Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal); | ||
6993 | |||
6994 | /* Correct value because of possible XMAC reset. XMAC Errata #2 */ | ||
6995 | Val += pPnmiPrt->CounterOffset[StatIndex]; | ||
6996 | |||
6997 | return (Val); | ||
6998 | } | ||
6999 | |||
7000 | /***************************************************************************** | ||
7001 | * | ||
7002 | * ResetCounter - Set all counters and timestamps to zero | ||
7003 | * | ||
7004 | * Description: | ||
7005 | * Notifies other common modules which store statistic data to | ||
7006 | * reset their counters and finally reset our own counters. | ||
7007 | * | ||
7008 | * Returns: | ||
7009 | * Nothing | ||
7010 | */ | ||
7011 | PNMI_STATIC void ResetCounter( | ||
7012 | SK_AC *pAC, /* Pointer to adapter context */ | ||
7013 | SK_IOC IoC, /* IO context handle */ | ||
7014 | SK_U32 NetIndex) | ||
7015 | { | ||
7016 | unsigned int PhysPortIndex; | ||
7017 | SK_EVPARA EventParam; | ||
7018 | |||
7019 | |||
7020 | SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); | ||
7021 | |||
7022 | /* Notify sensor module */ | ||
7023 | SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam); | ||
7024 | |||
7025 | /* Notify RLMT module */ | ||
7026 | EventParam.Para32[0] = NetIndex; | ||
7027 | EventParam.Para32[1] = (SK_U32)-1; | ||
7028 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam); | ||
7029 | EventParam.Para32[1] = 0; | ||
7030 | |||
7031 | /* Notify SIRQ module */ | ||
7032 | SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam); | ||
7033 | |||
7034 | /* Notify CSUM module */ | ||
7035 | #ifdef SK_USE_CSUM | ||
7036 | EventParam.Para32[0] = NetIndex; | ||
7037 | EventParam.Para32[1] = (SK_U32)-1; | ||
7038 | SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS, | ||
7039 | EventParam); | ||
7040 | #endif /* SK_USE_CSUM */ | ||
7041 | |||
7042 | /* Clear XMAC statistic */ | ||
7043 | for (PhysPortIndex = 0; PhysPortIndex < | ||
7044 | (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) { | ||
7045 | |||
7046 | (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex); | ||
7047 | |||
7048 | SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh, | ||
7049 | 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh)); | ||
7050 | SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. | ||
7051 | CounterOffset, 0, sizeof(pAC->Pnmi.Port[ | ||
7052 | PhysPortIndex].CounterOffset)); | ||
7053 | SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts, | ||
7054 | 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts)); | ||
7055 | SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. | ||
7056 | StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[ | ||
7057 | PhysPortIndex].StatSyncOctetsCts)); | ||
7058 | SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. | ||
7059 | StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[ | ||
7060 | PhysPortIndex].StatRxLongFrameCts)); | ||
7061 | SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. | ||
7062 | StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[ | ||
7063 | PhysPortIndex].StatRxFrameTooLongCts)); | ||
7064 | SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. | ||
7065 | StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[ | ||
7066 | PhysPortIndex].StatRxPMaccErr)); | ||
7067 | } | ||
7068 | |||
7069 | /* | ||
7070 | * Clear local statistics | ||
7071 | */ | ||
7072 | SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0, | ||
7073 | sizeof(pAC->Pnmi.VirtualCounterOffset)); | ||
7074 | pAC->Pnmi.RlmtChangeCts = 0; | ||
7075 | pAC->Pnmi.RlmtChangeTime = 0; | ||
7076 | SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0, | ||
7077 | sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue)); | ||
7078 | pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0; | ||
7079 | pAC->Pnmi.RlmtChangeEstimate.Estimate = 0; | ||
7080 | pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0; | ||
7081 | pAC->Pnmi.Port[NetIndex].TxRetryCts = 0; | ||
7082 | pAC->Pnmi.Port[NetIndex].RxIntrCts = 0; | ||
7083 | pAC->Pnmi.Port[NetIndex].TxIntrCts = 0; | ||
7084 | pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0; | ||
7085 | pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0; | ||
7086 | pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0; | ||
7087 | pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0; | ||
7088 | pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0; | ||
7089 | pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0; | ||
7090 | } | ||
7091 | |||
7092 | /***************************************************************************** | ||
7093 | * | ||
7094 | * GetTrapEntry - Get an entry in the trap buffer | ||
7095 | * | ||
7096 | * Description: | ||
7097 | * The trap buffer stores various events. A user application somehow | ||
7098 | * gets notified that an event occured and retrieves the trap buffer | ||
7099 | * contens (or simply polls the buffer). The buffer is organized as | ||
7100 | * a ring which stores the newest traps at the beginning. The oldest | ||
7101 | * traps are overwritten by the newest ones. Each trap entry has a | ||
7102 | * unique number, so that applications may detect new trap entries. | ||
7103 | * | ||
7104 | * Returns: | ||
7105 | * A pointer to the trap entry | ||
7106 | */ | ||
7107 | PNMI_STATIC char* GetTrapEntry( | ||
7108 | SK_AC *pAC, /* Pointer to adapter context */ | ||
7109 | SK_U32 TrapId, /* SNMP ID of the trap */ | ||
7110 | unsigned int Size) /* Space needed for trap entry */ | ||
7111 | { | ||
7112 | unsigned int BufPad = pAC->Pnmi.TrapBufPad; | ||
7113 | unsigned int BufFree = pAC->Pnmi.TrapBufFree; | ||
7114 | unsigned int Beg = pAC->Pnmi.TrapQueueBeg; | ||
7115 | unsigned int End = pAC->Pnmi.TrapQueueEnd; | ||
7116 | char *pBuf = &pAC->Pnmi.TrapBuf[0]; | ||
7117 | int Wrap; | ||
7118 | unsigned int NeededSpace; | ||
7119 | unsigned int EntrySize; | ||
7120 | SK_U32 Val32; | ||
7121 | SK_U64 Val64; | ||
7122 | |||
7123 | |||
7124 | /* Last byte of entry will get a copy of the entry length */ | ||
7125 | Size ++; | ||
7126 | |||
7127 | /* | ||
7128 | * Calculate needed buffer space */ | ||
7129 | if (Beg >= Size) { | ||
7130 | |||
7131 | NeededSpace = Size; | ||
7132 | Wrap = SK_FALSE; | ||
7133 | } | ||
7134 | else { | ||
7135 | NeededSpace = Beg + Size; | ||
7136 | Wrap = SK_TRUE; | ||
7137 | } | ||
7138 | |||
7139 | /* | ||
7140 | * Check if enough buffer space is provided. Otherwise | ||
7141 | * free some entries. Leave one byte space between begin | ||
7142 | * and end of buffer to make it possible to detect whether | ||
7143 | * the buffer is full or empty | ||
7144 | */ | ||
7145 | while (BufFree < NeededSpace + 1) { | ||
7146 | |||
7147 | if (End == 0) { | ||
7148 | |||
7149 | End = SK_PNMI_TRAP_QUEUE_LEN; | ||
7150 | } | ||
7151 | |||
7152 | EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1); | ||
7153 | BufFree += EntrySize; | ||
7154 | End -= EntrySize; | ||
7155 | #ifdef DEBUG | ||
7156 | SK_MEMSET(pBuf + End, (char)(-1), EntrySize); | ||
7157 | #endif /* DEBUG */ | ||
7158 | if (End == BufPad) { | ||
7159 | #ifdef DEBUG | ||
7160 | SK_MEMSET(pBuf, (char)(-1), End); | ||
7161 | #endif /* DEBUG */ | ||
7162 | BufFree += End; | ||
7163 | End = 0; | ||
7164 | BufPad = 0; | ||
7165 | } | ||
7166 | } | ||
7167 | |||
7168 | /* | ||
7169 | * Insert new entry as first entry. Newest entries are | ||
7170 | * stored at the beginning of the queue. | ||
7171 | */ | ||
7172 | if (Wrap) { | ||
7173 | |||
7174 | BufPad = Beg; | ||
7175 | Beg = SK_PNMI_TRAP_QUEUE_LEN - Size; | ||
7176 | } | ||
7177 | else { | ||
7178 | Beg = Beg - Size; | ||
7179 | } | ||
7180 | BufFree -= NeededSpace; | ||
7181 | |||
7182 | /* Save the current offsets */ | ||
7183 | pAC->Pnmi.TrapQueueBeg = Beg; | ||
7184 | pAC->Pnmi.TrapQueueEnd = End; | ||
7185 | pAC->Pnmi.TrapBufPad = BufPad; | ||
7186 | pAC->Pnmi.TrapBufFree = BufFree; | ||
7187 | |||
7188 | /* Initialize the trap entry */ | ||
7189 | *(pBuf + Beg + Size - 1) = (char)Size; | ||
7190 | *(pBuf + Beg) = (char)Size; | ||
7191 | Val32 = (pAC->Pnmi.TrapUnique) ++; | ||
7192 | SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32); | ||
7193 | SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId); | ||
7194 | Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC)); | ||
7195 | SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64); | ||
7196 | |||
7197 | return (pBuf + Beg); | ||
7198 | } | ||
7199 | |||
7200 | /***************************************************************************** | ||
7201 | * | ||
7202 | * CopyTrapQueue - Copies the trap buffer for the TRAP OID | ||
7203 | * | ||
7204 | * Description: | ||
7205 | * On a query of the TRAP OID the trap buffer contents will be | ||
7206 | * copied continuously to the request buffer, which must be large | ||
7207 | * enough. No length check is performed. | ||
7208 | * | ||
7209 | * Returns: | ||
7210 | * Nothing | ||
7211 | */ | ||
7212 | PNMI_STATIC void CopyTrapQueue( | ||
7213 | SK_AC *pAC, /* Pointer to adapter context */ | ||
7214 | char *pDstBuf) /* Buffer to which the queued traps will be copied */ | ||
7215 | { | ||
7216 | unsigned int BufPad = pAC->Pnmi.TrapBufPad; | ||
7217 | unsigned int Trap = pAC->Pnmi.TrapQueueBeg; | ||
7218 | unsigned int End = pAC->Pnmi.TrapQueueEnd; | ||
7219 | char *pBuf = &pAC->Pnmi.TrapBuf[0]; | ||
7220 | unsigned int Len; | ||
7221 | unsigned int DstOff = 0; | ||
7222 | |||
7223 | |||
7224 | while (Trap != End) { | ||
7225 | |||
7226 | Len = (unsigned int)*(pBuf + Trap); | ||
7227 | |||
7228 | /* | ||
7229 | * Last byte containing a copy of the length will | ||
7230 | * not be copied. | ||
7231 | */ | ||
7232 | *(pDstBuf + DstOff) = (char)(Len - 1); | ||
7233 | SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2); | ||
7234 | DstOff += Len - 1; | ||
7235 | |||
7236 | Trap += Len; | ||
7237 | if (Trap == SK_PNMI_TRAP_QUEUE_LEN) { | ||
7238 | |||
7239 | Trap = BufPad; | ||
7240 | } | ||
7241 | } | ||
7242 | } | ||
7243 | |||
7244 | /***************************************************************************** | ||
7245 | * | ||
7246 | * GetTrapQueueLen - Get the length of the trap buffer | ||
7247 | * | ||
7248 | * Description: | ||
7249 | * Evaluates the number of currently stored traps and the needed | ||
7250 | * buffer size to retrieve them. | ||
7251 | * | ||
7252 | * Returns: | ||
7253 | * Nothing | ||
7254 | */ | ||
7255 | PNMI_STATIC void GetTrapQueueLen( | ||
7256 | SK_AC *pAC, /* Pointer to adapter context */ | ||
7257 | unsigned int *pLen, /* Length in Bytes of all queued traps */ | ||
7258 | unsigned int *pEntries) /* Returns number of trapes stored in queue */ | ||
7259 | { | ||
7260 | unsigned int BufPad = pAC->Pnmi.TrapBufPad; | ||
7261 | unsigned int Trap = pAC->Pnmi.TrapQueueBeg; | ||
7262 | unsigned int End = pAC->Pnmi.TrapQueueEnd; | ||
7263 | char *pBuf = &pAC->Pnmi.TrapBuf[0]; | ||
7264 | unsigned int Len; | ||
7265 | unsigned int Entries = 0; | ||
7266 | unsigned int TotalLen = 0; | ||
7267 | |||
7268 | |||
7269 | while (Trap != End) { | ||
7270 | |||
7271 | Len = (unsigned int)*(pBuf + Trap); | ||
7272 | TotalLen += Len - 1; | ||
7273 | Entries ++; | ||
7274 | |||
7275 | Trap += Len; | ||
7276 | if (Trap == SK_PNMI_TRAP_QUEUE_LEN) { | ||
7277 | |||
7278 | Trap = BufPad; | ||
7279 | } | ||
7280 | } | ||
7281 | |||
7282 | *pEntries = Entries; | ||
7283 | *pLen = TotalLen; | ||
7284 | } | ||
7285 | |||
7286 | /***************************************************************************** | ||
7287 | * | ||
7288 | * QueueSimpleTrap - Store a simple trap to the trap buffer | ||
7289 | * | ||
7290 | * Description: | ||
7291 | * A simple trap is a trap with now additional data. It consists | ||
7292 | * simply of a trap code. | ||
7293 | * | ||
7294 | * Returns: | ||
7295 | * Nothing | ||
7296 | */ | ||
7297 | PNMI_STATIC void QueueSimpleTrap( | ||
7298 | SK_AC *pAC, /* Pointer to adapter context */ | ||
7299 | SK_U32 TrapId) /* Type of sensor trap */ | ||
7300 | { | ||
7301 | GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN); | ||
7302 | } | ||
7303 | |||
7304 | /***************************************************************************** | ||
7305 | * | ||
7306 | * QueueSensorTrap - Stores a sensor trap in the trap buffer | ||
7307 | * | ||
7308 | * Description: | ||
7309 | * Gets an entry in the trap buffer and fills it with sensor related | ||
7310 | * data. | ||
7311 | * | ||
7312 | * Returns: | ||
7313 | * Nothing | ||
7314 | */ | ||
7315 | PNMI_STATIC void QueueSensorTrap( | ||
7316 | SK_AC *pAC, /* Pointer to adapter context */ | ||
7317 | SK_U32 TrapId, /* Type of sensor trap */ | ||
7318 | unsigned int SensorIndex) /* Index of sensor which caused the trap */ | ||
7319 | { | ||
7320 | char *pBuf; | ||
7321 | unsigned int Offset; | ||
7322 | unsigned int DescrLen; | ||
7323 | SK_U32 Val32; | ||
7324 | |||
7325 | |||
7326 | /* Get trap buffer entry */ | ||
7327 | DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc); | ||
7328 | pBuf = GetTrapEntry(pAC, TrapId, | ||
7329 | SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen); | ||
7330 | Offset = SK_PNMI_TRAP_SIMPLE_LEN; | ||
7331 | |||
7332 | /* Store additionally sensor trap related data */ | ||
7333 | Val32 = OID_SKGE_SENSOR_INDEX; | ||
7334 | SK_PNMI_STORE_U32(pBuf + Offset, Val32); | ||
7335 | *(pBuf + Offset + 4) = 4; | ||
7336 | Val32 = (SK_U32)SensorIndex; | ||
7337 | SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32); | ||
7338 | Offset += 9; | ||
7339 | |||
7340 | Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR; | ||
7341 | SK_PNMI_STORE_U32(pBuf + Offset, Val32); | ||
7342 | *(pBuf + Offset + 4) = (char)DescrLen; | ||
7343 | SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc, | ||
7344 | DescrLen); | ||
7345 | Offset += DescrLen + 5; | ||
7346 | |||
7347 | Val32 = OID_SKGE_SENSOR_TYPE; | ||
7348 | SK_PNMI_STORE_U32(pBuf + Offset, Val32); | ||
7349 | *(pBuf + Offset + 4) = 1; | ||
7350 | *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType; | ||
7351 | Offset += 6; | ||
7352 | |||
7353 | Val32 = OID_SKGE_SENSOR_VALUE; | ||
7354 | SK_PNMI_STORE_U32(pBuf + Offset, Val32); | ||
7355 | *(pBuf + Offset + 4) = 4; | ||
7356 | Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue; | ||
7357 | SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32); | ||
7358 | } | ||
7359 | |||
7360 | /***************************************************************************** | ||
7361 | * | ||
7362 | * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer | ||
7363 | * | ||
7364 | * Description: | ||
7365 | * Nothing further to explain. | ||
7366 | * | ||
7367 | * Returns: | ||
7368 | * Nothing | ||
7369 | */ | ||
7370 | PNMI_STATIC void QueueRlmtNewMacTrap( | ||
7371 | SK_AC *pAC, /* Pointer to adapter context */ | ||
7372 | unsigned int ActiveMac) /* Index (0..n) of the currently active port */ | ||
7373 | { | ||
7374 | char *pBuf; | ||
7375 | SK_U32 Val32; | ||
7376 | |||
7377 | |||
7378 | pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT, | ||
7379 | SK_PNMI_TRAP_RLMT_CHANGE_LEN); | ||
7380 | |||
7381 | Val32 = OID_SKGE_RLMT_PORT_ACTIVE; | ||
7382 | SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32); | ||
7383 | *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1; | ||
7384 | *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac; | ||
7385 | } | ||
7386 | |||
7387 | /***************************************************************************** | ||
7388 | * | ||
7389 | * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer | ||
7390 | * | ||
7391 | * Description: | ||
7392 | * Nothing further to explain. | ||
7393 | * | ||
7394 | * Returns: | ||
7395 | * Nothing | ||
7396 | */ | ||
7397 | PNMI_STATIC void QueueRlmtPortTrap( | ||
7398 | SK_AC *pAC, /* Pointer to adapter context */ | ||
7399 | SK_U32 TrapId, /* Type of RLMT port trap */ | ||
7400 | unsigned int PortIndex) /* Index of the port, which changed its state */ | ||
7401 | { | ||
7402 | char *pBuf; | ||
7403 | SK_U32 Val32; | ||
7404 | |||
7405 | |||
7406 | pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN); | ||
7407 | |||
7408 | Val32 = OID_SKGE_RLMT_PORT_INDEX; | ||
7409 | SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32); | ||
7410 | *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1; | ||
7411 | *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex; | ||
7412 | } | ||
7413 | |||
7414 | /***************************************************************************** | ||
7415 | * | ||
7416 | * CopyMac - Copies a MAC address | ||
7417 | * | ||
7418 | * Description: | ||
7419 | * Nothing further to explain. | ||
7420 | * | ||
7421 | * Returns: | ||
7422 | * Nothing | ||
7423 | */ | ||
7424 | PNMI_STATIC void CopyMac( | ||
7425 | char *pDst, /* Pointer to destination buffer */ | ||
7426 | SK_MAC_ADDR *pMac) /* Pointer of Source */ | ||
7427 | { | ||
7428 | int i; | ||
7429 | |||
7430 | |||
7431 | for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) { | ||
7432 | |||
7433 | *(pDst + i) = pMac->a[i]; | ||
7434 | } | ||
7435 | } | ||
7436 | |||
7437 | #ifdef SK_POWER_MGMT | ||
7438 | /***************************************************************************** | ||
7439 | * | ||
7440 | * PowerManagement - OID handler function of PowerManagement OIDs | ||
7441 | * | ||
7442 | * Description: | ||
7443 | * The code is simple. No description necessary. | ||
7444 | * | ||
7445 | * Returns: | ||
7446 | * SK_PNMI_ERR_OK The request was successfully performed. | ||
7447 | * SK_PNMI_ERR_GENERAL A general severe internal error occured. | ||
7448 | * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain | ||
7449 | * the correct data (e.g. a 32bit value is | ||
7450 | * needed, but a 16 bit value was passed). | ||
7451 | * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't | ||
7452 | * exist (e.g. port instance 3 on a two port | ||
7453 | * adapter. | ||
7454 | */ | ||
7455 | |||
7456 | PNMI_STATIC int PowerManagement( | ||
7457 | SK_AC *pAC, /* Pointer to adapter context */ | ||
7458 | SK_IOC IoC, /* IO context handle */ | ||
7459 | int Action, /* Get/PreSet/Set action */ | ||
7460 | SK_U32 Id, /* Object ID that is to be processed */ | ||
7461 | char *pBuf, /* Buffer to which to mgmt data will be retrieved */ | ||
7462 | unsigned int *pLen, /* On call: buffer length. On return: used buffer */ | ||
7463 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
7464 | unsigned int TableIndex, /* Index to the Id table */ | ||
7465 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ | ||
7466 | { | ||
7467 | |||
7468 | SK_U32 RetCode = SK_PNMI_ERR_GENERAL; | ||
7469 | |||
7470 | /* | ||
7471 | * Check instance. We only handle single instance variables | ||
7472 | */ | ||
7473 | if (Instance != (SK_U32)(-1) && Instance != 1) { | ||
7474 | |||
7475 | *pLen = 0; | ||
7476 | return (SK_PNMI_ERR_UNKNOWN_INST); | ||
7477 | } | ||
7478 | |||
7479 | |||
7480 | /* Check length */ | ||
7481 | switch (Id) { | ||
7482 | |||
7483 | case OID_PNP_CAPABILITIES: | ||
7484 | if (*pLen < sizeof(SK_PNP_CAPABILITIES)) { | ||
7485 | |||
7486 | *pLen = sizeof(SK_PNP_CAPABILITIES); | ||
7487 | return (SK_PNMI_ERR_TOO_SHORT); | ||
7488 | } | ||
7489 | break; | ||
7490 | |||
7491 | case OID_PNP_SET_POWER: | ||
7492 | case OID_PNP_QUERY_POWER: | ||
7493 | if (*pLen < sizeof(SK_DEVICE_POWER_STATE)) | ||
7494 | { | ||
7495 | *pLen = sizeof(SK_DEVICE_POWER_STATE); | ||
7496 | return (SK_PNMI_ERR_TOO_SHORT); | ||
7497 | } | ||
7498 | break; | ||
7499 | |||
7500 | case OID_PNP_ADD_WAKE_UP_PATTERN: | ||
7501 | case OID_PNP_REMOVE_WAKE_UP_PATTERN: | ||
7502 | if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) { | ||
7503 | |||
7504 | *pLen = sizeof(SK_PM_PACKET_PATTERN); | ||
7505 | return (SK_PNMI_ERR_TOO_SHORT); | ||
7506 | } | ||
7507 | break; | ||
7508 | |||
7509 | case OID_PNP_ENABLE_WAKE_UP: | ||
7510 | if (*pLen < sizeof(SK_U32)) { | ||
7511 | |||
7512 | *pLen = sizeof(SK_U32); | ||
7513 | return (SK_PNMI_ERR_TOO_SHORT); | ||
7514 | } | ||
7515 | break; | ||
7516 | } | ||
7517 | |||
7518 | /* | ||
7519 | * Perform action | ||
7520 | */ | ||
7521 | if (Action == SK_PNMI_GET) { | ||
7522 | |||
7523 | /* | ||
7524 | * Get value | ||
7525 | */ | ||
7526 | switch (Id) { | ||
7527 | |||
7528 | case OID_PNP_CAPABILITIES: | ||
7529 | RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen); | ||
7530 | break; | ||
7531 | |||
7532 | case OID_PNP_QUERY_POWER: | ||
7533 | /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests | ||
7534 | the miniport to indicate whether it can transition its NIC | ||
7535 | to the low-power state. | ||
7536 | A miniport driver must always return NDIS_STATUS_SUCCESS | ||
7537 | to a query of OID_PNP_QUERY_POWER. */ | ||
7538 | *pLen = sizeof(SK_DEVICE_POWER_STATE); | ||
7539 | RetCode = SK_PNMI_ERR_OK; | ||
7540 | break; | ||
7541 | |||
7542 | /* NDIS handles these OIDs as write-only. | ||
7543 | * So in case of get action the buffer with written length = 0 | ||
7544 | * is returned | ||
7545 | */ | ||
7546 | case OID_PNP_SET_POWER: | ||
7547 | case OID_PNP_ADD_WAKE_UP_PATTERN: | ||
7548 | case OID_PNP_REMOVE_WAKE_UP_PATTERN: | ||
7549 | *pLen = 0; | ||
7550 | RetCode = SK_PNMI_ERR_NOT_SUPPORTED; | ||
7551 | break; | ||
7552 | |||
7553 | case OID_PNP_ENABLE_WAKE_UP: | ||
7554 | RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen); | ||
7555 | break; | ||
7556 | |||
7557 | default: | ||
7558 | RetCode = SK_PNMI_ERR_GENERAL; | ||
7559 | break; | ||
7560 | } | ||
7561 | |||
7562 | return (RetCode); | ||
7563 | } | ||
7564 | |||
7565 | |||
7566 | /* | ||
7567 | * Perform preset or set | ||
7568 | */ | ||
7569 | |||
7570 | /* POWER module does not support PRESET action */ | ||
7571 | if (Action == SK_PNMI_PRESET) { | ||
7572 | return (SK_PNMI_ERR_OK); | ||
7573 | } | ||
7574 | |||
7575 | switch (Id) { | ||
7576 | case OID_PNP_SET_POWER: | ||
7577 | RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen); | ||
7578 | break; | ||
7579 | |||
7580 | case OID_PNP_ADD_WAKE_UP_PATTERN: | ||
7581 | RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen); | ||
7582 | break; | ||
7583 | |||
7584 | case OID_PNP_REMOVE_WAKE_UP_PATTERN: | ||
7585 | RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen); | ||
7586 | break; | ||
7587 | |||
7588 | case OID_PNP_ENABLE_WAKE_UP: | ||
7589 | RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen); | ||
7590 | break; | ||
7591 | |||
7592 | default: | ||
7593 | RetCode = SK_PNMI_ERR_READ_ONLY; | ||
7594 | } | ||
7595 | |||
7596 | return (RetCode); | ||
7597 | } | ||
7598 | #endif /* SK_POWER_MGMT */ | ||
7599 | |||
7600 | #ifdef SK_DIAG_SUPPORT | ||
7601 | /***************************************************************************** | ||
7602 | * | ||
7603 | * DiagActions - OID handler function of Diagnostic driver | ||
7604 | * | ||
7605 | * Description: | ||
7606 | * The code is simple. No description necessary. | ||
7607 | * | ||
7608 | * Returns: | ||
7609 | * SK_PNMI_ERR_OK The request was successfully performed. | ||
7610 | * SK_PNMI_ERR_GENERAL A general severe internal error occured. | ||
7611 | * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain | ||
7612 | * the correct data (e.g. a 32bit value is | ||
7613 | * needed, but a 16 bit value was passed). | ||
7614 | * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't | ||
7615 | * exist (e.g. port instance 3 on a two port | ||
7616 | * adapter. | ||
7617 | */ | ||
7618 | |||
7619 | PNMI_STATIC int DiagActions( | ||
7620 | SK_AC *pAC, /* Pointer to adapter context */ | ||
7621 | SK_IOC IoC, /* IO context handle */ | ||
7622 | int Action, /* GET/PRESET/SET action */ | ||
7623 | SK_U32 Id, /* Object ID that is to be processed */ | ||
7624 | char *pBuf, /* Buffer used for the management data transfer */ | ||
7625 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
7626 | SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ | ||
7627 | unsigned int TableIndex, /* Index to the Id table */ | ||
7628 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
7629 | { | ||
7630 | |||
7631 | SK_U32 DiagStatus; | ||
7632 | SK_U32 RetCode = SK_PNMI_ERR_GENERAL; | ||
7633 | |||
7634 | /* | ||
7635 | * Check instance. We only handle single instance variables. | ||
7636 | */ | ||
7637 | if (Instance != (SK_U32)(-1) && Instance != 1) { | ||
7638 | |||
7639 | *pLen = 0; | ||
7640 | return (SK_PNMI_ERR_UNKNOWN_INST); | ||
7641 | } | ||
7642 | |||
7643 | /* | ||
7644 | * Check length. | ||
7645 | */ | ||
7646 | switch (Id) { | ||
7647 | |||
7648 | case OID_SKGE_DIAG_MODE: | ||
7649 | if (*pLen < sizeof(SK_U32)) { | ||
7650 | |||
7651 | *pLen = sizeof(SK_U32); | ||
7652 | return (SK_PNMI_ERR_TOO_SHORT); | ||
7653 | } | ||
7654 | break; | ||
7655 | |||
7656 | default: | ||
7657 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040, SK_PNMI_ERR040MSG); | ||
7658 | *pLen = 0; | ||
7659 | return (SK_PNMI_ERR_GENERAL); | ||
7660 | } | ||
7661 | |||
7662 | /* Perform action. */ | ||
7663 | |||
7664 | /* GET value. */ | ||
7665 | if (Action == SK_PNMI_GET) { | ||
7666 | |||
7667 | switch (Id) { | ||
7668 | |||
7669 | case OID_SKGE_DIAG_MODE: | ||
7670 | DiagStatus = pAC->Pnmi.DiagAttached; | ||
7671 | SK_PNMI_STORE_U32(pBuf, DiagStatus); | ||
7672 | *pLen = sizeof(SK_U32); | ||
7673 | RetCode = SK_PNMI_ERR_OK; | ||
7674 | break; | ||
7675 | |||
7676 | default: | ||
7677 | *pLen = 0; | ||
7678 | RetCode = SK_PNMI_ERR_GENERAL; | ||
7679 | break; | ||
7680 | } | ||
7681 | return (RetCode); | ||
7682 | } | ||
7683 | |||
7684 | /* From here SET or PRESET value. */ | ||
7685 | |||
7686 | /* PRESET value is not supported. */ | ||
7687 | if (Action == SK_PNMI_PRESET) { | ||
7688 | return (SK_PNMI_ERR_OK); | ||
7689 | } | ||
7690 | |||
7691 | /* SET value. */ | ||
7692 | switch (Id) { | ||
7693 | case OID_SKGE_DIAG_MODE: | ||
7694 | |||
7695 | /* Handle the SET. */ | ||
7696 | switch (*pBuf) { | ||
7697 | |||
7698 | /* Attach the DIAG to this adapter. */ | ||
7699 | case SK_DIAG_ATTACHED: | ||
7700 | /* Check if we come from running */ | ||
7701 | if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) { | ||
7702 | |||
7703 | RetCode = SkDrvLeaveDiagMode(pAC); | ||
7704 | |||
7705 | } | ||
7706 | else if (pAC->Pnmi.DiagAttached == SK_DIAG_IDLE) { | ||
7707 | |||
7708 | RetCode = SK_PNMI_ERR_OK; | ||
7709 | } | ||
7710 | |||
7711 | else { | ||
7712 | |||
7713 | RetCode = SK_PNMI_ERR_GENERAL; | ||
7714 | |||
7715 | } | ||
7716 | |||
7717 | if (RetCode == SK_PNMI_ERR_OK) { | ||
7718 | |||
7719 | pAC->Pnmi.DiagAttached = SK_DIAG_ATTACHED; | ||
7720 | } | ||
7721 | break; | ||
7722 | |||
7723 | /* Enter the DIAG mode in the driver. */ | ||
7724 | case SK_DIAG_RUNNING: | ||
7725 | RetCode = SK_PNMI_ERR_OK; | ||
7726 | |||
7727 | /* | ||
7728 | * If DiagAttached is set, we can tell the driver | ||
7729 | * to enter the DIAG mode. | ||
7730 | */ | ||
7731 | if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) { | ||
7732 | /* If DiagMode is not active, we can enter it. */ | ||
7733 | if (!pAC->DiagModeActive) { | ||
7734 | |||
7735 | RetCode = SkDrvEnterDiagMode(pAC); | ||
7736 | } | ||
7737 | else { | ||
7738 | |||
7739 | RetCode = SK_PNMI_ERR_GENERAL; | ||
7740 | } | ||
7741 | } | ||
7742 | else { | ||
7743 | |||
7744 | RetCode = SK_PNMI_ERR_GENERAL; | ||
7745 | } | ||
7746 | |||
7747 | if (RetCode == SK_PNMI_ERR_OK) { | ||
7748 | |||
7749 | pAC->Pnmi.DiagAttached = SK_DIAG_RUNNING; | ||
7750 | } | ||
7751 | break; | ||
7752 | |||
7753 | case SK_DIAG_IDLE: | ||
7754 | /* Check if we come from running */ | ||
7755 | if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) { | ||
7756 | |||
7757 | RetCode = SkDrvLeaveDiagMode(pAC); | ||
7758 | |||
7759 | } | ||
7760 | else if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) { | ||
7761 | |||
7762 | RetCode = SK_PNMI_ERR_OK; | ||
7763 | } | ||
7764 | |||
7765 | else { | ||
7766 | |||
7767 | RetCode = SK_PNMI_ERR_GENERAL; | ||
7768 | |||
7769 | } | ||
7770 | |||
7771 | if (RetCode == SK_PNMI_ERR_OK) { | ||
7772 | |||
7773 | pAC->Pnmi.DiagAttached = SK_DIAG_IDLE; | ||
7774 | } | ||
7775 | break; | ||
7776 | |||
7777 | default: | ||
7778 | RetCode = SK_PNMI_ERR_BAD_VALUE; | ||
7779 | break; | ||
7780 | } | ||
7781 | break; | ||
7782 | |||
7783 | default: | ||
7784 | RetCode = SK_PNMI_ERR_GENERAL; | ||
7785 | } | ||
7786 | |||
7787 | if (RetCode == SK_PNMI_ERR_OK) { | ||
7788 | *pLen = sizeof(SK_U32); | ||
7789 | } | ||
7790 | else { | ||
7791 | |||
7792 | *pLen = 0; | ||
7793 | } | ||
7794 | return (RetCode); | ||
7795 | } | ||
7796 | #endif /* SK_DIAG_SUPPORT */ | ||
7797 | |||
7798 | /***************************************************************************** | ||
7799 | * | ||
7800 | * Vct - OID handler function of OIDs | ||
7801 | * | ||
7802 | * Description: | ||
7803 | * The code is simple. No description necessary. | ||
7804 | * | ||
7805 | * Returns: | ||
7806 | * SK_PNMI_ERR_OK The request was performed successfully. | ||
7807 | * SK_PNMI_ERR_GENERAL A general severe internal error occured. | ||
7808 | * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain | ||
7809 | * the correct data (e.g. a 32bit value is | ||
7810 | * needed, but a 16 bit value was passed). | ||
7811 | * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't | ||
7812 | * exist (e.g. port instance 3 on a two port | ||
7813 | * adapter). | ||
7814 | * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed. | ||
7815 | * | ||
7816 | */ | ||
7817 | |||
7818 | PNMI_STATIC int Vct( | ||
7819 | SK_AC *pAC, /* Pointer to adapter context */ | ||
7820 | SK_IOC IoC, /* IO context handle */ | ||
7821 | int Action, /* GET/PRESET/SET action */ | ||
7822 | SK_U32 Id, /* Object ID that is to be processed */ | ||
7823 | char *pBuf, /* Buffer used for the management data transfer */ | ||
7824 | unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ | ||
7825 | SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */ | ||
7826 | unsigned int TableIndex, /* Index to the Id table */ | ||
7827 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
7828 | { | ||
7829 | SK_GEPORT *pPrt; | ||
7830 | SK_PNMI_VCT *pVctBackupData; | ||
7831 | SK_U32 LogPortMax; | ||
7832 | SK_U32 PhysPortMax; | ||
7833 | SK_U32 PhysPortIndex; | ||
7834 | SK_U32 Limit; | ||
7835 | SK_U32 Offset; | ||
7836 | SK_BOOL Link; | ||
7837 | SK_U32 RetCode = SK_PNMI_ERR_GENERAL; | ||
7838 | int i; | ||
7839 | SK_EVPARA Para; | ||
7840 | SK_U32 CableLength; | ||
7841 | |||
7842 | /* | ||
7843 | * Calculate the port indexes from the instance. | ||
7844 | */ | ||
7845 | PhysPortMax = pAC->GIni.GIMacsFound; | ||
7846 | LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); | ||
7847 | |||
7848 | /* Dual net mode? */ | ||
7849 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
7850 | LogPortMax--; | ||
7851 | } | ||
7852 | |||
7853 | if ((Instance != (SK_U32) (-1))) { | ||
7854 | /* Check instance range. */ | ||
7855 | if ((Instance < 2) || (Instance > LogPortMax)) { | ||
7856 | *pLen = 0; | ||
7857 | return (SK_PNMI_ERR_UNKNOWN_INST); | ||
7858 | } | ||
7859 | |||
7860 | if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { | ||
7861 | PhysPortIndex = NetIndex; | ||
7862 | } | ||
7863 | else { | ||
7864 | PhysPortIndex = Instance - 2; | ||
7865 | } | ||
7866 | Limit = PhysPortIndex + 1; | ||
7867 | } | ||
7868 | else { | ||
7869 | /* | ||
7870 | * Instance == (SK_U32) (-1), get all Instances of that OID. | ||
7871 | * | ||
7872 | * Not implemented yet. May be used in future releases. | ||
7873 | */ | ||
7874 | PhysPortIndex = 0; | ||
7875 | Limit = PhysPortMax; | ||
7876 | } | ||
7877 | |||
7878 | pPrt = &pAC->GIni.GP[PhysPortIndex]; | ||
7879 | if (pPrt->PHWLinkUp) { | ||
7880 | Link = SK_TRUE; | ||
7881 | } | ||
7882 | else { | ||
7883 | Link = SK_FALSE; | ||
7884 | } | ||
7885 | |||
7886 | /* Check MAC type */ | ||
7887 | if (pPrt->PhyType != SK_PHY_MARV_COPPER) { | ||
7888 | *pLen = 0; | ||
7889 | return (SK_PNMI_ERR_GENERAL); | ||
7890 | } | ||
7891 | |||
7892 | /* Initialize backup data pointer. */ | ||
7893 | pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex]; | ||
7894 | |||
7895 | /* Check action type */ | ||
7896 | if (Action == SK_PNMI_GET) { | ||
7897 | /* Check length */ | ||
7898 | switch (Id) { | ||
7899 | |||
7900 | case OID_SKGE_VCT_GET: | ||
7901 | if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) { | ||
7902 | *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT); | ||
7903 | return (SK_PNMI_ERR_TOO_SHORT); | ||
7904 | } | ||
7905 | break; | ||
7906 | |||
7907 | case OID_SKGE_VCT_STATUS: | ||
7908 | if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) { | ||
7909 | *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8); | ||
7910 | return (SK_PNMI_ERR_TOO_SHORT); | ||
7911 | } | ||
7912 | break; | ||
7913 | |||
7914 | default: | ||
7915 | *pLen = 0; | ||
7916 | return (SK_PNMI_ERR_GENERAL); | ||
7917 | } | ||
7918 | |||
7919 | /* Get value */ | ||
7920 | Offset = 0; | ||
7921 | for (; PhysPortIndex < Limit; PhysPortIndex++) { | ||
7922 | switch (Id) { | ||
7923 | |||
7924 | case OID_SKGE_VCT_GET: | ||
7925 | if ((Link == SK_FALSE) && | ||
7926 | (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) { | ||
7927 | RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE); | ||
7928 | if (RetCode == 0) { | ||
7929 | pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING; | ||
7930 | pAC->Pnmi.VctStatus[PhysPortIndex] |= | ||
7931 | (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE); | ||
7932 | |||
7933 | /* Copy results for later use to PNMI struct. */ | ||
7934 | for (i = 0; i < 4; i++) { | ||
7935 | if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) { | ||
7936 | if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) { | ||
7937 | pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH; | ||
7938 | } | ||
7939 | } | ||
7940 | if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) { | ||
7941 | CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28); | ||
7942 | } | ||
7943 | else { | ||
7944 | CableLength = 0; | ||
7945 | } | ||
7946 | pVctBackupData->PMdiPairLen[i] = CableLength; | ||
7947 | pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i]; | ||
7948 | } | ||
7949 | |||
7950 | Para.Para32[0] = PhysPortIndex; | ||
7951 | Para.Para32[1] = -1; | ||
7952 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para); | ||
7953 | SkEventDispatcher(pAC, IoC); | ||
7954 | } | ||
7955 | else { | ||
7956 | ; /* VCT test is running. */ | ||
7957 | } | ||
7958 | } | ||
7959 | |||
7960 | /* Get all results. */ | ||
7961 | CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex); | ||
7962 | Offset += sizeof(SK_U8); | ||
7963 | *(pBuf + Offset) = pPrt->PCableLen; | ||
7964 | Offset += sizeof(SK_U8); | ||
7965 | for (i = 0; i < 4; i++) { | ||
7966 | SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]); | ||
7967 | Offset += sizeof(SK_U32); | ||
7968 | } | ||
7969 | for (i = 0; i < 4; i++) { | ||
7970 | *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i]; | ||
7971 | Offset += sizeof(SK_U8); | ||
7972 | } | ||
7973 | |||
7974 | RetCode = SK_PNMI_ERR_OK; | ||
7975 | break; | ||
7976 | |||
7977 | case OID_SKGE_VCT_STATUS: | ||
7978 | CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex); | ||
7979 | Offset += sizeof(SK_U8); | ||
7980 | RetCode = SK_PNMI_ERR_OK; | ||
7981 | break; | ||
7982 | |||
7983 | default: | ||
7984 | *pLen = 0; | ||
7985 | return (SK_PNMI_ERR_GENERAL); | ||
7986 | } | ||
7987 | } /* for */ | ||
7988 | *pLen = Offset; | ||
7989 | return (RetCode); | ||
7990 | |||
7991 | } /* if SK_PNMI_GET */ | ||
7992 | |||
7993 | /* | ||
7994 | * From here SET or PRESET action. Check if the passed | ||
7995 | * buffer length is plausible. | ||
7996 | */ | ||
7997 | |||
7998 | /* Check length */ | ||
7999 | switch (Id) { | ||
8000 | case OID_SKGE_VCT_SET: | ||
8001 | if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) { | ||
8002 | *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32); | ||
8003 | return (SK_PNMI_ERR_TOO_SHORT); | ||
8004 | } | ||
8005 | break; | ||
8006 | |||
8007 | default: | ||
8008 | *pLen = 0; | ||
8009 | return (SK_PNMI_ERR_GENERAL); | ||
8010 | } | ||
8011 | |||
8012 | /* | ||
8013 | * Perform preset or set. | ||
8014 | */ | ||
8015 | |||
8016 | /* VCT does not support PRESET action. */ | ||
8017 | if (Action == SK_PNMI_PRESET) { | ||
8018 | return (SK_PNMI_ERR_OK); | ||
8019 | } | ||
8020 | |||
8021 | Offset = 0; | ||
8022 | for (; PhysPortIndex < Limit; PhysPortIndex++) { | ||
8023 | switch (Id) { | ||
8024 | case OID_SKGE_VCT_SET: /* Start VCT test. */ | ||
8025 | if (Link == SK_FALSE) { | ||
8026 | SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST); | ||
8027 | |||
8028 | RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE); | ||
8029 | if (RetCode == 0) { /* RetCode: 0 => Start! */ | ||
8030 | pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING; | ||
8031 | pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA; | ||
8032 | pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK; | ||
8033 | |||
8034 | /* | ||
8035 | * Start VCT timer counter. | ||
8036 | */ | ||
8037 | SK_MEMSET((char *) &Para, 0, sizeof(Para)); | ||
8038 | Para.Para32[0] = PhysPortIndex; | ||
8039 | Para.Para32[1] = -1; | ||
8040 | SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer, | ||
8041 | 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para); | ||
8042 | SK_PNMI_STORE_U32((pBuf + Offset), RetCode); | ||
8043 | RetCode = SK_PNMI_ERR_OK; | ||
8044 | } | ||
8045 | else { /* RetCode: 2 => Running! */ | ||
8046 | SK_PNMI_STORE_U32((pBuf + Offset), RetCode); | ||
8047 | RetCode = SK_PNMI_ERR_OK; | ||
8048 | } | ||
8049 | } | ||
8050 | else { /* RetCode: 4 => Link! */ | ||
8051 | RetCode = 4; | ||
8052 | SK_PNMI_STORE_U32((pBuf + Offset), RetCode); | ||
8053 | RetCode = SK_PNMI_ERR_OK; | ||
8054 | } | ||
8055 | Offset += sizeof(SK_U32); | ||
8056 | break; | ||
8057 | |||
8058 | default: | ||
8059 | *pLen = 0; | ||
8060 | return (SK_PNMI_ERR_GENERAL); | ||
8061 | } | ||
8062 | } /* for */ | ||
8063 | *pLen = Offset; | ||
8064 | return (RetCode); | ||
8065 | |||
8066 | } /* Vct */ | ||
8067 | |||
8068 | |||
8069 | PNMI_STATIC void CheckVctStatus( | ||
8070 | SK_AC *pAC, | ||
8071 | SK_IOC IoC, | ||
8072 | char *pBuf, | ||
8073 | SK_U32 Offset, | ||
8074 | SK_U32 PhysPortIndex) | ||
8075 | { | ||
8076 | SK_GEPORT *pPrt; | ||
8077 | SK_PNMI_VCT *pVctData; | ||
8078 | SK_U32 RetCode; | ||
8079 | |||
8080 | pPrt = &pAC->GIni.GP[PhysPortIndex]; | ||
8081 | |||
8082 | pVctData = (SK_PNMI_VCT *) (pBuf + Offset); | ||
8083 | pVctData->VctStatus = SK_PNMI_VCT_NONE; | ||
8084 | |||
8085 | if (!pPrt->PHWLinkUp) { | ||
8086 | |||
8087 | /* Was a VCT test ever made before? */ | ||
8088 | if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) { | ||
8089 | if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) { | ||
8090 | pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA; | ||
8091 | } | ||
8092 | else { | ||
8093 | pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA; | ||
8094 | } | ||
8095 | } | ||
8096 | |||
8097 | /* Check VCT test status. */ | ||
8098 | RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE); | ||
8099 | if (RetCode == 2) { /* VCT test is running. */ | ||
8100 | pVctData->VctStatus |= SK_PNMI_VCT_RUNNING; | ||
8101 | } | ||
8102 | else { /* VCT data was copied to pAC here. Check PENDING state. */ | ||
8103 | if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) { | ||
8104 | pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA; | ||
8105 | } | ||
8106 | } | ||
8107 | |||
8108 | if (pPrt->PCableLen != 0xff) { /* Old DSP value. */ | ||
8109 | pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA; | ||
8110 | } | ||
8111 | } | ||
8112 | else { | ||
8113 | |||
8114 | /* Was a VCT test ever made before? */ | ||
8115 | if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) { | ||
8116 | pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA; | ||
8117 | pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA; | ||
8118 | } | ||
8119 | |||
8120 | /* DSP only valid in 100/1000 modes. */ | ||
8121 | if (pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed != | ||
8122 | SK_LSPEED_STAT_10MBPS) { | ||
8123 | pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA; | ||
8124 | } | ||
8125 | } | ||
8126 | } /* CheckVctStatus */ | ||
8127 | |||
8128 | |||
8129 | /***************************************************************************** | ||
8130 | * | ||
8131 | * SkPnmiGenIoctl - Handles new generic PNMI IOCTL, calls the needed | ||
8132 | * PNMI function depending on the subcommand and | ||
8133 | * returns all data belonging to the complete database | ||
8134 | * or OID request. | ||
8135 | * | ||
8136 | * Description: | ||
8137 | * Looks up the requested subcommand, calls the corresponding handler | ||
8138 | * function and passes all required parameters to it. | ||
8139 | * The function is called by the driver. It is needed to handle the new | ||
8140 | * generic PNMI IOCTL. This IOCTL is given to the driver and contains both | ||
8141 | * the OID and a subcommand to decide what kind of request has to be done. | ||
8142 | * | ||
8143 | * Returns: | ||
8144 | * SK_PNMI_ERR_OK The request was successfully performed | ||
8145 | * SK_PNMI_ERR_GENERAL A general severe internal error occured | ||
8146 | * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take | ||
8147 | * the data. | ||
8148 | * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown | ||
8149 | * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't | ||
8150 | * exist (e.g. port instance 3 on a two port | ||
8151 | * adapter. | ||
8152 | */ | ||
8153 | int SkPnmiGenIoctl( | ||
8154 | SK_AC *pAC, /* Pointer to adapter context struct */ | ||
8155 | SK_IOC IoC, /* I/O context */ | ||
8156 | void *pBuf, /* Buffer used for the management data transfer */ | ||
8157 | unsigned int *pLen, /* Length of buffer */ | ||
8158 | SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ | ||
8159 | { | ||
8160 | SK_I32 Mode; /* Store value of subcommand. */ | ||
8161 | SK_U32 Oid; /* Store value of OID. */ | ||
8162 | int ReturnCode; /* Store return value to show status of PNMI action. */ | ||
8163 | int HeaderLength; /* Length of desired action plus OID. */ | ||
8164 | |||
8165 | ReturnCode = SK_PNMI_ERR_GENERAL; | ||
8166 | |||
8167 | SK_MEMCPY(&Mode, pBuf, sizeof(SK_I32)); | ||
8168 | SK_MEMCPY(&Oid, (char *) pBuf + sizeof(SK_I32), sizeof(SK_U32)); | ||
8169 | HeaderLength = sizeof(SK_I32) + sizeof(SK_U32); | ||
8170 | *pLen = *pLen - HeaderLength; | ||
8171 | SK_MEMCPY((char *) pBuf + sizeof(SK_I32), (char *) pBuf + HeaderLength, *pLen); | ||
8172 | |||
8173 | switch(Mode) { | ||
8174 | case SK_GET_SINGLE_VAR: | ||
8175 | ReturnCode = SkPnmiGetVar(pAC, IoC, Oid, | ||
8176 | (char *) pBuf + sizeof(SK_I32), pLen, | ||
8177 | ((SK_U32) (-1)), NetIndex); | ||
8178 | SK_PNMI_STORE_U32(pBuf, ReturnCode); | ||
8179 | *pLen = *pLen + sizeof(SK_I32); | ||
8180 | break; | ||
8181 | case SK_PRESET_SINGLE_VAR: | ||
8182 | ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid, | ||
8183 | (char *) pBuf + sizeof(SK_I32), pLen, | ||
8184 | ((SK_U32) (-1)), NetIndex); | ||
8185 | SK_PNMI_STORE_U32(pBuf, ReturnCode); | ||
8186 | *pLen = *pLen + sizeof(SK_I32); | ||
8187 | break; | ||
8188 | case SK_SET_SINGLE_VAR: | ||
8189 | ReturnCode = SkPnmiSetVar(pAC, IoC, Oid, | ||
8190 | (char *) pBuf + sizeof(SK_I32), pLen, | ||
8191 | ((SK_U32) (-1)), NetIndex); | ||
8192 | SK_PNMI_STORE_U32(pBuf, ReturnCode); | ||
8193 | *pLen = *pLen + sizeof(SK_I32); | ||
8194 | break; | ||
8195 | case SK_GET_FULL_MIB: | ||
8196 | ReturnCode = SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex); | ||
8197 | break; | ||
8198 | case SK_PRESET_FULL_MIB: | ||
8199 | ReturnCode = SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex); | ||
8200 | break; | ||
8201 | case SK_SET_FULL_MIB: | ||
8202 | ReturnCode = SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex); | ||
8203 | break; | ||
8204 | default: | ||
8205 | break; | ||
8206 | } | ||
8207 | |||
8208 | return (ReturnCode); | ||
8209 | |||
8210 | } /* SkGeIocGen */ | ||
diff --git a/drivers/net/sk98lin/skgesirq.c b/drivers/net/sk98lin/skgesirq.c new file mode 100644 index 000000000000..3e7aa49afd00 --- /dev/null +++ b/drivers/net/sk98lin/skgesirq.c | |||
@@ -0,0 +1,2229 @@ | |||
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 | static 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 | /* Snap statistic counters */ | ||
616 | (void)SkXmUpdateStats(pAC, IoC, 0); | ||
617 | |||
618 | (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_HI, &RegVal32); | ||
619 | |||
620 | pPrt->LastOctets = (SK_U64)RegVal32 << 32; | ||
621 | |||
622 | (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_LO, &RegVal32); | ||
623 | |||
624 | pPrt->LastOctets += RegVal32; | ||
625 | |||
626 | Para.Para32[0] = 0; | ||
627 | SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME, | ||
628 | SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para); | ||
629 | } | ||
630 | } | ||
631 | #endif /* GENESIS */ | ||
632 | } | ||
633 | |||
634 | if ((Istatus & IS_PA_TO_TX2) != 0) { | ||
635 | |||
636 | pPrt = &pAC->GIni.GP[1]; | ||
637 | |||
638 | /* May be a normal situation in a server with a slow network */ | ||
639 | SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX2); | ||
640 | |||
641 | #ifdef GENESIS | ||
642 | if (pAC->GIni.GIGenesis) { | ||
643 | /* workaround: see above */ | ||
644 | if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || | ||
645 | pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) && | ||
646 | !pPrt->HalfDupTimerActive) { | ||
647 | pPrt->HalfDupTimerActive = SK_TRUE; | ||
648 | /* Snap statistic counters */ | ||
649 | (void)SkXmUpdateStats(pAC, IoC, 1); | ||
650 | |||
651 | (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_HI, &RegVal32); | ||
652 | |||
653 | pPrt->LastOctets = (SK_U64)RegVal32 << 32; | ||
654 | |||
655 | (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_LO, &RegVal32); | ||
656 | |||
657 | pPrt->LastOctets += RegVal32; | ||
658 | |||
659 | Para.Para32[0] = 1; | ||
660 | SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME, | ||
661 | SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para); | ||
662 | } | ||
663 | } | ||
664 | #endif /* GENESIS */ | ||
665 | } | ||
666 | |||
667 | /* Check interrupts of the particular queues */ | ||
668 | if ((Istatus & IS_R1_C) != 0) { | ||
669 | /* Clear IRQ */ | ||
670 | SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_C); | ||
671 | SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E006, | ||
672 | SKERR_SIRQ_E006MSG); | ||
673 | Para.Para64 = MAC_1; | ||
674 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); | ||
675 | Para.Para32[0] = MAC_1; | ||
676 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); | ||
677 | } | ||
678 | |||
679 | if ((Istatus & IS_R2_C) != 0) { | ||
680 | /* Clear IRQ */ | ||
681 | SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_C); | ||
682 | SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E007, | ||
683 | SKERR_SIRQ_E007MSG); | ||
684 | Para.Para64 = MAC_2; | ||
685 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); | ||
686 | Para.Para32[0] = MAC_2; | ||
687 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); | ||
688 | } | ||
689 | |||
690 | if ((Istatus & IS_XS1_C) != 0) { | ||
691 | /* Clear IRQ */ | ||
692 | SK_OUT32(IoC, B0_XS1_CSR, CSR_IRQ_CL_C); | ||
693 | SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E008, | ||
694 | SKERR_SIRQ_E008MSG); | ||
695 | Para.Para64 = MAC_1; | ||
696 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); | ||
697 | Para.Para32[0] = MAC_1; | ||
698 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); | ||
699 | } | ||
700 | |||
701 | if ((Istatus & IS_XA1_C) != 0) { | ||
702 | /* Clear IRQ */ | ||
703 | SK_OUT32(IoC, B0_XA1_CSR, CSR_IRQ_CL_C); | ||
704 | SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E009, | ||
705 | SKERR_SIRQ_E009MSG); | ||
706 | Para.Para64 = MAC_1; | ||
707 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); | ||
708 | Para.Para32[0] = MAC_1; | ||
709 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); | ||
710 | } | ||
711 | |||
712 | if ((Istatus & IS_XS2_C) != 0) { | ||
713 | /* Clear IRQ */ | ||
714 | SK_OUT32(IoC, B0_XS2_CSR, CSR_IRQ_CL_C); | ||
715 | SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E010, | ||
716 | SKERR_SIRQ_E010MSG); | ||
717 | Para.Para64 = MAC_2; | ||
718 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); | ||
719 | Para.Para32[0] = MAC_2; | ||
720 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); | ||
721 | } | ||
722 | |||
723 | if ((Istatus & IS_XA2_C) != 0) { | ||
724 | /* Clear IRQ */ | ||
725 | SK_OUT32(IoC, B0_XA2_CSR, CSR_IRQ_CL_C); | ||
726 | SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E011, | ||
727 | SKERR_SIRQ_E011MSG); | ||
728 | Para.Para64 = MAC_2; | ||
729 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); | ||
730 | Para.Para32[0] = MAC_2; | ||
731 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); | ||
732 | } | ||
733 | |||
734 | /* External reg interrupt */ | ||
735 | if ((Istatus & IS_EXT_REG) != 0) { | ||
736 | /* Test IRQs from PHY */ | ||
737 | for (i = 0; i < pAC->GIni.GIMacsFound; i++) { | ||
738 | |||
739 | pPrt = &pAC->GIni.GP[i]; | ||
740 | |||
741 | if (pPrt->PState == SK_PRT_RESET) { | ||
742 | continue; | ||
743 | } | ||
744 | |||
745 | #ifdef GENESIS | ||
746 | if (pAC->GIni.GIGenesis) { | ||
747 | |||
748 | switch (pPrt->PhyType) { | ||
749 | |||
750 | case SK_PHY_XMAC: | ||
751 | break; | ||
752 | |||
753 | case SK_PHY_BCOM: | ||
754 | SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_STAT, &PhyInt); | ||
755 | |||
756 | if ((PhyInt & ~PHY_B_DEF_MSK) != 0) { | ||
757 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, | ||
758 | ("Port %d Bcom Int: 0x%04X\n", | ||
759 | i, PhyInt)); | ||
760 | SkPhyIsrBcom(pAC, IoC, i, PhyInt); | ||
761 | } | ||
762 | break; | ||
763 | #ifdef OTHER_PHY | ||
764 | case SK_PHY_LONE: | ||
765 | SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_STAT, &PhyInt); | ||
766 | |||
767 | if ((PhyInt & PHY_L_DEF_MSK) != 0) { | ||
768 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, | ||
769 | ("Port %d Lone Int: %x\n", | ||
770 | i, PhyInt)); | ||
771 | SkPhyIsrLone(pAC, IoC, i, PhyInt); | ||
772 | } | ||
773 | break; | ||
774 | #endif /* OTHER_PHY */ | ||
775 | } | ||
776 | } | ||
777 | #endif /* GENESIS */ | ||
778 | |||
779 | #ifdef YUKON | ||
780 | if (pAC->GIni.GIYukon) { | ||
781 | /* Read PHY Interrupt Status */ | ||
782 | SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_STAT, &PhyInt); | ||
783 | |||
784 | if ((PhyInt & PHY_M_DEF_MSK) != 0) { | ||
785 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, | ||
786 | ("Port %d Marv Int: 0x%04X\n", | ||
787 | i, PhyInt)); | ||
788 | SkPhyIsrGmac(pAC, IoC, i, PhyInt); | ||
789 | } | ||
790 | } | ||
791 | #endif /* YUKON */ | ||
792 | } | ||
793 | } | ||
794 | |||
795 | /* I2C Ready interrupt */ | ||
796 | if ((Istatus & IS_I2C_READY) != 0) { | ||
797 | #ifdef SK_SLIM | ||
798 | SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); | ||
799 | #else | ||
800 | SkI2cIsr(pAC, IoC); | ||
801 | #endif | ||
802 | } | ||
803 | |||
804 | /* SW forced interrupt */ | ||
805 | if ((Istatus & IS_IRQ_SW) != 0) { | ||
806 | /* clear the software IRQ */ | ||
807 | SK_OUT8(IoC, B0_CTST, CS_CL_SW_IRQ); | ||
808 | } | ||
809 | |||
810 | if ((Istatus & IS_LNK_SYNC_M1) != 0) { | ||
811 | /* | ||
812 | * We do NOT need the Link Sync interrupt, because it shows | ||
813 | * us only a link going down. | ||
814 | */ | ||
815 | /* clear interrupt */ | ||
816 | SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LED_CLR_IRQ); | ||
817 | } | ||
818 | |||
819 | /* Check MAC after link sync counter */ | ||
820 | if ((Istatus & IS_MAC1) != 0) { | ||
821 | /* IRQ from MAC 1 */ | ||
822 | SkMacIrq(pAC, IoC, MAC_1); | ||
823 | } | ||
824 | |||
825 | if ((Istatus & IS_LNK_SYNC_M2) != 0) { | ||
826 | /* | ||
827 | * We do NOT need the Link Sync interrupt, because it shows | ||
828 | * us only a link going down. | ||
829 | */ | ||
830 | /* clear interrupt */ | ||
831 | SK_OUT8(IoC, MR_ADDR(MAC_2, LNK_SYNC_CTRL), LED_CLR_IRQ); | ||
832 | } | ||
833 | |||
834 | /* Check MAC after link sync counter */ | ||
835 | if ((Istatus & IS_MAC2) != 0) { | ||
836 | /* IRQ from MAC 2 */ | ||
837 | SkMacIrq(pAC, IoC, MAC_2); | ||
838 | } | ||
839 | |||
840 | /* Timer interrupt (served last) */ | ||
841 | if ((Istatus & IS_TIMINT) != 0) { | ||
842 | /* check for HW Errors */ | ||
843 | if (((Istatus & IS_HW_ERR) & ~pAC->GIni.GIValIrqMask) != 0) { | ||
844 | /* read the HW Error Interrupt source */ | ||
845 | SK_IN32(IoC, B0_HWE_ISRC, &RegVal32); | ||
846 | |||
847 | SkGeHwErr(pAC, IoC, RegVal32); | ||
848 | } | ||
849 | |||
850 | SkHwtIsr(pAC, IoC); | ||
851 | } | ||
852 | |||
853 | } /* SkGeSirqIsr */ | ||
854 | |||
855 | |||
856 | #ifdef GENESIS | ||
857 | /****************************************************************************** | ||
858 | * | ||
859 | * SkGePortCheckShorts() - Implementing XMAC Workaround Errata # 2 | ||
860 | * | ||
861 | * return: | ||
862 | * 0 o.k. nothing needed | ||
863 | * 1 Restart needed on this port | ||
864 | */ | ||
865 | static int SkGePortCheckShorts( | ||
866 | SK_AC *pAC, /* Adapter Context */ | ||
867 | SK_IOC IoC, /* IO Context */ | ||
868 | int Port) /* Which port should be checked */ | ||
869 | { | ||
870 | SK_U32 Shorts; /* Short Event Counter */ | ||
871 | SK_U32 CheckShorts; /* Check value for Short Event Counter */ | ||
872 | SK_U64 RxCts; /* Rx Counter (packets on network) */ | ||
873 | SK_U32 RxTmp; /* Rx temp. Counter */ | ||
874 | SK_U32 FcsErrCts; /* FCS Error Counter */ | ||
875 | SK_GEPORT *pPrt; /* GIni Port struct pointer */ | ||
876 | int Rtv; /* Return value */ | ||
877 | int i; | ||
878 | |||
879 | pPrt = &pAC->GIni.GP[Port]; | ||
880 | |||
881 | /* Default: no action */ | ||
882 | Rtv = SK_HW_PS_NONE; | ||
883 | |||
884 | (void)SkXmUpdateStats(pAC, IoC, Port); | ||
885 | |||
886 | /* Extra precaution: check for short Event counter */ | ||
887 | (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts); | ||
888 | |||
889 | /* | ||
890 | * Read Rx counters (packets seen on the network and not necessarily | ||
891 | * really received. | ||
892 | */ | ||
893 | RxCts = 0; | ||
894 | |||
895 | for (i = 0; i < sizeof(SkGeRxRegs)/sizeof(SkGeRxRegs[0]); i++) { | ||
896 | |||
897 | (void)SkXmMacStatistic(pAC, IoC, Port, SkGeRxRegs[i], &RxTmp); | ||
898 | |||
899 | RxCts += (SK_U64)RxTmp; | ||
900 | } | ||
901 | |||
902 | /* On default: check shorts against zero */ | ||
903 | CheckShorts = 0; | ||
904 | |||
905 | /* Extra precaution on active links */ | ||
906 | if (pPrt->PHWLinkUp) { | ||
907 | /* Reset Link Restart counter */ | ||
908 | pPrt->PLinkResCt = 0; | ||
909 | pPrt->PAutoNegTOCt = 0; | ||
910 | |||
911 | /* If link is up check for 2 */ | ||
912 | CheckShorts = 2; | ||
913 | |||
914 | (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXF_FCS_ERR, &FcsErrCts); | ||
915 | |||
916 | if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE && | ||
917 | pPrt->PLipaAutoNeg == SK_LIPA_UNKNOWN && | ||
918 | (pPrt->PLinkMode == SK_LMODE_HALF || | ||
919 | pPrt->PLinkMode == SK_LMODE_FULL)) { | ||
920 | /* | ||
921 | * This is autosensing and we are in the fallback | ||
922 | * manual full/half duplex mode. | ||
923 | */ | ||
924 | if (RxCts == pPrt->PPrevRx) { | ||
925 | /* Nothing received, restart link */ | ||
926 | pPrt->PPrevFcs = FcsErrCts; | ||
927 | pPrt->PPrevShorts = Shorts; | ||
928 | |||
929 | return(SK_HW_PS_RESTART); | ||
930 | } | ||
931 | else { | ||
932 | pPrt->PLipaAutoNeg = SK_LIPA_MANUAL; | ||
933 | } | ||
934 | } | ||
935 | |||
936 | if (((RxCts - pPrt->PPrevRx) > pPrt->PRxLim) || | ||
937 | (!(FcsErrCts - pPrt->PPrevFcs))) { | ||
938 | /* | ||
939 | * Note: The compare with zero above has to be done the way shown, | ||
940 | * otherwise the Linux driver will have a problem. | ||
941 | */ | ||
942 | /* | ||
943 | * We received a bunch of frames or no CRC error occured on the | ||
944 | * network -> ok. | ||
945 | */ | ||
946 | pPrt->PPrevRx = RxCts; | ||
947 | pPrt->PPrevFcs = FcsErrCts; | ||
948 | pPrt->PPrevShorts = Shorts; | ||
949 | |||
950 | return(SK_HW_PS_NONE); | ||
951 | } | ||
952 | |||
953 | pPrt->PPrevFcs = FcsErrCts; | ||
954 | } | ||
955 | |||
956 | |||
957 | if ((Shorts - pPrt->PPrevShorts) > CheckShorts) { | ||
958 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, | ||
959 | ("Short Event Count Restart Port %d \n", Port)); | ||
960 | Rtv = SK_HW_PS_RESTART; | ||
961 | } | ||
962 | |||
963 | pPrt->PPrevShorts = Shorts; | ||
964 | pPrt->PPrevRx = RxCts; | ||
965 | |||
966 | return(Rtv); | ||
967 | } /* SkGePortCheckShorts */ | ||
968 | #endif /* GENESIS */ | ||
969 | |||
970 | |||
971 | /****************************************************************************** | ||
972 | * | ||
973 | * SkGePortCheckUp() - Check if the link is up | ||
974 | * | ||
975 | * return: | ||
976 | * 0 o.k. nothing needed | ||
977 | * 1 Restart needed on this port | ||
978 | * 2 Link came up | ||
979 | */ | ||
980 | static int SkGePortCheckUp( | ||
981 | SK_AC *pAC, /* Adapter Context */ | ||
982 | SK_IOC IoC, /* IO Context */ | ||
983 | int Port) /* Which port should be checked */ | ||
984 | { | ||
985 | SK_GEPORT *pPrt; /* GIni Port struct pointer */ | ||
986 | SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */ | ||
987 | int Rtv; /* Return value */ | ||
988 | |||
989 | Rtv = SK_HW_PS_NONE; | ||
990 | |||
991 | pPrt = &pAC->GIni.GP[Port]; | ||
992 | |||
993 | if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { | ||
994 | AutoNeg = SK_FALSE; | ||
995 | } | ||
996 | else { | ||
997 | AutoNeg = SK_TRUE; | ||
998 | } | ||
999 | |||
1000 | #ifdef GENESIS | ||
1001 | if (pAC->GIni.GIGenesis) { | ||
1002 | |||
1003 | switch (pPrt->PhyType) { | ||
1004 | |||
1005 | case SK_PHY_XMAC: | ||
1006 | Rtv = SkGePortCheckUpXmac(pAC, IoC, Port, AutoNeg); | ||
1007 | break; | ||
1008 | case SK_PHY_BCOM: | ||
1009 | Rtv = SkGePortCheckUpBcom(pAC, IoC, Port, AutoNeg); | ||
1010 | break; | ||
1011 | #ifdef OTHER_PHY | ||
1012 | case SK_PHY_LONE: | ||
1013 | Rtv = SkGePortCheckUpLone(pAC, IoC, Port, AutoNeg); | ||
1014 | break; | ||
1015 | case SK_PHY_NAT: | ||
1016 | Rtv = SkGePortCheckUpNat(pAC, IoC, Port, AutoNeg); | ||
1017 | break; | ||
1018 | #endif /* OTHER_PHY */ | ||
1019 | } | ||
1020 | } | ||
1021 | #endif /* GENESIS */ | ||
1022 | |||
1023 | #ifdef YUKON | ||
1024 | if (pAC->GIni.GIYukon) { | ||
1025 | |||
1026 | Rtv = SkGePortCheckUpGmac(pAC, IoC, Port, AutoNeg); | ||
1027 | } | ||
1028 | #endif /* YUKON */ | ||
1029 | |||
1030 | return(Rtv); | ||
1031 | } /* SkGePortCheckUp */ | ||
1032 | |||
1033 | |||
1034 | #ifdef GENESIS | ||
1035 | /****************************************************************************** | ||
1036 | * | ||
1037 | * SkGePortCheckUpXmac() - Implementing of the Workaround Errata # 2 | ||
1038 | * | ||
1039 | * return: | ||
1040 | * 0 o.k. nothing needed | ||
1041 | * 1 Restart needed on this port | ||
1042 | * 2 Link came up | ||
1043 | */ | ||
1044 | static int SkGePortCheckUpXmac( | ||
1045 | SK_AC *pAC, /* Adapter Context */ | ||
1046 | SK_IOC IoC, /* IO Context */ | ||
1047 | int Port, /* Which port should be checked */ | ||
1048 | SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ | ||
1049 | { | ||
1050 | SK_U32 Shorts; /* Short Event Counter */ | ||
1051 | SK_GEPORT *pPrt; /* GIni Port struct pointer */ | ||
1052 | int Done; | ||
1053 | SK_U32 GpReg; /* General Purpose register value */ | ||
1054 | SK_U16 Isrc; /* Interrupt source register */ | ||
1055 | SK_U16 IsrcSum; /* Interrupt source register sum */ | ||
1056 | SK_U16 LpAb; /* Link Partner Ability */ | ||
1057 | SK_U16 ResAb; /* Resolved Ability */ | ||
1058 | SK_U16 ExtStat; /* Extended Status Register */ | ||
1059 | SK_U8 NextMode; /* Next AutoSensing Mode */ | ||
1060 | |||
1061 | pPrt = &pAC->GIni.GP[Port]; | ||
1062 | |||
1063 | if (pPrt->PHWLinkUp) { | ||
1064 | if (pPrt->PhyType != SK_PHY_XMAC) { | ||
1065 | return(SK_HW_PS_NONE); | ||
1066 | } | ||
1067 | else { | ||
1068 | return(SkGePortCheckShorts(pAC, IoC, Port)); | ||
1069 | } | ||
1070 | } | ||
1071 | |||
1072 | IsrcSum = pPrt->PIsave; | ||
1073 | pPrt->PIsave = 0; | ||
1074 | |||
1075 | /* Now wait for each port's link */ | ||
1076 | if (pPrt->PLinkBroken) { | ||
1077 | /* Link was broken */ | ||
1078 | XM_IN32(IoC, Port, XM_GP_PORT, &GpReg); | ||
1079 | |||
1080 | if ((GpReg & XM_GP_INP_ASS) == 0) { | ||
1081 | /* The Link is in sync */ | ||
1082 | XM_IN16(IoC, Port, XM_ISRC, &Isrc); | ||
1083 | IsrcSum |= Isrc; | ||
1084 | SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum); | ||
1085 | |||
1086 | if ((Isrc & XM_IS_INP_ASS) == 0) { | ||
1087 | /* It has been in sync since last time */ | ||
1088 | /* Restart the PORT */ | ||
1089 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, | ||
1090 | ("Link in sync Restart Port %d\n", Port)); | ||
1091 | |||
1092 | (void)SkXmUpdateStats(pAC, IoC, Port); | ||
1093 | |||
1094 | /* We now need to reinitialize the PrevShorts counter */ | ||
1095 | (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts); | ||
1096 | pPrt->PPrevShorts = Shorts; | ||
1097 | |||
1098 | pPrt->PLinkBroken = SK_FALSE; | ||
1099 | |||
1100 | /* | ||
1101 | * Link Restart Workaround: | ||
1102 | * it may be possible that the other Link side | ||
1103 | * restarts its link as well an we detect | ||
1104 | * another LinkBroken. To prevent this | ||
1105 | * happening we check for a maximum number | ||
1106 | * of consecutive restart. If those happens, | ||
1107 | * we do NOT restart the active link and | ||
1108 | * check whether the link is now o.k. | ||
1109 | */ | ||
1110 | pPrt->PLinkResCt++; | ||
1111 | |||
1112 | pPrt->PAutoNegTimeOut = 0; | ||
1113 | |||
1114 | if (pPrt->PLinkResCt < SK_MAX_LRESTART) { | ||
1115 | return(SK_HW_PS_RESTART); | ||
1116 | } | ||
1117 | |||
1118 | pPrt->PLinkResCt = 0; | ||
1119 | |||
1120 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1121 | ("Do NOT restart on Port %d %x %x\n", Port, Isrc, IsrcSum)); | ||
1122 | } | ||
1123 | else { | ||
1124 | pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND); | ||
1125 | |||
1126 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1127 | ("Save Sync/nosync Port %d %x %x\n", Port, Isrc, IsrcSum)); | ||
1128 | |||
1129 | /* Do nothing more if link is broken */ | ||
1130 | return(SK_HW_PS_NONE); | ||
1131 | } | ||
1132 | } | ||
1133 | else { | ||
1134 | /* Do nothing more if link is broken */ | ||
1135 | return(SK_HW_PS_NONE); | ||
1136 | } | ||
1137 | |||
1138 | } | ||
1139 | else { | ||
1140 | /* Link was not broken, check if it is */ | ||
1141 | XM_IN16(IoC, Port, XM_ISRC, &Isrc); | ||
1142 | IsrcSum |= Isrc; | ||
1143 | if ((Isrc & XM_IS_INP_ASS) != 0) { | ||
1144 | XM_IN16(IoC, Port, XM_ISRC, &Isrc); | ||
1145 | IsrcSum |= Isrc; | ||
1146 | if ((Isrc & XM_IS_INP_ASS) != 0) { | ||
1147 | XM_IN16(IoC, Port, XM_ISRC, &Isrc); | ||
1148 | IsrcSum |= Isrc; | ||
1149 | if ((Isrc & XM_IS_INP_ASS) != 0) { | ||
1150 | pPrt->PLinkBroken = SK_TRUE; | ||
1151 | /* Re-Init Link partner Autoneg flag */ | ||
1152 | pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN; | ||
1153 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, | ||
1154 | ("Link broken Port %d\n", Port)); | ||
1155 | |||
1156 | /* Cable removed-> reinit sense mode */ | ||
1157 | SkHWInitDefSense(pAC, IoC, Port); | ||
1158 | |||
1159 | return(SK_HW_PS_RESTART); | ||
1160 | } | ||
1161 | } | ||
1162 | } | ||
1163 | else { | ||
1164 | SkXmAutoNegLipaXmac(pAC, IoC, Port, Isrc); | ||
1165 | |||
1166 | if (SkGePortCheckShorts(pAC, IoC, Port) == SK_HW_PS_RESTART) { | ||
1167 | return(SK_HW_PS_RESTART); | ||
1168 | } | ||
1169 | } | ||
1170 | } | ||
1171 | |||
1172 | /* | ||
1173 | * here we usually can check whether the link is in sync and | ||
1174 | * auto-negotiation is done. | ||
1175 | */ | ||
1176 | XM_IN32(IoC, Port, XM_GP_PORT, &GpReg); | ||
1177 | XM_IN16(IoC, Port, XM_ISRC, &Isrc); | ||
1178 | IsrcSum |= Isrc; | ||
1179 | |||
1180 | SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum); | ||
1181 | |||
1182 | if ((GpReg & XM_GP_INP_ASS) != 0 || (IsrcSum & XM_IS_INP_ASS) != 0) { | ||
1183 | if ((GpReg & XM_GP_INP_ASS) == 0) { | ||
1184 | /* Save Auto-negotiation Done interrupt only if link is in sync */ | ||
1185 | pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND); | ||
1186 | } | ||
1187 | #ifdef DEBUG | ||
1188 | if ((pPrt->PIsave & XM_IS_AND) != 0) { | ||
1189 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1190 | ("AutoNeg done rescheduled Port %d\n", Port)); | ||
1191 | } | ||
1192 | #endif /* DEBUG */ | ||
1193 | return(SK_HW_PS_NONE); | ||
1194 | } | ||
1195 | |||
1196 | if (AutoNeg) { | ||
1197 | if ((IsrcSum & XM_IS_AND) != 0) { | ||
1198 | SkHWLinkUp(pAC, IoC, Port); | ||
1199 | Done = SkMacAutoNegDone(pAC, IoC, Port); | ||
1200 | if (Done != SK_AND_OK) { | ||
1201 | /* Get PHY parameters, for debugging only */ | ||
1202 | SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LpAb); | ||
1203 | SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb); | ||
1204 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1205 | ("AutoNeg FAIL Port %d (LpAb %x, ResAb %x)\n", | ||
1206 | Port, LpAb, ResAb)); | ||
1207 | |||
1208 | /* Try next possible mode */ | ||
1209 | NextMode = SkHWSenseGetNext(pAC, IoC, Port); | ||
1210 | SkHWLinkDown(pAC, IoC, Port); | ||
1211 | if (Done == SK_AND_DUP_CAP) { | ||
1212 | /* GoTo next mode */ | ||
1213 | SkHWSenseSetNext(pAC, IoC, Port, NextMode); | ||
1214 | } | ||
1215 | |||
1216 | return(SK_HW_PS_RESTART); | ||
1217 | } | ||
1218 | /* | ||
1219 | * Dummy Read extended status to prevent extra link down/ups | ||
1220 | * (clear Page Received bit if set) | ||
1221 | */ | ||
1222 | SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_EXP, &ExtStat); | ||
1223 | |||
1224 | return(SK_HW_PS_LINK); | ||
1225 | } | ||
1226 | |||
1227 | /* AutoNeg not done, but HW link is up. Check for timeouts */ | ||
1228 | pPrt->PAutoNegTimeOut++; | ||
1229 | if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) { | ||
1230 | /* Increase the Timeout counter */ | ||
1231 | pPrt->PAutoNegTOCt++; | ||
1232 | |||
1233 | /* Timeout occured */ | ||
1234 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, | ||
1235 | ("AutoNeg timeout Port %d\n", Port)); | ||
1236 | if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE && | ||
1237 | pPrt->PLipaAutoNeg != SK_LIPA_AUTO) { | ||
1238 | /* Set Link manually up */ | ||
1239 | SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL); | ||
1240 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, | ||
1241 | ("Set manual full duplex Port %d\n", Port)); | ||
1242 | } | ||
1243 | |||
1244 | if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE && | ||
1245 | pPrt->PLipaAutoNeg == SK_LIPA_AUTO && | ||
1246 | pPrt->PAutoNegTOCt >= SK_MAX_ANEG_TO) { | ||
1247 | /* | ||
1248 | * This is rather complicated. | ||
1249 | * we need to check here whether the LIPA_AUTO | ||
1250 | * we saw before is false alert. We saw at one | ||
1251 | * switch ( SR8800) that on boot time it sends | ||
1252 | * just one auto-neg packet and does no further | ||
1253 | * auto-negotiation. | ||
1254 | * Solution: we restart the autosensing after | ||
1255 | * a few timeouts. | ||
1256 | */ | ||
1257 | pPrt->PAutoNegTOCt = 0; | ||
1258 | pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN; | ||
1259 | SkHWInitDefSense(pAC, IoC, Port); | ||
1260 | } | ||
1261 | |||
1262 | /* Do the restart */ | ||
1263 | return(SK_HW_PS_RESTART); | ||
1264 | } | ||
1265 | } | ||
1266 | else { | ||
1267 | /* Link is up and we don't need more */ | ||
1268 | #ifdef DEBUG | ||
1269 | if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) { | ||
1270 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1271 | ("ERROR: Lipa auto detected on port %d\n", Port)); | ||
1272 | } | ||
1273 | #endif /* DEBUG */ | ||
1274 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, | ||
1275 | ("Link sync(GP), Port %d\n", Port)); | ||
1276 | SkHWLinkUp(pAC, IoC, Port); | ||
1277 | |||
1278 | /* | ||
1279 | * Link sync (GP) and so assume a good connection. But if not received | ||
1280 | * a bunch of frames received in a time slot (maybe broken tx cable) | ||
1281 | * the port is restart. | ||
1282 | */ | ||
1283 | return(SK_HW_PS_LINK); | ||
1284 | } | ||
1285 | |||
1286 | return(SK_HW_PS_NONE); | ||
1287 | } /* SkGePortCheckUpXmac */ | ||
1288 | |||
1289 | |||
1290 | /****************************************************************************** | ||
1291 | * | ||
1292 | * SkGePortCheckUpBcom() - Check if the link is up on Bcom PHY | ||
1293 | * | ||
1294 | * return: | ||
1295 | * 0 o.k. nothing needed | ||
1296 | * 1 Restart needed on this port | ||
1297 | * 2 Link came up | ||
1298 | */ | ||
1299 | static int SkGePortCheckUpBcom( | ||
1300 | SK_AC *pAC, /* Adapter Context */ | ||
1301 | SK_IOC IoC, /* IO Context */ | ||
1302 | int Port, /* Which port should be checked */ | ||
1303 | SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ | ||
1304 | { | ||
1305 | SK_GEPORT *pPrt; /* GIni Port struct pointer */ | ||
1306 | int Done; | ||
1307 | SK_U16 Isrc; /* Interrupt source register */ | ||
1308 | SK_U16 PhyStat; /* Phy Status Register */ | ||
1309 | SK_U16 ResAb; /* Master/Slave resolution */ | ||
1310 | SK_U16 Ctrl; /* Broadcom control flags */ | ||
1311 | #ifdef DEBUG | ||
1312 | SK_U16 LpAb; | ||
1313 | SK_U16 ExtStat; | ||
1314 | #endif /* DEBUG */ | ||
1315 | |||
1316 | pPrt = &pAC->GIni.GP[Port]; | ||
1317 | |||
1318 | /* Check for No HCD Link events (#10523) */ | ||
1319 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &Isrc); | ||
1320 | |||
1321 | #ifdef xDEBUG | ||
1322 | if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) == | ||
1323 | (PHY_B_IS_SCR_S_ER | PHY_B_IS_RRS_CHANGE | PHY_B_IS_LRS_CHANGE)) { | ||
1324 | |||
1325 | SK_U32 Stat1, Stat2, Stat3; | ||
1326 | |||
1327 | Stat1 = 0; | ||
1328 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1); | ||
1329 | CMSMPrintString( | ||
1330 | pAC->pConfigTable, | ||
1331 | MSG_TYPE_RUNTIME_INFO, | ||
1332 | "CheckUp1 - Stat: %x, Mask: %x", | ||
1333 | (void *)Isrc, | ||
1334 | (void *)Stat1); | ||
1335 | |||
1336 | Stat1 = 0; | ||
1337 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1); | ||
1338 | Stat2 = 0; | ||
1339 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &Stat2); | ||
1340 | Stat1 = Stat1 << 16 | Stat2; | ||
1341 | Stat2 = 0; | ||
1342 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2); | ||
1343 | Stat3 = 0; | ||
1344 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3); | ||
1345 | Stat2 = Stat2 << 16 | Stat3; | ||
1346 | CMSMPrintString( | ||
1347 | pAC->pConfigTable, | ||
1348 | MSG_TYPE_RUNTIME_INFO, | ||
1349 | "Ctrl/Stat: %x, AN Adv/LP: %x", | ||
1350 | (void *)Stat1, | ||
1351 | (void *)Stat2); | ||
1352 | |||
1353 | Stat1 = 0; | ||
1354 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1); | ||
1355 | Stat2 = 0; | ||
1356 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2); | ||
1357 | Stat1 = Stat1 << 16 | Stat2; | ||
1358 | Stat2 = 0; | ||
1359 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2); | ||
1360 | Stat3 = 0; | ||
1361 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &Stat3); | ||
1362 | Stat2 = Stat2 << 16 | Stat3; | ||
1363 | CMSMPrintString( | ||
1364 | pAC->pConfigTable, | ||
1365 | MSG_TYPE_RUNTIME_INFO, | ||
1366 | "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x", | ||
1367 | (void *)Stat1, | ||
1368 | (void *)Stat2); | ||
1369 | |||
1370 | Stat1 = 0; | ||
1371 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1); | ||
1372 | Stat2 = 0; | ||
1373 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2); | ||
1374 | Stat1 = Stat1 << 16 | Stat2; | ||
1375 | Stat2 = 0; | ||
1376 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2); | ||
1377 | Stat3 = 0; | ||
1378 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3); | ||
1379 | Stat2 = Stat2 << 16 | Stat3; | ||
1380 | CMSMPrintString( | ||
1381 | pAC->pConfigTable, | ||
1382 | MSG_TYPE_RUNTIME_INFO, | ||
1383 | "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x", | ||
1384 | (void *)Stat1, | ||
1385 | (void *)Stat2); | ||
1386 | } | ||
1387 | #endif /* DEBUG */ | ||
1388 | |||
1389 | if ((Isrc & (PHY_B_IS_NO_HDCL /* | PHY_B_IS_NO_HDC */)) != 0) { | ||
1390 | /* | ||
1391 | * Workaround BCom Errata: | ||
1392 | * enable and disable loopback mode if "NO HCD" occurs. | ||
1393 | */ | ||
1394 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Ctrl); | ||
1395 | SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL, | ||
1396 | (SK_U16)(Ctrl | PHY_CT_LOOP)); | ||
1397 | SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL, | ||
1398 | (SK_U16)(Ctrl & ~PHY_CT_LOOP)); | ||
1399 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1400 | ("No HCD Link event, Port %d\n", Port)); | ||
1401 | #ifdef xDEBUG | ||
1402 | CMSMPrintString( | ||
1403 | pAC->pConfigTable, | ||
1404 | MSG_TYPE_RUNTIME_INFO, | ||
1405 | "No HCD link event, port %d.", | ||
1406 | (void *)Port, | ||
1407 | (void *)NULL); | ||
1408 | #endif /* DEBUG */ | ||
1409 | } | ||
1410 | |||
1411 | /* Not obsolete: link status bit is latched to 0 and autoclearing! */ | ||
1412 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat); | ||
1413 | |||
1414 | if (pPrt->PHWLinkUp) { | ||
1415 | return(SK_HW_PS_NONE); | ||
1416 | } | ||
1417 | |||
1418 | #ifdef xDEBUG | ||
1419 | { | ||
1420 | SK_U32 Stat1, Stat2, Stat3; | ||
1421 | |||
1422 | Stat1 = 0; | ||
1423 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1); | ||
1424 | CMSMPrintString( | ||
1425 | pAC->pConfigTable, | ||
1426 | MSG_TYPE_RUNTIME_INFO, | ||
1427 | "CheckUp1a - Stat: %x, Mask: %x", | ||
1428 | (void *)Isrc, | ||
1429 | (void *)Stat1); | ||
1430 | |||
1431 | Stat1 = 0; | ||
1432 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1); | ||
1433 | Stat2 = 0; | ||
1434 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat); | ||
1435 | Stat1 = Stat1 << 16 | PhyStat; | ||
1436 | Stat2 = 0; | ||
1437 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2); | ||
1438 | Stat3 = 0; | ||
1439 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3); | ||
1440 | Stat2 = Stat2 << 16 | Stat3; | ||
1441 | CMSMPrintString( | ||
1442 | pAC->pConfigTable, | ||
1443 | MSG_TYPE_RUNTIME_INFO, | ||
1444 | "Ctrl/Stat: %x, AN Adv/LP: %x", | ||
1445 | (void *)Stat1, | ||
1446 | (void *)Stat2); | ||
1447 | |||
1448 | Stat1 = 0; | ||
1449 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1); | ||
1450 | Stat2 = 0; | ||
1451 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2); | ||
1452 | Stat1 = Stat1 << 16 | Stat2; | ||
1453 | Stat2 = 0; | ||
1454 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2); | ||
1455 | Stat3 = 0; | ||
1456 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb); | ||
1457 | Stat2 = Stat2 << 16 | ResAb; | ||
1458 | CMSMPrintString( | ||
1459 | pAC->pConfigTable, | ||
1460 | MSG_TYPE_RUNTIME_INFO, | ||
1461 | "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x", | ||
1462 | (void *)Stat1, | ||
1463 | (void *)Stat2); | ||
1464 | |||
1465 | Stat1 = 0; | ||
1466 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1); | ||
1467 | Stat2 = 0; | ||
1468 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2); | ||
1469 | Stat1 = Stat1 << 16 | Stat2; | ||
1470 | Stat2 = 0; | ||
1471 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2); | ||
1472 | Stat3 = 0; | ||
1473 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3); | ||
1474 | Stat2 = Stat2 << 16 | Stat3; | ||
1475 | CMSMPrintString( | ||
1476 | pAC->pConfigTable, | ||
1477 | MSG_TYPE_RUNTIME_INFO, | ||
1478 | "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x", | ||
1479 | (void *)Stat1, | ||
1480 | (void *)Stat2); | ||
1481 | } | ||
1482 | #endif /* DEBUG */ | ||
1483 | |||
1484 | /* | ||
1485 | * Here we usually can check whether the link is in sync and | ||
1486 | * auto-negotiation is done. | ||
1487 | */ | ||
1488 | |||
1489 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat); | ||
1490 | |||
1491 | SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); | ||
1492 | |||
1493 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1494 | ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat)); | ||
1495 | |||
1496 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb); | ||
1497 | |||
1498 | if ((ResAb & PHY_B_1000S_MSF) != 0) { | ||
1499 | /* Error */ | ||
1500 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1501 | ("Master/Slave Fault port %d\n", Port)); | ||
1502 | |||
1503 | pPrt->PAutoNegFail = SK_TRUE; | ||
1504 | pPrt->PMSStatus = SK_MS_STAT_FAULT; | ||
1505 | |||
1506 | return(SK_HW_PS_RESTART); | ||
1507 | } | ||
1508 | |||
1509 | if ((PhyStat & PHY_ST_LSYNC) == 0) { | ||
1510 | return(SK_HW_PS_NONE); | ||
1511 | } | ||
1512 | |||
1513 | pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? | ||
1514 | SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE; | ||
1515 | |||
1516 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1517 | ("Port %d, ResAb: 0x%04X\n", Port, ResAb)); | ||
1518 | |||
1519 | if (AutoNeg) { | ||
1520 | if ((PhyStat & PHY_ST_AN_OVER) != 0) { | ||
1521 | |||
1522 | SkHWLinkUp(pAC, IoC, Port); | ||
1523 | |||
1524 | Done = SkMacAutoNegDone(pAC, IoC, Port); | ||
1525 | |||
1526 | if (Done != SK_AND_OK) { | ||
1527 | #ifdef DEBUG | ||
1528 | /* Get PHY parameters, for debugging only */ | ||
1529 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LpAb); | ||
1530 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ExtStat); | ||
1531 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1532 | ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n", | ||
1533 | Port, LpAb, ExtStat)); | ||
1534 | #endif /* DEBUG */ | ||
1535 | return(SK_HW_PS_RESTART); | ||
1536 | } | ||
1537 | else { | ||
1538 | #ifdef xDEBUG | ||
1539 | /* Dummy read ISR to prevent extra link downs/ups */ | ||
1540 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat); | ||
1541 | |||
1542 | if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) { | ||
1543 | CMSMPrintString( | ||
1544 | pAC->pConfigTable, | ||
1545 | MSG_TYPE_RUNTIME_INFO, | ||
1546 | "CheckUp2 - Stat: %x", | ||
1547 | (void *)ExtStat, | ||
1548 | (void *)NULL); | ||
1549 | } | ||
1550 | #endif /* DEBUG */ | ||
1551 | return(SK_HW_PS_LINK); | ||
1552 | } | ||
1553 | } | ||
1554 | } | ||
1555 | else { /* !AutoNeg */ | ||
1556 | /* Link is up and we don't need more. */ | ||
1557 | #ifdef DEBUG | ||
1558 | if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) { | ||
1559 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1560 | ("ERROR: Lipa auto detected on port %d\n", Port)); | ||
1561 | } | ||
1562 | #endif /* DEBUG */ | ||
1563 | |||
1564 | #ifdef xDEBUG | ||
1565 | /* Dummy read ISR to prevent extra link downs/ups */ | ||
1566 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat); | ||
1567 | |||
1568 | if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) { | ||
1569 | CMSMPrintString( | ||
1570 | pAC->pConfigTable, | ||
1571 | MSG_TYPE_RUNTIME_INFO, | ||
1572 | "CheckUp3 - Stat: %x", | ||
1573 | (void *)ExtStat, | ||
1574 | (void *)NULL); | ||
1575 | } | ||
1576 | #endif /* DEBUG */ | ||
1577 | |||
1578 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, | ||
1579 | ("Link sync(GP), Port %d\n", Port)); | ||
1580 | SkHWLinkUp(pAC, IoC, Port); | ||
1581 | |||
1582 | return(SK_HW_PS_LINK); | ||
1583 | } | ||
1584 | |||
1585 | return(SK_HW_PS_NONE); | ||
1586 | } /* SkGePortCheckUpBcom */ | ||
1587 | #endif /* GENESIS */ | ||
1588 | |||
1589 | |||
1590 | #ifdef YUKON | ||
1591 | /****************************************************************************** | ||
1592 | * | ||
1593 | * SkGePortCheckUpGmac() - Check if the link is up on Marvell PHY | ||
1594 | * | ||
1595 | * return: | ||
1596 | * 0 o.k. nothing needed | ||
1597 | * 1 Restart needed on this port | ||
1598 | * 2 Link came up | ||
1599 | */ | ||
1600 | static int SkGePortCheckUpGmac( | ||
1601 | SK_AC *pAC, /* Adapter Context */ | ||
1602 | SK_IOC IoC, /* IO Context */ | ||
1603 | int Port, /* Which port should be checked */ | ||
1604 | SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ | ||
1605 | { | ||
1606 | SK_GEPORT *pPrt; /* GIni Port struct pointer */ | ||
1607 | int Done; | ||
1608 | SK_U16 PhyIsrc; /* PHY Interrupt source */ | ||
1609 | SK_U16 PhyStat; /* PPY Status */ | ||
1610 | SK_U16 PhySpecStat;/* PHY Specific Status */ | ||
1611 | SK_U16 ResAb; /* Master/Slave resolution */ | ||
1612 | SK_EVPARA Para; | ||
1613 | #ifdef DEBUG | ||
1614 | SK_U16 Word; /* I/O helper */ | ||
1615 | #endif /* DEBUG */ | ||
1616 | |||
1617 | pPrt = &pAC->GIni.GP[Port]; | ||
1618 | |||
1619 | if (pPrt->PHWLinkUp) { | ||
1620 | return(SK_HW_PS_NONE); | ||
1621 | } | ||
1622 | |||
1623 | /* Read PHY Status */ | ||
1624 | SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat); | ||
1625 | |||
1626 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1627 | ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat)); | ||
1628 | |||
1629 | /* Read PHY Interrupt Status */ | ||
1630 | SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &PhyIsrc); | ||
1631 | |||
1632 | if ((PhyIsrc & PHY_M_IS_AN_COMPL) != 0) { | ||
1633 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1634 | ("Auto-Negotiation Completed, PhyIsrc: 0x%04X\n", PhyIsrc)); | ||
1635 | } | ||
1636 | |||
1637 | if ((PhyIsrc & PHY_M_IS_LSP_CHANGE) != 0) { | ||
1638 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1639 | ("Link Speed Changed, PhyIsrc: 0x%04X\n", PhyIsrc)); | ||
1640 | } | ||
1641 | |||
1642 | SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); | ||
1643 | |||
1644 | SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb); | ||
1645 | |||
1646 | if ((ResAb & PHY_B_1000S_MSF) != 0) { | ||
1647 | /* Error */ | ||
1648 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1649 | ("Master/Slave Fault port %d\n", Port)); | ||
1650 | |||
1651 | pPrt->PAutoNegFail = SK_TRUE; | ||
1652 | pPrt->PMSStatus = SK_MS_STAT_FAULT; | ||
1653 | |||
1654 | return(SK_HW_PS_RESTART); | ||
1655 | } | ||
1656 | |||
1657 | /* Read PHY Specific Status */ | ||
1658 | SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat); | ||
1659 | |||
1660 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1661 | ("Phy1000BT: 0x%04X, PhySpecStat: 0x%04X\n", ResAb, PhySpecStat)); | ||
1662 | |||
1663 | #ifdef DEBUG | ||
1664 | SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_EXP, &Word); | ||
1665 | |||
1666 | if ((PhyIsrc & PHY_M_IS_AN_PR) != 0 || (Word & PHY_ANE_RX_PG) != 0 || | ||
1667 | (PhySpecStat & PHY_M_PS_PAGE_REC) != 0) { | ||
1668 | /* Read PHY Next Page Link Partner */ | ||
1669 | SkGmPhyRead(pAC, IoC, Port, PHY_MARV_NEPG_LP, &Word); | ||
1670 | |||
1671 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1672 | ("Page Received, NextPage: 0x%04X\n", Word)); | ||
1673 | } | ||
1674 | #endif /* DEBUG */ | ||
1675 | |||
1676 | if ((PhySpecStat & PHY_M_PS_LINK_UP) == 0) { | ||
1677 | return(SK_HW_PS_NONE); | ||
1678 | } | ||
1679 | |||
1680 | if ((PhySpecStat & PHY_M_PS_DOWNS_STAT) != 0 || | ||
1681 | (PhyIsrc & PHY_M_IS_DOWNSH_DET) != 0) { | ||
1682 | /* Downshift detected */ | ||
1683 | SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E025, SKERR_SIRQ_E025MSG); | ||
1684 | |||
1685 | Para.Para64 = Port; | ||
1686 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_DOWNSHIFT_DET, Para); | ||
1687 | |||
1688 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1689 | ("Downshift detected, PhyIsrc: 0x%04X\n", PhyIsrc)); | ||
1690 | } | ||
1691 | |||
1692 | pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? | ||
1693 | SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE; | ||
1694 | |||
1695 | pPrt->PCableLen = (SK_U8)((PhySpecStat & PHY_M_PS_CABLE_MSK) >> 7); | ||
1696 | |||
1697 | if (AutoNeg) { | ||
1698 | /* Auto-Negotiation Over ? */ | ||
1699 | if ((PhyStat & PHY_ST_AN_OVER) != 0) { | ||
1700 | |||
1701 | SkHWLinkUp(pAC, IoC, Port); | ||
1702 | |||
1703 | Done = SkMacAutoNegDone(pAC, IoC, Port); | ||
1704 | |||
1705 | if (Done != SK_AND_OK) { | ||
1706 | return(SK_HW_PS_RESTART); | ||
1707 | } | ||
1708 | |||
1709 | return(SK_HW_PS_LINK); | ||
1710 | } | ||
1711 | } | ||
1712 | else { /* !AutoNeg */ | ||
1713 | /* Link is up and we don't need more */ | ||
1714 | #ifdef DEBUG | ||
1715 | if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) { | ||
1716 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1717 | ("ERROR: Lipa auto detected on port %d\n", Port)); | ||
1718 | } | ||
1719 | #endif /* DEBUG */ | ||
1720 | |||
1721 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, | ||
1722 | ("Link sync, Port %d\n", Port)); | ||
1723 | SkHWLinkUp(pAC, IoC, Port); | ||
1724 | |||
1725 | return(SK_HW_PS_LINK); | ||
1726 | } | ||
1727 | |||
1728 | return(SK_HW_PS_NONE); | ||
1729 | } /* SkGePortCheckUpGmac */ | ||
1730 | #endif /* YUKON */ | ||
1731 | |||
1732 | |||
1733 | #ifdef OTHER_PHY | ||
1734 | /****************************************************************************** | ||
1735 | * | ||
1736 | * SkGePortCheckUpLone() - Check if the link is up on Level One PHY | ||
1737 | * | ||
1738 | * return: | ||
1739 | * 0 o.k. nothing needed | ||
1740 | * 1 Restart needed on this port | ||
1741 | * 2 Link came up | ||
1742 | */ | ||
1743 | static int SkGePortCheckUpLone( | ||
1744 | SK_AC *pAC, /* Adapter Context */ | ||
1745 | SK_IOC IoC, /* IO Context */ | ||
1746 | int Port, /* Which port should be checked */ | ||
1747 | SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ | ||
1748 | { | ||
1749 | SK_GEPORT *pPrt; /* GIni Port struct pointer */ | ||
1750 | int Done; | ||
1751 | SK_U16 Isrc; /* Interrupt source register */ | ||
1752 | SK_U16 LpAb; /* Link Partner Ability */ | ||
1753 | SK_U16 ExtStat; /* Extended Status Register */ | ||
1754 | SK_U16 PhyStat; /* Phy Status Register */ | ||
1755 | SK_U16 StatSum; | ||
1756 | SK_U8 NextMode; /* Next AutoSensing Mode */ | ||
1757 | |||
1758 | pPrt = &pAC->GIni.GP[Port]; | ||
1759 | |||
1760 | if (pPrt->PHWLinkUp) { | ||
1761 | return(SK_HW_PS_NONE); | ||
1762 | } | ||
1763 | |||
1764 | StatSum = pPrt->PIsave; | ||
1765 | pPrt->PIsave = 0; | ||
1766 | |||
1767 | /* | ||
1768 | * here we usually can check whether the link is in sync and | ||
1769 | * auto-negotiation is done. | ||
1770 | */ | ||
1771 | SkXmPhyRead(pAC, IoC, Port, PHY_LONE_STAT, &PhyStat); | ||
1772 | StatSum |= PhyStat; | ||
1773 | |||
1774 | SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); | ||
1775 | |||
1776 | if ((PhyStat & PHY_ST_LSYNC) == 0) { | ||
1777 | /* Save Auto-negotiation Done bit */ | ||
1778 | pPrt->PIsave = (SK_U16)(StatSum & PHY_ST_AN_OVER); | ||
1779 | #ifdef DEBUG | ||
1780 | if ((pPrt->PIsave & PHY_ST_AN_OVER) != 0) { | ||
1781 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1782 | ("AutoNeg done rescheduled Port %d\n", Port)); | ||
1783 | } | ||
1784 | #endif /* DEBUG */ | ||
1785 | return(SK_HW_PS_NONE); | ||
1786 | } | ||
1787 | |||
1788 | if (AutoNeg) { | ||
1789 | if ((StatSum & PHY_ST_AN_OVER) != 0) { | ||
1790 | SkHWLinkUp(pAC, IoC, Port); | ||
1791 | Done = SkMacAutoNegDone(pAC, IoC, Port); | ||
1792 | if (Done != SK_AND_OK) { | ||
1793 | /* Get PHY parameters, for debugging only */ | ||
1794 | SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LpAb); | ||
1795 | SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ExtStat); | ||
1796 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1797 | ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n", | ||
1798 | Port, LpAb, ExtStat)); | ||
1799 | |||
1800 | /* Try next possible mode */ | ||
1801 | NextMode = SkHWSenseGetNext(pAC, IoC, Port); | ||
1802 | SkHWLinkDown(pAC, IoC, Port); | ||
1803 | if (Done == SK_AND_DUP_CAP) { | ||
1804 | /* GoTo next mode */ | ||
1805 | SkHWSenseSetNext(pAC, IoC, Port, NextMode); | ||
1806 | } | ||
1807 | |||
1808 | return(SK_HW_PS_RESTART); | ||
1809 | |||
1810 | } | ||
1811 | else { | ||
1812 | /* | ||
1813 | * Dummy Read interrupt status to prevent | ||
1814 | * extra link down/ups | ||
1815 | */ | ||
1816 | SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat); | ||
1817 | return(SK_HW_PS_LINK); | ||
1818 | } | ||
1819 | } | ||
1820 | |||
1821 | /* AutoNeg not done, but HW link is up. Check for timeouts */ | ||
1822 | pPrt->PAutoNegTimeOut++; | ||
1823 | if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) { | ||
1824 | /* Timeout occured */ | ||
1825 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, | ||
1826 | ("AutoNeg timeout Port %d\n", Port)); | ||
1827 | if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE && | ||
1828 | pPrt->PLipaAutoNeg != SK_LIPA_AUTO) { | ||
1829 | /* Set Link manually up */ | ||
1830 | SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL); | ||
1831 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, | ||
1832 | ("Set manual full duplex Port %d\n", Port)); | ||
1833 | } | ||
1834 | |||
1835 | /* Do the restart */ | ||
1836 | return(SK_HW_PS_RESTART); | ||
1837 | } | ||
1838 | } | ||
1839 | else { | ||
1840 | /* Link is up and we don't need more */ | ||
1841 | #ifdef DEBUG | ||
1842 | if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) { | ||
1843 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1844 | ("ERROR: Lipa auto detected on port %d\n", Port)); | ||
1845 | } | ||
1846 | #endif /* DEBUG */ | ||
1847 | |||
1848 | /* | ||
1849 | * Dummy Read interrupt status to prevent | ||
1850 | * extra link down/ups | ||
1851 | */ | ||
1852 | SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat); | ||
1853 | |||
1854 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, | ||
1855 | ("Link sync(GP), Port %d\n", Port)); | ||
1856 | SkHWLinkUp(pAC, IoC, Port); | ||
1857 | |||
1858 | return(SK_HW_PS_LINK); | ||
1859 | } | ||
1860 | |||
1861 | return(SK_HW_PS_NONE); | ||
1862 | } /* SkGePortCheckUpLone */ | ||
1863 | |||
1864 | |||
1865 | /****************************************************************************** | ||
1866 | * | ||
1867 | * SkGePortCheckUpNat() - Check if the link is up on National PHY | ||
1868 | * | ||
1869 | * return: | ||
1870 | * 0 o.k. nothing needed | ||
1871 | * 1 Restart needed on this port | ||
1872 | * 2 Link came up | ||
1873 | */ | ||
1874 | static int SkGePortCheckUpNat( | ||
1875 | SK_AC *pAC, /* Adapter Context */ | ||
1876 | SK_IOC IoC, /* IO Context */ | ||
1877 | int Port, /* Which port should be checked */ | ||
1878 | SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ | ||
1879 | { | ||
1880 | /* todo: National */ | ||
1881 | return(SK_HW_PS_NONE); | ||
1882 | } /* SkGePortCheckUpNat */ | ||
1883 | #endif /* OTHER_PHY */ | ||
1884 | |||
1885 | |||
1886 | /****************************************************************************** | ||
1887 | * | ||
1888 | * SkGeSirqEvent() - Event Service Routine | ||
1889 | * | ||
1890 | * Description: | ||
1891 | * | ||
1892 | * Notes: | ||
1893 | */ | ||
1894 | int SkGeSirqEvent( | ||
1895 | SK_AC *pAC, /* Adapter Context */ | ||
1896 | SK_IOC IoC, /* Io Context */ | ||
1897 | SK_U32 Event, /* Module specific Event */ | ||
1898 | SK_EVPARA Para) /* Event specific Parameter */ | ||
1899 | { | ||
1900 | SK_GEPORT *pPrt; /* GIni Port struct pointer */ | ||
1901 | SK_U32 Port; | ||
1902 | SK_U32 Val32; | ||
1903 | int PortStat; | ||
1904 | SK_U8 Val8; | ||
1905 | #ifdef GENESIS | ||
1906 | SK_U64 Octets; | ||
1907 | #endif /* GENESIS */ | ||
1908 | |||
1909 | Port = Para.Para32[0]; | ||
1910 | pPrt = &pAC->GIni.GP[Port]; | ||
1911 | |||
1912 | switch (Event) { | ||
1913 | case SK_HWEV_WATIM: | ||
1914 | if (pPrt->PState == SK_PRT_RESET) { | ||
1915 | |||
1916 | PortStat = SK_HW_PS_NONE; | ||
1917 | } | ||
1918 | else { | ||
1919 | /* Check whether port came up */ | ||
1920 | PortStat = SkGePortCheckUp(pAC, IoC, (int)Port); | ||
1921 | } | ||
1922 | |||
1923 | switch (PortStat) { | ||
1924 | case SK_HW_PS_RESTART: | ||
1925 | if (pPrt->PHWLinkUp) { | ||
1926 | /* Set Link to down */ | ||
1927 | SkHWLinkDown(pAC, IoC, (int)Port); | ||
1928 | |||
1929 | /* | ||
1930 | * Signal directly to RLMT to ensure correct | ||
1931 | * sequence of SWITCH and RESET event. | ||
1932 | */ | ||
1933 | SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para); | ||
1934 | } | ||
1935 | |||
1936 | /* Restart needed */ | ||
1937 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para); | ||
1938 | break; | ||
1939 | |||
1940 | case SK_HW_PS_LINK: | ||
1941 | /* Signal to RLMT */ | ||
1942 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_UP, Para); | ||
1943 | break; | ||
1944 | } | ||
1945 | |||
1946 | /* Start again the check Timer */ | ||
1947 | if (pPrt->PHWLinkUp) { | ||
1948 | Val32 = SK_WA_ACT_TIME; | ||
1949 | } | ||
1950 | else { | ||
1951 | Val32 = SK_WA_INA_TIME; | ||
1952 | } | ||
1953 | |||
1954 | /* Todo: still needed for non-XMAC PHYs??? */ | ||
1955 | /* Start workaround Errata #2 timer */ | ||
1956 | SkTimerStart(pAC, IoC, &pPrt->PWaTimer, Val32, | ||
1957 | SKGE_HWAC, SK_HWEV_WATIM, Para); | ||
1958 | break; | ||
1959 | |||
1960 | case SK_HWEV_PORT_START: | ||
1961 | if (pPrt->PHWLinkUp) { | ||
1962 | /* | ||
1963 | * Signal directly to RLMT to ensure correct | ||
1964 | * sequence of SWITCH and RESET event. | ||
1965 | */ | ||
1966 | SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para); | ||
1967 | } | ||
1968 | |||
1969 | SkHWLinkDown(pAC, IoC, (int)Port); | ||
1970 | |||
1971 | /* Schedule Port RESET */ | ||
1972 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para); | ||
1973 | |||
1974 | /* Start workaround Errata #2 timer */ | ||
1975 | SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME, | ||
1976 | SKGE_HWAC, SK_HWEV_WATIM, Para); | ||
1977 | break; | ||
1978 | |||
1979 | case SK_HWEV_PORT_STOP: | ||
1980 | if (pPrt->PHWLinkUp) { | ||
1981 | /* | ||
1982 | * Signal directly to RLMT to ensure correct | ||
1983 | * sequence of SWITCH and RESET event. | ||
1984 | */ | ||
1985 | SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para); | ||
1986 | } | ||
1987 | |||
1988 | /* Stop Workaround Timer */ | ||
1989 | SkTimerStop(pAC, IoC, &pPrt->PWaTimer); | ||
1990 | |||
1991 | SkHWLinkDown(pAC, IoC, (int)Port); | ||
1992 | break; | ||
1993 | |||
1994 | case SK_HWEV_UPDATE_STAT: | ||
1995 | /* We do NOT need to update any statistics */ | ||
1996 | break; | ||
1997 | |||
1998 | case SK_HWEV_CLEAR_STAT: | ||
1999 | /* We do NOT need to clear any statistics */ | ||
2000 | for (Port = 0; Port < (SK_U32)pAC->GIni.GIMacsFound; Port++) { | ||
2001 | pPrt->PPrevRx = 0; | ||
2002 | pPrt->PPrevFcs = 0; | ||
2003 | pPrt->PPrevShorts = 0; | ||
2004 | } | ||
2005 | break; | ||
2006 | |||
2007 | case SK_HWEV_SET_LMODE: | ||
2008 | Val8 = (SK_U8)Para.Para32[1]; | ||
2009 | if (pPrt->PLinkModeConf != Val8) { | ||
2010 | /* Set New link mode */ | ||
2011 | pPrt->PLinkModeConf = Val8; | ||
2012 | |||
2013 | /* Restart Port */ | ||
2014 | SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para); | ||
2015 | SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para); | ||
2016 | } | ||
2017 | break; | ||
2018 | |||
2019 | case SK_HWEV_SET_FLOWMODE: | ||
2020 | Val8 = (SK_U8)Para.Para32[1]; | ||
2021 | if (pPrt->PFlowCtrlMode != Val8) { | ||
2022 | /* Set New Flow Control mode */ | ||
2023 | pPrt->PFlowCtrlMode = Val8; | ||
2024 | |||
2025 | /* Restart Port */ | ||
2026 | SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para); | ||
2027 | SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para); | ||
2028 | } | ||
2029 | break; | ||
2030 | |||
2031 | case SK_HWEV_SET_ROLE: | ||
2032 | /* not possible for fiber */ | ||
2033 | if (!pAC->GIni.GICopperType) { | ||
2034 | break; | ||
2035 | } | ||
2036 | Val8 = (SK_U8)Para.Para32[1]; | ||
2037 | if (pPrt->PMSMode != Val8) { | ||
2038 | /* Set New Role (Master/Slave) mode */ | ||
2039 | pPrt->PMSMode = 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_SPEED: | ||
2048 | if (pPrt->PhyType != SK_PHY_MARV_COPPER) { | ||
2049 | break; | ||
2050 | } | ||
2051 | Val8 = (SK_U8)Para.Para32[1]; | ||
2052 | if (pPrt->PLinkSpeed != Val8) { | ||
2053 | /* Set New Speed parameter */ | ||
2054 | pPrt->PLinkSpeed = Val8; | ||
2055 | |||
2056 | /* Restart Port */ | ||
2057 | SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para); | ||
2058 | SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para); | ||
2059 | } | ||
2060 | break; | ||
2061 | |||
2062 | #ifdef GENESIS | ||
2063 | case SK_HWEV_HALFDUP_CHK: | ||
2064 | if (pAC->GIni.GIGenesis) { | ||
2065 | /* | ||
2066 | * half duplex hangup workaround. | ||
2067 | * See packet arbiter timeout interrupt for description | ||
2068 | */ | ||
2069 | pPrt->HalfDupTimerActive = SK_FALSE; | ||
2070 | if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || | ||
2071 | pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) { | ||
2072 | /* Snap statistic counters */ | ||
2073 | (void)SkXmUpdateStats(pAC, IoC, Port); | ||
2074 | |||
2075 | (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_HI, &Val32); | ||
2076 | |||
2077 | Octets = (SK_U64)Val32 << 32; | ||
2078 | |||
2079 | (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_LO, &Val32); | ||
2080 | |||
2081 | Octets += Val32; | ||
2082 | |||
2083 | if (pPrt->LastOctets == Octets) { | ||
2084 | /* Tx hanging, a FIFO flush restarts it */ | ||
2085 | SkMacFlushTxFifo(pAC, IoC, Port); | ||
2086 | } | ||
2087 | } | ||
2088 | } | ||
2089 | break; | ||
2090 | #endif /* GENESIS */ | ||
2091 | |||
2092 | default: | ||
2093 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_SIRQ_E001, SKERR_SIRQ_E001MSG); | ||
2094 | break; | ||
2095 | } | ||
2096 | |||
2097 | return(0); | ||
2098 | } /* SkGeSirqEvent */ | ||
2099 | |||
2100 | |||
2101 | #ifdef GENESIS | ||
2102 | /****************************************************************************** | ||
2103 | * | ||
2104 | * SkPhyIsrBcom() - PHY interrupt service routine | ||
2105 | * | ||
2106 | * Description: handles all interrupts from BCom PHY | ||
2107 | * | ||
2108 | * Returns: N/A | ||
2109 | */ | ||
2110 | static void SkPhyIsrBcom( | ||
2111 | SK_AC *pAC, /* Adapter Context */ | ||
2112 | SK_IOC IoC, /* Io Context */ | ||
2113 | int Port, /* Port Num = PHY Num */ | ||
2114 | SK_U16 IStatus) /* Interrupt Status */ | ||
2115 | { | ||
2116 | SK_GEPORT *pPrt; /* GIni Port struct pointer */ | ||
2117 | SK_EVPARA Para; | ||
2118 | |||
2119 | pPrt = &pAC->GIni.GP[Port]; | ||
2120 | |||
2121 | if ((IStatus & PHY_B_IS_PSE) != 0) { | ||
2122 | /* Incorrectable pair swap error */ | ||
2123 | SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E022, | ||
2124 | SKERR_SIRQ_E022MSG); | ||
2125 | } | ||
2126 | |||
2127 | if ((IStatus & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) != 0) { | ||
2128 | |||
2129 | SkHWLinkDown(pAC, IoC, Port); | ||
2130 | |||
2131 | Para.Para32[0] = (SK_U32)Port; | ||
2132 | /* Signal to RLMT */ | ||
2133 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); | ||
2134 | |||
2135 | /* Start workaround Errata #2 timer */ | ||
2136 | SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME, | ||
2137 | SKGE_HWAC, SK_HWEV_WATIM, Para); | ||
2138 | } | ||
2139 | |||
2140 | } /* SkPhyIsrBcom */ | ||
2141 | #endif /* GENESIS */ | ||
2142 | |||
2143 | |||
2144 | #ifdef YUKON | ||
2145 | /****************************************************************************** | ||
2146 | * | ||
2147 | * SkPhyIsrGmac() - PHY interrupt service routine | ||
2148 | * | ||
2149 | * Description: handles all interrupts from Marvell PHY | ||
2150 | * | ||
2151 | * Returns: N/A | ||
2152 | */ | ||
2153 | static void SkPhyIsrGmac( | ||
2154 | SK_AC *pAC, /* Adapter Context */ | ||
2155 | SK_IOC IoC, /* Io Context */ | ||
2156 | int Port, /* Port Num = PHY Num */ | ||
2157 | SK_U16 IStatus) /* Interrupt Status */ | ||
2158 | { | ||
2159 | SK_GEPORT *pPrt; /* GIni Port struct pointer */ | ||
2160 | SK_EVPARA Para; | ||
2161 | SK_U16 Word; | ||
2162 | |||
2163 | pPrt = &pAC->GIni.GP[Port]; | ||
2164 | |||
2165 | if ((IStatus & (PHY_M_IS_AN_PR | PHY_M_IS_LST_CHANGE)) != 0) { | ||
2166 | |||
2167 | SkHWLinkDown(pAC, IoC, Port); | ||
2168 | |||
2169 | SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &Word); | ||
2170 | |||
2171 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2172 | ("AutoNeg.Adv: 0x%04X\n", Word)); | ||
2173 | |||
2174 | /* Set Auto-negotiation advertisement */ | ||
2175 | if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) { | ||
2176 | /* restore Asymmetric Pause bit */ | ||
2177 | SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, | ||
2178 | (SK_U16)(Word | PHY_M_AN_ASP)); | ||
2179 | } | ||
2180 | |||
2181 | Para.Para32[0] = (SK_U32)Port; | ||
2182 | /* Signal to RLMT */ | ||
2183 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); | ||
2184 | } | ||
2185 | |||
2186 | if ((IStatus & PHY_M_IS_AN_ERROR) != 0) { | ||
2187 | /* Auto-Negotiation Error */ | ||
2188 | SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E023, SKERR_SIRQ_E023MSG); | ||
2189 | } | ||
2190 | |||
2191 | if ((IStatus & PHY_M_IS_FIFO_ERROR) != 0) { | ||
2192 | /* FIFO Overflow/Underrun Error */ | ||
2193 | SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E024, SKERR_SIRQ_E024MSG); | ||
2194 | } | ||
2195 | |||
2196 | } /* SkPhyIsrGmac */ | ||
2197 | #endif /* YUKON */ | ||
2198 | |||
2199 | |||
2200 | #ifdef OTHER_PHY | ||
2201 | /****************************************************************************** | ||
2202 | * | ||
2203 | * SkPhyIsrLone() - PHY interrupt service routine | ||
2204 | * | ||
2205 | * Description: handles all interrupts from LONE PHY | ||
2206 | * | ||
2207 | * Returns: N/A | ||
2208 | */ | ||
2209 | static void SkPhyIsrLone( | ||
2210 | SK_AC *pAC, /* Adapter Context */ | ||
2211 | SK_IOC IoC, /* Io Context */ | ||
2212 | int Port, /* Port Num = PHY Num */ | ||
2213 | SK_U16 IStatus) /* Interrupt Status */ | ||
2214 | { | ||
2215 | SK_EVPARA Para; | ||
2216 | |||
2217 | if (IStatus & (PHY_L_IS_DUP | PHY_L_IS_ISOL)) { | ||
2218 | |||
2219 | SkHWLinkDown(pAC, IoC, Port); | ||
2220 | |||
2221 | Para.Para32[0] = (SK_U32)Port; | ||
2222 | /* Signal to RLMT */ | ||
2223 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); | ||
2224 | } | ||
2225 | |||
2226 | } /* SkPhyIsrLone */ | ||
2227 | #endif /* OTHER_PHY */ | ||
2228 | |||
2229 | /* End of File */ | ||
diff --git a/drivers/net/sk98lin/ski2c.c b/drivers/net/sk98lin/ski2c.c new file mode 100644 index 000000000000..79bf57cb5326 --- /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 | static 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 | static 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 | static 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..a204f5bb55d4 --- /dev/null +++ b/drivers/net/sk98lin/sklm80.c | |||
@@ -0,0 +1,141 @@ | |||
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 | #define BREAK_OR_WAIT(pAC,IoC,Event) break | ||
38 | |||
39 | /* | ||
40 | * read a sensors value (LM80 specific) | ||
41 | * | ||
42 | * This function reads a sensors value from the I2C sensor chip LM80. | ||
43 | * The sensor is defined by its index into the sensors database in the struct | ||
44 | * pAC points to. | ||
45 | * | ||
46 | * Returns 1 if the read is completed | ||
47 | * 0 if the read must be continued (I2C Bus still allocated) | ||
48 | */ | ||
49 | int SkLm80ReadSensor( | ||
50 | SK_AC *pAC, /* Adapter Context */ | ||
51 | SK_IOC IoC, /* I/O Context needed in level 1 and 2 */ | ||
52 | SK_SENSOR *pSen) /* Sensor to be read */ | ||
53 | { | ||
54 | SK_I32 Value; | ||
55 | |||
56 | switch (pSen->SenState) { | ||
57 | case SK_SEN_IDLE: | ||
58 | /* Send address to ADDR register */ | ||
59 | SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, pSen->SenReg, 0); | ||
60 | |||
61 | pSen->SenState = SK_SEN_VALUE ; | ||
62 | BREAK_OR_WAIT(pAC, IoC, I2C_READ); | ||
63 | |||
64 | case SK_SEN_VALUE: | ||
65 | /* Read value from data register */ | ||
66 | SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value)); | ||
67 | |||
68 | Value &= 0xff; /* only least significant byte is valid */ | ||
69 | |||
70 | /* Do NOT check the Value against the thresholds */ | ||
71 | /* Checking is done in the calling instance */ | ||
72 | |||
73 | if (pSen->SenType == SK_SEN_VOLT) { | ||
74 | /* Voltage sensor */ | ||
75 | pSen->SenValue = Value * SK_LM80_VT_LSB; | ||
76 | pSen->SenState = SK_SEN_IDLE ; | ||
77 | return(1); | ||
78 | } | ||
79 | |||
80 | if (pSen->SenType == SK_SEN_FAN) { | ||
81 | if (Value != 0 && Value != 0xff) { | ||
82 | /* Fan speed counter */ | ||
83 | pSen->SenValue = SK_LM80_FAN_FAKTOR/Value; | ||
84 | } | ||
85 | else { | ||
86 | /* Indicate Fan error */ | ||
87 | pSen->SenValue = 0; | ||
88 | } | ||
89 | pSen->SenState = SK_SEN_IDLE ; | ||
90 | return(1); | ||
91 | } | ||
92 | |||
93 | /* First: correct the value: it might be negative */ | ||
94 | if ((Value & 0x80) != 0) { | ||
95 | /* Value is negative */ | ||
96 | Value = Value - 256; | ||
97 | } | ||
98 | |||
99 | /* We have a temperature sensor and need to get the signed extension. | ||
100 | * For now we get the extension from the last reading, so in the normal | ||
101 | * case we won't see flickering temperatures. | ||
102 | */ | ||
103 | pSen->SenValue = (Value * SK_LM80_TEMP_LSB) + | ||
104 | (pSen->SenValue % SK_LM80_TEMP_LSB); | ||
105 | |||
106 | /* Send address to ADDR register */ | ||
107 | SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, LM80_TEMP_CTRL, 0); | ||
108 | |||
109 | pSen->SenState = SK_SEN_VALEXT ; | ||
110 | BREAK_OR_WAIT(pAC, IoC, I2C_READ); | ||
111 | |||
112 | case SK_SEN_VALEXT: | ||
113 | /* Read value from data register */ | ||
114 | SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value)); | ||
115 | Value &= LM80_TEMP_LSB_9; /* only bit 7 is valid */ | ||
116 | |||
117 | /* cut the LSB bit */ | ||
118 | pSen->SenValue = ((pSen->SenValue / SK_LM80_TEMP_LSB) * | ||
119 | SK_LM80_TEMP_LSB); | ||
120 | |||
121 | if (pSen->SenValue < 0) { | ||
122 | /* Value negative: The bit value must be subtracted */ | ||
123 | pSen->SenValue -= ((Value >> 7) * SK_LM80_TEMPEXT_LSB); | ||
124 | } | ||
125 | else { | ||
126 | /* Value positive: The bit value must be added */ | ||
127 | pSen->SenValue += ((Value >> 7) * SK_LM80_TEMPEXT_LSB); | ||
128 | } | ||
129 | |||
130 | pSen->SenState = SK_SEN_IDLE ; | ||
131 | return(1); | ||
132 | |||
133 | default: | ||
134 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E007, SKERR_I2C_E007MSG); | ||
135 | return(1); | ||
136 | } | ||
137 | |||
138 | /* Not completed */ | ||
139 | return(0); | ||
140 | } | ||
141 | |||
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..be8d1ccddf6d --- /dev/null +++ b/drivers/net/sk98lin/skrlmt.c | |||
@@ -0,0 +1,3257 @@ | |||
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 | |||
286 | /* local variables ************************************************************/ | ||
287 | |||
288 | /* None. */ | ||
289 | |||
290 | /* functions ******************************************************************/ | ||
291 | |||
292 | RLMT_STATIC void SkRlmtCheckSwitch( | ||
293 | SK_AC *pAC, | ||
294 | SK_IOC IoC, | ||
295 | SK_U32 NetIdx); | ||
296 | RLMT_STATIC void SkRlmtCheckSeg( | ||
297 | SK_AC *pAC, | ||
298 | SK_IOC IoC, | ||
299 | SK_U32 NetIdx); | ||
300 | RLMT_STATIC void SkRlmtEvtSetNets( | ||
301 | SK_AC *pAC, | ||
302 | SK_IOC IoC, | ||
303 | SK_EVPARA Para); | ||
304 | |||
305 | /****************************************************************************** | ||
306 | * | ||
307 | * SkRlmtInit - initialize data, set state to init | ||
308 | * | ||
309 | * Description: | ||
310 | * | ||
311 | * SK_INIT_DATA | ||
312 | * ============ | ||
313 | * | ||
314 | * This routine initializes all RLMT-related variables to a known state. | ||
315 | * The initial state is SK_RLMT_RS_INIT. | ||
316 | * All ports are initialized to SK_RLMT_PS_INIT. | ||
317 | * | ||
318 | * | ||
319 | * SK_INIT_IO | ||
320 | * ========== | ||
321 | * | ||
322 | * Nothing. | ||
323 | * | ||
324 | * | ||
325 | * SK_INIT_RUN | ||
326 | * =========== | ||
327 | * | ||
328 | * Determine the adapter's random value. | ||
329 | * Set the hw registers, the "logical MAC address", the | ||
330 | * RLMT multicast address, and eventually the BPDU multicast address. | ||
331 | * | ||
332 | * Context: | ||
333 | * init, pageable | ||
334 | * | ||
335 | * Returns: | ||
336 | * Nothing. | ||
337 | */ | ||
338 | void SkRlmtInit( | ||
339 | SK_AC *pAC, /* Adapter Context */ | ||
340 | SK_IOC IoC, /* I/O Context */ | ||
341 | int Level) /* Initialization Level */ | ||
342 | { | ||
343 | SK_U32 i, j; | ||
344 | SK_U64 Random; | ||
345 | SK_EVPARA Para; | ||
346 | SK_MAC_ADDR VirtualMacAddress; | ||
347 | SK_MAC_ADDR PhysicalAMacAddress; | ||
348 | SK_BOOL VirtualMacAddressSet; | ||
349 | SK_BOOL PhysicalAMacAddressSet; | ||
350 | |||
351 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT, | ||
352 | ("RLMT Init level %d.\n", Level)) | ||
353 | |||
354 | switch (Level) { | ||
355 | case SK_INIT_DATA: /* Initialize data structures. */ | ||
356 | SK_MEMSET((char *)&pAC->Rlmt, 0, sizeof(SK_RLMT)); | ||
357 | |||
358 | for (i = 0; i < SK_MAX_MACS; i++) { | ||
359 | pAC->Rlmt.Port[i].PortState = SK_RLMT_PS_INIT; | ||
360 | pAC->Rlmt.Port[i].LinkDown = SK_TRUE; | ||
361 | pAC->Rlmt.Port[i].PortDown = SK_TRUE; | ||
362 | pAC->Rlmt.Port[i].PortStarted = SK_FALSE; | ||
363 | pAC->Rlmt.Port[i].PortNoRx = SK_FALSE; | ||
364 | pAC->Rlmt.Port[i].RootIdSet = SK_FALSE; | ||
365 | pAC->Rlmt.Port[i].PortNumber = i; | ||
366 | pAC->Rlmt.Port[i].Net = &pAC->Rlmt.Net[0]; | ||
367 | pAC->Rlmt.Port[i].AddrPort = &pAC->Addr.Port[i]; | ||
368 | } | ||
369 | |||
370 | pAC->Rlmt.NumNets = 1; | ||
371 | for (i = 0; i < SK_MAX_NETS; i++) { | ||
372 | pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT; | ||
373 | pAC->Rlmt.Net[i].RootIdSet = SK_FALSE; | ||
374 | pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT; | ||
375 | pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF; /* Automatic. */ | ||
376 | /* Just assuming. */ | ||
377 | pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort; | ||
378 | pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE; | ||
379 | pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL; | ||
380 | pAC->Rlmt.Net[i].NetNumber = i; | ||
381 | } | ||
382 | |||
383 | pAC->Rlmt.Net[0].Port[0] = &pAC->Rlmt.Port[0]; | ||
384 | pAC->Rlmt.Net[0].Port[1] = &pAC->Rlmt.Port[1]; | ||
385 | #if SK_MAX_NETS > 1 | ||
386 | pAC->Rlmt.Net[1].Port[0] = &pAC->Rlmt.Port[1]; | ||
387 | #endif /* SK_MAX_NETS > 1 */ | ||
388 | break; | ||
389 | |||
390 | case SK_INIT_IO: /* GIMacsFound first available here. */ | ||
391 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT, | ||
392 | ("RLMT: %d MACs were detected.\n", pAC->GIni.GIMacsFound)) | ||
393 | |||
394 | pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound; | ||
395 | |||
396 | /* Initialize HW registers? */ | ||
397 | if (pAC->GIni.GIMacsFound == 1) { | ||
398 | Para.Para32[0] = SK_RLMT_MODE_CLS; | ||
399 | Para.Para32[1] = 0; | ||
400 | (void)SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE, Para); | ||
401 | } | ||
402 | break; | ||
403 | |||
404 | case SK_INIT_RUN: | ||
405 | /* Ensure RLMT is set to one net. */ | ||
406 | if (pAC->Rlmt.NumNets > 1) { | ||
407 | Para.Para32[0] = 1; | ||
408 | Para.Para32[1] = -1; | ||
409 | SkRlmtEvtSetNets(pAC, IoC, Para); | ||
410 | } | ||
411 | |||
412 | for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { | ||
413 | Random = SkOsGetTime(pAC); | ||
414 | *(SK_U32*)&pAC->Rlmt.Port[i].Random = *(SK_U32*)&Random; | ||
415 | |||
416 | for (j = 0; j < 4; j++) { | ||
417 | pAC->Rlmt.Port[i].Random[j] ^= pAC->Rlmt.Port[i].AddrPort-> | ||
418 | CurrentMacAddress.a[SK_MAC_ADDR_LEN - 1 - j]; | ||
419 | } | ||
420 | |||
421 | (void)SkAddrMcClear(pAC, IoC, i, SK_ADDR_PERMANENT | SK_MC_SW_ONLY); | ||
422 | |||
423 | /* Add RLMT MC address. */ | ||
424 | (void)SkAddrMcAdd(pAC, IoC, i, &SkRlmtMcAddr, SK_ADDR_PERMANENT); | ||
425 | |||
426 | if (pAC->Rlmt.Net[0].RlmtMode & SK_RLMT_CHECK_SEG) { | ||
427 | /* Add BPDU MC address. */ | ||
428 | (void)SkAddrMcAdd(pAC, IoC, i, &BridgeMcAddr, SK_ADDR_PERMANENT); | ||
429 | } | ||
430 | |||
431 | (void)SkAddrMcUpdate(pAC, IoC, i); | ||
432 | } | ||
433 | |||
434 | VirtualMacAddressSet = SK_FALSE; | ||
435 | /* Read virtual MAC address from Control Register File. */ | ||
436 | for (j = 0; j < SK_MAC_ADDR_LEN; j++) { | ||
437 | |||
438 | SK_IN8(IoC, B2_MAC_1 + j, &VirtualMacAddress.a[j]); | ||
439 | VirtualMacAddressSet |= VirtualMacAddress.a[j]; | ||
440 | } | ||
441 | |||
442 | PhysicalAMacAddressSet = SK_FALSE; | ||
443 | /* Read physical MAC address for MAC A from Control Register File. */ | ||
444 | for (j = 0; j < SK_MAC_ADDR_LEN; j++) { | ||
445 | |||
446 | SK_IN8(IoC, B2_MAC_2 + j, &PhysicalAMacAddress.a[j]); | ||
447 | PhysicalAMacAddressSet |= PhysicalAMacAddress.a[j]; | ||
448 | } | ||
449 | |||
450 | /* check if the two mac addresses contain reasonable values */ | ||
451 | if (!VirtualMacAddressSet || !PhysicalAMacAddressSet) { | ||
452 | |||
453 | pAC->Rlmt.RlmtOff = SK_TRUE; | ||
454 | } | ||
455 | |||
456 | /* if the two mac addresses are equal switch off the RLMT_PRE_LOOKAHEAD | ||
457 | and the RLMT_LOOKAHEAD macros */ | ||
458 | else if (SK_ADDR_EQUAL(PhysicalAMacAddress.a, VirtualMacAddress.a)) { | ||
459 | |||
460 | pAC->Rlmt.RlmtOff = SK_TRUE; | ||
461 | } | ||
462 | else { | ||
463 | pAC->Rlmt.RlmtOff = SK_FALSE; | ||
464 | } | ||
465 | break; | ||
466 | |||
467 | default: /* error */ | ||
468 | break; | ||
469 | } | ||
470 | return; | ||
471 | } /* SkRlmtInit */ | ||
472 | |||
473 | |||
474 | /****************************************************************************** | ||
475 | * | ||
476 | * SkRlmtBuildCheckChain - build the check chain | ||
477 | * | ||
478 | * Description: | ||
479 | * This routine builds the local check chain: | ||
480 | * - Each port that is up checks the next port. | ||
481 | * - The last port that is up checks the first port that is up. | ||
482 | * | ||
483 | * Notes: | ||
484 | * - Currently only local ports are considered when building the chain. | ||
485 | * - Currently the SuspectState is just reset; | ||
486 | * it would be better to save it ... | ||
487 | * | ||
488 | * Context: | ||
489 | * runtime, pageable? | ||
490 | * | ||
491 | * Returns: | ||
492 | * Nothing | ||
493 | */ | ||
494 | RLMT_STATIC void SkRlmtBuildCheckChain( | ||
495 | SK_AC *pAC, /* Adapter Context */ | ||
496 | SK_U32 NetIdx) /* Net Number */ | ||
497 | { | ||
498 | SK_U32 i; | ||
499 | SK_U32 NumMacsUp; | ||
500 | SK_RLMT_PORT * FirstMacUp; | ||
501 | SK_RLMT_PORT * PrevMacUp; | ||
502 | |||
503 | FirstMacUp = NULL; | ||
504 | PrevMacUp = NULL; | ||
505 | |||
506 | if (!(pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) { | ||
507 | for (i = 0; i < pAC->Rlmt.Net[i].NumPorts; i++) { | ||
508 | pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0; | ||
509 | } | ||
510 | return; /* Done. */ | ||
511 | } | ||
512 | |||
513 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
514 | ("SkRlmtBuildCheckChain.\n")) | ||
515 | |||
516 | NumMacsUp = 0; | ||
517 | |||
518 | for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) { | ||
519 | pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0; | ||
520 | pAC->Rlmt.Net[NetIdx].Port[i]->PortsSuspect = 0; | ||
521 | pAC->Rlmt.Net[NetIdx].Port[i]->CheckingState &= | ||
522 | ~(SK_RLMT_PCS_RX | SK_RLMT_PCS_TX); | ||
523 | |||
524 | /* | ||
525 | * If more than two links are detected we should consider | ||
526 | * checking at least two other ports: | ||
527 | * 1. the next port that is not LinkDown and | ||
528 | * 2. the next port that is not PortDown. | ||
529 | */ | ||
530 | if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) { | ||
531 | if (NumMacsUp == 0) { | ||
532 | FirstMacUp = pAC->Rlmt.Net[NetIdx].Port[i]; | ||
533 | } | ||
534 | else { | ||
535 | PrevMacUp->PortCheck[ | ||
536 | pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked].CheckAddr = | ||
537 | pAC->Rlmt.Net[NetIdx].Port[i]->AddrPort->CurrentMacAddress; | ||
538 | PrevMacUp->PortCheck[ | ||
539 | PrevMacUp->PortsChecked].SuspectTx = SK_FALSE; | ||
540 | PrevMacUp->PortsChecked++; | ||
541 | } | ||
542 | PrevMacUp = pAC->Rlmt.Net[NetIdx].Port[i]; | ||
543 | NumMacsUp++; | ||
544 | } | ||
545 | } | ||
546 | |||
547 | if (NumMacsUp > 1) { | ||
548 | PrevMacUp->PortCheck[PrevMacUp->PortsChecked].CheckAddr = | ||
549 | FirstMacUp->AddrPort->CurrentMacAddress; | ||
550 | PrevMacUp->PortCheck[PrevMacUp->PortsChecked].SuspectTx = | ||
551 | SK_FALSE; | ||
552 | PrevMacUp->PortsChecked++; | ||
553 | } | ||
554 | |||
555 | #ifdef DEBUG | ||
556 | for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) { | ||
557 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
558 | ("Port %d checks %d other ports: %2X.\n", i, | ||
559 | pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked, | ||
560 | pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[0].CheckAddr.a[5])) | ||
561 | } | ||
562 | #endif /* DEBUG */ | ||
563 | |||
564 | return; | ||
565 | } /* SkRlmtBuildCheckChain */ | ||
566 | |||
567 | |||
568 | /****************************************************************************** | ||
569 | * | ||
570 | * SkRlmtBuildPacket - build an RLMT packet | ||
571 | * | ||
572 | * Description: | ||
573 | * This routine sets up an RLMT packet. | ||
574 | * | ||
575 | * Context: | ||
576 | * runtime, pageable? | ||
577 | * | ||
578 | * Returns: | ||
579 | * NULL or pointer to RLMT mbuf | ||
580 | */ | ||
581 | RLMT_STATIC SK_MBUF *SkRlmtBuildPacket( | ||
582 | SK_AC *pAC, /* Adapter Context */ | ||
583 | SK_IOC IoC, /* I/O Context */ | ||
584 | SK_U32 PortNumber, /* Sending port */ | ||
585 | SK_U16 PacketType, /* RLMT packet type */ | ||
586 | SK_MAC_ADDR *SrcAddr, /* Source address */ | ||
587 | SK_MAC_ADDR *DestAddr) /* Destination address */ | ||
588 | { | ||
589 | int i; | ||
590 | SK_U16 Length; | ||
591 | SK_MBUF *pMb; | ||
592 | SK_RLMT_PACKET *pPacket; | ||
593 | |||
594 | #ifdef DEBUG | ||
595 | SK_U8 CheckSrc = 0; | ||
596 | SK_U8 CheckDest = 0; | ||
597 | |||
598 | for (i = 0; i < SK_MAC_ADDR_LEN; ++i) { | ||
599 | CheckSrc |= SrcAddr->a[i]; | ||
600 | CheckDest |= DestAddr->a[i]; | ||
601 | } | ||
602 | |||
603 | if ((CheckSrc == 0) || (CheckDest == 0)) { | ||
604 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_ERR, | ||
605 | ("SkRlmtBuildPacket: Invalid %s%saddr.\n", | ||
606 | (CheckSrc == 0 ? "Src" : ""), (CheckDest == 0 ? "Dest" : ""))) | ||
607 | } | ||
608 | #endif | ||
609 | |||
610 | if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) != NULL) { | ||
611 | pPacket = (SK_RLMT_PACKET*)pMb->pData; | ||
612 | for (i = 0; i < SK_MAC_ADDR_LEN; i++) { | ||
613 | pPacket->DstAddr[i] = DestAddr->a[i]; | ||
614 | pPacket->SrcAddr[i] = SrcAddr->a[i]; | ||
615 | } | ||
616 | pPacket->DSap = SK_RLMT_DSAP; | ||
617 | pPacket->SSap = SK_RLMT_SSAP; | ||
618 | pPacket->Ctrl = SK_RLMT_CTRL; | ||
619 | pPacket->Indicator[0] = SK_RLMT_INDICATOR0; | ||
620 | pPacket->Indicator[1] = SK_RLMT_INDICATOR1; | ||
621 | pPacket->Indicator[2] = SK_RLMT_INDICATOR2; | ||
622 | pPacket->Indicator[3] = SK_RLMT_INDICATOR3; | ||
623 | pPacket->Indicator[4] = SK_RLMT_INDICATOR4; | ||
624 | pPacket->Indicator[5] = SK_RLMT_INDICATOR5; | ||
625 | pPacket->Indicator[6] = SK_RLMT_INDICATOR6; | ||
626 | |||
627 | SK_U16_TO_NETWORK_ORDER(PacketType, &pPacket->RlmtPacketType[0]); | ||
628 | |||
629 | for (i = 0; i < 4; i++) { | ||
630 | pPacket->Random[i] = pAC->Rlmt.Port[PortNumber].Random[i]; | ||
631 | } | ||
632 | |||
633 | SK_U16_TO_NETWORK_ORDER( | ||
634 | SK_RLMT_PACKET_VERSION, &pPacket->RlmtPacketVersion[0]); | ||
635 | |||
636 | for (i = 0; i < SK_PACKET_DATA_LEN; i++) { | ||
637 | pPacket->Data[i] = 0x00; | ||
638 | } | ||
639 | |||
640 | Length = SK_RLMT_MAX_PACKET_SIZE; /* Or smaller. */ | ||
641 | pMb->Length = Length; | ||
642 | pMb->PortIdx = PortNumber; | ||
643 | Length -= 14; | ||
644 | SK_U16_TO_NETWORK_ORDER(Length, &pPacket->TypeLen[0]); | ||
645 | |||
646 | if (PacketType == SK_PACKET_ALIVE) { | ||
647 | pAC->Rlmt.Port[PortNumber].TxHelloCts++; | ||
648 | } | ||
649 | } | ||
650 | |||
651 | return (pMb); | ||
652 | } /* SkRlmtBuildPacket */ | ||
653 | |||
654 | |||
655 | /****************************************************************************** | ||
656 | * | ||
657 | * SkRlmtBuildSpanningTreePacket - build spanning tree check packet | ||
658 | * | ||
659 | * Description: | ||
660 | * This routine sets up a BPDU packet for spanning tree check. | ||
661 | * | ||
662 | * Context: | ||
663 | * runtime, pageable? | ||
664 | * | ||
665 | * Returns: | ||
666 | * NULL or pointer to RLMT mbuf | ||
667 | */ | ||
668 | RLMT_STATIC SK_MBUF *SkRlmtBuildSpanningTreePacket( | ||
669 | SK_AC *pAC, /* Adapter Context */ | ||
670 | SK_IOC IoC, /* I/O Context */ | ||
671 | SK_U32 PortNumber) /* Sending port */ | ||
672 | { | ||
673 | unsigned i; | ||
674 | SK_U16 Length; | ||
675 | SK_MBUF *pMb; | ||
676 | SK_SPTREE_PACKET *pSPacket; | ||
677 | |||
678 | if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) != | ||
679 | NULL) { | ||
680 | pSPacket = (SK_SPTREE_PACKET*)pMb->pData; | ||
681 | for (i = 0; i < SK_MAC_ADDR_LEN; i++) { | ||
682 | pSPacket->DstAddr[i] = BridgeMcAddr.a[i]; | ||
683 | pSPacket->SrcAddr[i] = | ||
684 | pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i]; | ||
685 | } | ||
686 | pSPacket->DSap = SK_RLMT_SPT_DSAP; | ||
687 | pSPacket->SSap = SK_RLMT_SPT_SSAP; | ||
688 | pSPacket->Ctrl = SK_RLMT_SPT_CTRL; | ||
689 | |||
690 | pSPacket->ProtocolId[0] = SK_RLMT_SPT_PROTOCOL_ID0; | ||
691 | pSPacket->ProtocolId[1] = SK_RLMT_SPT_PROTOCOL_ID1; | ||
692 | pSPacket->ProtocolVersionId = SK_RLMT_SPT_PROTOCOL_VERSION_ID; | ||
693 | pSPacket->BpduType = SK_RLMT_SPT_BPDU_TYPE; | ||
694 | pSPacket->Flags = SK_RLMT_SPT_FLAGS; | ||
695 | pSPacket->RootId[0] = SK_RLMT_SPT_ROOT_ID0; | ||
696 | pSPacket->RootId[1] = SK_RLMT_SPT_ROOT_ID1; | ||
697 | pSPacket->RootPathCost[0] = SK_RLMT_SPT_ROOT_PATH_COST0; | ||
698 | pSPacket->RootPathCost[1] = SK_RLMT_SPT_ROOT_PATH_COST1; | ||
699 | pSPacket->RootPathCost[2] = SK_RLMT_SPT_ROOT_PATH_COST2; | ||
700 | pSPacket->RootPathCost[3] = SK_RLMT_SPT_ROOT_PATH_COST3; | ||
701 | pSPacket->BridgeId[0] = SK_RLMT_SPT_BRIDGE_ID0; | ||
702 | pSPacket->BridgeId[1] = SK_RLMT_SPT_BRIDGE_ID1; | ||
703 | |||
704 | /* | ||
705 | * Use logical MAC address as bridge ID and filter these packets | ||
706 | * on receive. | ||
707 | */ | ||
708 | for (i = 0; i < SK_MAC_ADDR_LEN; i++) { | ||
709 | pSPacket->BridgeId[i + 2] = pSPacket->RootId[i + 2] = | ||
710 | pAC->Addr.Net[pAC->Rlmt.Port[PortNumber].Net->NetNumber]. | ||
711 | CurrentMacAddress.a[i]; | ||
712 | } | ||
713 | pSPacket->PortId[0] = SK_RLMT_SPT_PORT_ID0; | ||
714 | pSPacket->PortId[1] = SK_RLMT_SPT_PORT_ID1; | ||
715 | pSPacket->MessageAge[0] = SK_RLMT_SPT_MSG_AGE0; | ||
716 | pSPacket->MessageAge[1] = SK_RLMT_SPT_MSG_AGE1; | ||
717 | pSPacket->MaxAge[0] = SK_RLMT_SPT_MAX_AGE0; | ||
718 | pSPacket->MaxAge[1] = SK_RLMT_SPT_MAX_AGE1; | ||
719 | pSPacket->HelloTime[0] = SK_RLMT_SPT_HELLO_TIME0; | ||
720 | pSPacket->HelloTime[1] = SK_RLMT_SPT_HELLO_TIME1; | ||
721 | pSPacket->ForwardDelay[0] = SK_RLMT_SPT_FWD_DELAY0; | ||
722 | pSPacket->ForwardDelay[1] = SK_RLMT_SPT_FWD_DELAY1; | ||
723 | |||
724 | Length = SK_RLMT_MAX_PACKET_SIZE; /* Or smaller. */ | ||
725 | pMb->Length = Length; | ||
726 | pMb->PortIdx = PortNumber; | ||
727 | Length -= 14; | ||
728 | SK_U16_TO_NETWORK_ORDER(Length, &pSPacket->TypeLen[0]); | ||
729 | |||
730 | pAC->Rlmt.Port[PortNumber].TxSpHelloReqCts++; | ||
731 | } | ||
732 | |||
733 | return (pMb); | ||
734 | } /* SkRlmtBuildSpanningTreePacket */ | ||
735 | |||
736 | |||
737 | /****************************************************************************** | ||
738 | * | ||
739 | * SkRlmtSend - build and send check packets | ||
740 | * | ||
741 | * Description: | ||
742 | * Depending on the RLMT state and the checking state, several packets | ||
743 | * are sent through the indicated port. | ||
744 | * | ||
745 | * Context: | ||
746 | * runtime, pageable? | ||
747 | * | ||
748 | * Returns: | ||
749 | * Nothing. | ||
750 | */ | ||
751 | RLMT_STATIC void SkRlmtSend( | ||
752 | SK_AC *pAC, /* Adapter Context */ | ||
753 | SK_IOC IoC, /* I/O Context */ | ||
754 | SK_U32 PortNumber) /* Sending port */ | ||
755 | { | ||
756 | unsigned j; | ||
757 | SK_EVPARA Para; | ||
758 | SK_RLMT_PORT *pRPort; | ||
759 | |||
760 | pRPort = &pAC->Rlmt.Port[PortNumber]; | ||
761 | if (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) { | ||
762 | if (pRPort->CheckingState & (SK_RLMT_PCS_TX | SK_RLMT_PCS_RX)) { | ||
763 | /* Port is suspicious. Send the RLMT packet to the RLMT mc addr. */ | ||
764 | if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber, | ||
765 | SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress, | ||
766 | &SkRlmtMcAddr)) != NULL) { | ||
767 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); | ||
768 | } | ||
769 | } | ||
770 | else { | ||
771 | /* | ||
772 | * Send a directed RLMT packet to all ports that are | ||
773 | * checked by the indicated port. | ||
774 | */ | ||
775 | for (j = 0; j < pRPort->PortsChecked; j++) { | ||
776 | if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber, | ||
777 | SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress, | ||
778 | &pRPort->PortCheck[j].CheckAddr)) != NULL) { | ||
779 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); | ||
780 | } | ||
781 | } | ||
782 | } | ||
783 | } | ||
784 | |||
785 | if ((pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) && | ||
786 | (pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEND_SEG)) { | ||
787 | /* | ||
788 | * Send a BPDU packet to make a connected switch tell us | ||
789 | * the correct root bridge. | ||
790 | */ | ||
791 | if ((Para.pParaPtr = | ||
792 | SkRlmtBuildSpanningTreePacket(pAC, IoC, PortNumber)) != NULL) { | ||
793 | pAC->Rlmt.Port[PortNumber].Net->CheckingState &= ~SK_RLMT_RCS_SEND_SEG; | ||
794 | pRPort->RootIdSet = SK_FALSE; | ||
795 | |||
796 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); | ||
797 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_TX, | ||
798 | ("SkRlmtSend: BPDU Packet on Port %u.\n", PortNumber)) | ||
799 | } | ||
800 | } | ||
801 | return; | ||
802 | } /* SkRlmtSend */ | ||
803 | |||
804 | |||
805 | /****************************************************************************** | ||
806 | * | ||
807 | * SkRlmtPortReceives - check if port is (going) down and bring it up | ||
808 | * | ||
809 | * Description: | ||
810 | * This routine checks if a port who received a non-BPDU packet | ||
811 | * needs to go up or needs to be stopped going down. | ||
812 | * | ||
813 | * Context: | ||
814 | * runtime, pageable? | ||
815 | * | ||
816 | * Returns: | ||
817 | * Nothing. | ||
818 | */ | ||
819 | RLMT_STATIC void SkRlmtPortReceives( | ||
820 | SK_AC *pAC, /* Adapter Context */ | ||
821 | SK_IOC IoC, /* I/O Context */ | ||
822 | SK_U32 PortNumber) /* Port to check */ | ||
823 | { | ||
824 | SK_RLMT_PORT *pRPort; | ||
825 | SK_EVPARA Para; | ||
826 | |||
827 | pRPort = &pAC->Rlmt.Port[PortNumber]; | ||
828 | pRPort->PortNoRx = SK_FALSE; | ||
829 | |||
830 | if ((pRPort->PortState == SK_RLMT_PS_DOWN) && | ||
831 | !(pRPort->CheckingState & SK_RLMT_PCS_TX)) { | ||
832 | /* | ||
833 | * Port is marked down (rx), but received a non-BPDU packet. | ||
834 | * Bring it up. | ||
835 | */ | ||
836 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, | ||
837 | ("SkRlmtPacketReceive: Received on PortDown.\n")) | ||
838 | |||
839 | pRPort->PortState = SK_RLMT_PS_GOING_UP; | ||
840 | pRPort->GuTimeStamp = SkOsGetTime(pAC); | ||
841 | Para.Para32[0] = PortNumber; | ||
842 | Para.Para32[1] = (SK_U32)-1; | ||
843 | SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL, | ||
844 | SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para); | ||
845 | pRPort->CheckingState &= ~SK_RLMT_PCS_RX; | ||
846 | /* pAC->Rlmt.CheckSwitch = SK_TRUE; */ | ||
847 | SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber); | ||
848 | } /* PortDown && !SuspectTx */ | ||
849 | else if (pRPort->CheckingState & SK_RLMT_PCS_RX) { | ||
850 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, | ||
851 | ("SkRlmtPacketReceive: Stop bringing port down.\n")) | ||
852 | SkTimerStop(pAC, IoC, &pRPort->DownRxTimer); | ||
853 | pRPort->CheckingState &= ~SK_RLMT_PCS_RX; | ||
854 | /* pAC->Rlmt.CheckSwitch = SK_TRUE; */ | ||
855 | SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber); | ||
856 | } /* PortGoingDown */ | ||
857 | |||
858 | return; | ||
859 | } /* SkRlmtPortReceives */ | ||
860 | |||
861 | |||
862 | /****************************************************************************** | ||
863 | * | ||
864 | * SkRlmtPacketReceive - receive a packet for closer examination | ||
865 | * | ||
866 | * Description: | ||
867 | * This routine examines a packet more closely than SK_RLMT_LOOKAHEAD. | ||
868 | * | ||
869 | * Context: | ||
870 | * runtime, pageable? | ||
871 | * | ||
872 | * Returns: | ||
873 | * Nothing. | ||
874 | */ | ||
875 | RLMT_STATIC void SkRlmtPacketReceive( | ||
876 | SK_AC *pAC, /* Adapter Context */ | ||
877 | SK_IOC IoC, /* I/O Context */ | ||
878 | SK_MBUF *pMb) /* Received packet */ | ||
879 | { | ||
880 | #ifdef xDEBUG | ||
881 | extern void DumpData(char *p, int size); | ||
882 | #endif /* DEBUG */ | ||
883 | int i; | ||
884 | unsigned j; | ||
885 | SK_U16 PacketType; | ||
886 | SK_U32 PortNumber; | ||
887 | SK_ADDR_PORT *pAPort; | ||
888 | SK_RLMT_PORT *pRPort; | ||
889 | SK_RLMT_PACKET *pRPacket; | ||
890 | SK_SPTREE_PACKET *pSPacket; | ||
891 | SK_EVPARA Para; | ||
892 | |||
893 | PortNumber = pMb->PortIdx; | ||
894 | pAPort = &pAC->Addr.Port[PortNumber]; | ||
895 | pRPort = &pAC->Rlmt.Port[PortNumber]; | ||
896 | |||
897 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, | ||
898 | ("SkRlmtPacketReceive: PortNumber == %d.\n", PortNumber)) | ||
899 | |||
900 | pRPacket = (SK_RLMT_PACKET*)pMb->pData; | ||
901 | pSPacket = (SK_SPTREE_PACKET*)pRPacket; | ||
902 | |||
903 | #ifdef xDEBUG | ||
904 | DumpData((char *)pRPacket, 32); | ||
905 | #endif /* DEBUG */ | ||
906 | |||
907 | if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) != 0) { | ||
908 | SkRlmtPortReceives(pAC, IoC, PortNumber); | ||
909 | } | ||
910 | |||
911 | /* Check destination address. */ | ||
912 | |||
913 | if (!SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->DstAddr) && | ||
914 | !SK_ADDR_EQUAL(SkRlmtMcAddr.a, pRPacket->DstAddr) && | ||
915 | !SK_ADDR_EQUAL(BridgeMcAddr.a, pRPacket->DstAddr)) { | ||
916 | |||
917 | /* Not sent to current MAC or registered MC address => Trash it. */ | ||
918 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, | ||
919 | ("SkRlmtPacketReceive: Not for me.\n")) | ||
920 | |||
921 | SkDrvFreeRlmtMbuf(pAC, IoC, pMb); | ||
922 | return; | ||
923 | } | ||
924 | else if (SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->SrcAddr)) { | ||
925 | |||
926 | /* | ||
927 | * Was sent by same port (may happen during port switching | ||
928 | * or in case of duplicate MAC addresses). | ||
929 | */ | ||
930 | |||
931 | /* | ||
932 | * Check for duplicate address here: | ||
933 | * If Packet.Random != My.Random => DupAddr. | ||
934 | */ | ||
935 | for (i = 3; i >= 0; i--) { | ||
936 | if (pRPort->Random[i] != pRPacket->Random[i]) { | ||
937 | break; | ||
938 | } | ||
939 | } | ||
940 | |||
941 | /* | ||
942 | * CAUTION: Do not check for duplicate MAC address in RLMT Alive Reply | ||
943 | * packets (they have the LLC_COMMAND_RESPONSE_BIT set in | ||
944 | * pRPacket->SSap). | ||
945 | */ | ||
946 | if (i >= 0 && pRPacket->DSap == SK_RLMT_DSAP && | ||
947 | pRPacket->Ctrl == SK_RLMT_CTRL && | ||
948 | pRPacket->SSap == SK_RLMT_SSAP && | ||
949 | pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 && | ||
950 | pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 && | ||
951 | pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 && | ||
952 | pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 && | ||
953 | pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 && | ||
954 | pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 && | ||
955 | pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) { | ||
956 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, | ||
957 | ("SkRlmtPacketReceive: Duplicate MAC Address.\n")) | ||
958 | |||
959 | /* Error Log entry. */ | ||
960 | SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E006, SKERR_RLMT_E006_MSG); | ||
961 | } | ||
962 | else { | ||
963 | /* Simply trash it. */ | ||
964 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, | ||
965 | ("SkRlmtPacketReceive: Sent by me.\n")) | ||
966 | } | ||
967 | |||
968 | SkDrvFreeRlmtMbuf(pAC, IoC, pMb); | ||
969 | return; | ||
970 | } | ||
971 | |||
972 | /* Check SuspectTx entries. */ | ||
973 | if (pRPort->PortsSuspect > 0) { | ||
974 | for (j = 0; j < pRPort->PortsChecked; j++) { | ||
975 | if (pRPort->PortCheck[j].SuspectTx && | ||
976 | SK_ADDR_EQUAL( | ||
977 | pRPacket->SrcAddr, pRPort->PortCheck[j].CheckAddr.a)) { | ||
978 | pRPort->PortCheck[j].SuspectTx = SK_FALSE; | ||
979 | pRPort->PortsSuspect--; | ||
980 | break; | ||
981 | } | ||
982 | } | ||
983 | } | ||
984 | |||
985 | /* Determine type of packet. */ | ||
986 | if (pRPacket->DSap == SK_RLMT_DSAP && | ||
987 | pRPacket->Ctrl == SK_RLMT_CTRL && | ||
988 | (pRPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SSAP && | ||
989 | pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 && | ||
990 | pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 && | ||
991 | pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 && | ||
992 | pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 && | ||
993 | pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 && | ||
994 | pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 && | ||
995 | pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) { | ||
996 | |||
997 | /* It's an RLMT packet. */ | ||
998 | PacketType = (SK_U16)((pRPacket->RlmtPacketType[0] << 8) | | ||
999 | pRPacket->RlmtPacketType[1]); | ||
1000 | |||
1001 | switch (PacketType) { | ||
1002 | case SK_PACKET_ANNOUNCE: /* Not yet used. */ | ||
1003 | #if 0 | ||
1004 | /* Build the check chain. */ | ||
1005 | SkRlmtBuildCheckChain(pAC); | ||
1006 | #endif /* 0 */ | ||
1007 | |||
1008 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, | ||
1009 | ("SkRlmtPacketReceive: Announce.\n")) | ||
1010 | |||
1011 | SkDrvFreeRlmtMbuf(pAC, IoC, pMb); | ||
1012 | break; | ||
1013 | |||
1014 | case SK_PACKET_ALIVE: | ||
1015 | if (pRPacket->SSap & LLC_COMMAND_RESPONSE_BIT) { | ||
1016 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, | ||
1017 | ("SkRlmtPacketReceive: Alive Reply.\n")) | ||
1018 | |||
1019 | if (!(pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_LLC) || | ||
1020 | SK_ADDR_EQUAL( | ||
1021 | pRPacket->DstAddr, pAPort->CurrentMacAddress.a)) { | ||
1022 | /* Obviously we could send something. */ | ||
1023 | if (pRPort->CheckingState & SK_RLMT_PCS_TX) { | ||
1024 | pRPort->CheckingState &= ~SK_RLMT_PCS_TX; | ||
1025 | SkTimerStop(pAC, IoC, &pRPort->DownTxTimer); | ||
1026 | } | ||
1027 | |||
1028 | if ((pRPort->PortState == SK_RLMT_PS_DOWN) && | ||
1029 | !(pRPort->CheckingState & SK_RLMT_PCS_RX)) { | ||
1030 | pRPort->PortState = SK_RLMT_PS_GOING_UP; | ||
1031 | pRPort->GuTimeStamp = SkOsGetTime(pAC); | ||
1032 | |||
1033 | SkTimerStop(pAC, IoC, &pRPort->DownTxTimer); | ||
1034 | |||
1035 | Para.Para32[0] = PortNumber; | ||
1036 | Para.Para32[1] = (SK_U32)-1; | ||
1037 | SkTimerStart(pAC, IoC, &pRPort->UpTimer, | ||
1038 | SK_RLMT_PORTUP_TIM_VAL, SKGE_RLMT, | ||
1039 | SK_RLMT_PORTUP_TIM, Para); | ||
1040 | } | ||
1041 | } | ||
1042 | |||
1043 | /* Mark sending port as alive? */ | ||
1044 | SkDrvFreeRlmtMbuf(pAC, IoC, pMb); | ||
1045 | } | ||
1046 | else { /* Alive Request Packet. */ | ||
1047 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, | ||
1048 | ("SkRlmtPacketReceive: Alive Request.\n")) | ||
1049 | |||
1050 | pRPort->RxHelloCts++; | ||
1051 | |||
1052 | /* Answer. */ | ||
1053 | for (i = 0; i < SK_MAC_ADDR_LEN; i++) { | ||
1054 | pRPacket->DstAddr[i] = pRPacket->SrcAddr[i]; | ||
1055 | pRPacket->SrcAddr[i] = | ||
1056 | pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i]; | ||
1057 | } | ||
1058 | pRPacket->SSap |= LLC_COMMAND_RESPONSE_BIT; | ||
1059 | |||
1060 | Para.pParaPtr = pMb; | ||
1061 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); | ||
1062 | } | ||
1063 | break; | ||
1064 | |||
1065 | case SK_PACKET_CHECK_TX: | ||
1066 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, | ||
1067 | ("SkRlmtPacketReceive: Check your tx line.\n")) | ||
1068 | |||
1069 | /* A port checking us requests us to check our tx line. */ | ||
1070 | pRPort->CheckingState |= SK_RLMT_PCS_TX; | ||
1071 | |||
1072 | /* Start PortDownTx timer. */ | ||
1073 | Para.Para32[0] = PortNumber; | ||
1074 | Para.Para32[1] = (SK_U32)-1; | ||
1075 | SkTimerStart(pAC, IoC, &pRPort->DownTxTimer, | ||
1076 | SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT, | ||
1077 | SK_RLMT_PORTDOWN_TX_TIM, Para); | ||
1078 | |||
1079 | SkDrvFreeRlmtMbuf(pAC, IoC, pMb); | ||
1080 | |||
1081 | if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber, | ||
1082 | SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress, | ||
1083 | &SkRlmtMcAddr)) != NULL) { | ||
1084 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); | ||
1085 | } | ||
1086 | break; | ||
1087 | |||
1088 | case SK_PACKET_ADDR_CHANGED: | ||
1089 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, | ||
1090 | ("SkRlmtPacketReceive: Address Change.\n")) | ||
1091 | |||
1092 | /* Build the check chain. */ | ||
1093 | SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber); | ||
1094 | SkDrvFreeRlmtMbuf(pAC, IoC, pMb); | ||
1095 | break; | ||
1096 | |||
1097 | default: | ||
1098 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, | ||
1099 | ("SkRlmtPacketReceive: Unknown RLMT packet.\n")) | ||
1100 | |||
1101 | /* RA;:;: ??? */ | ||
1102 | SkDrvFreeRlmtMbuf(pAC, IoC, pMb); | ||
1103 | } | ||
1104 | } | ||
1105 | else if (pSPacket->DSap == SK_RLMT_SPT_DSAP && | ||
1106 | pSPacket->Ctrl == SK_RLMT_SPT_CTRL && | ||
1107 | (pSPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SPT_SSAP) { | ||
1108 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, | ||
1109 | ("SkRlmtPacketReceive: BPDU Packet.\n")) | ||
1110 | |||
1111 | /* Spanning Tree packet. */ | ||
1112 | pRPort->RxSpHelloCts++; | ||
1113 | |||
1114 | if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pAC->Addr.Net[pAC->Rlmt. | ||
1115 | Port[PortNumber].Net->NetNumber].CurrentMacAddress.a[0])) { | ||
1116 | /* | ||
1117 | * Check segmentation if a new root bridge is set and | ||
1118 | * the segmentation check is not currently running. | ||
1119 | */ | ||
1120 | if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pRPort->Root.Id[2]) && | ||
1121 | (pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) && | ||
1122 | (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) | ||
1123 | != 0 && (pAC->Rlmt.Port[PortNumber].Net->CheckingState & | ||
1124 | SK_RLMT_RCS_SEG) == 0) { | ||
1125 | pAC->Rlmt.Port[PortNumber].Net->CheckingState |= | ||
1126 | SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG; | ||
1127 | } | ||
1128 | |||
1129 | /* Store tree view of this port. */ | ||
1130 | for (i = 0; i < 8; i++) { | ||
1131 | pRPort->Root.Id[i] = pSPacket->RootId[i]; | ||
1132 | } | ||
1133 | pRPort->RootIdSet = SK_TRUE; | ||
1134 | |||
1135 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP, | ||
1136 | ("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n", | ||
1137 | PortNumber, | ||
1138 | pRPort->Root.Id[0], pRPort->Root.Id[1], | ||
1139 | pRPort->Root.Id[2], pRPort->Root.Id[3], | ||
1140 | pRPort->Root.Id[4], pRPort->Root.Id[5], | ||
1141 | pRPort->Root.Id[6], pRPort->Root.Id[7])) | ||
1142 | } | ||
1143 | |||
1144 | SkDrvFreeRlmtMbuf(pAC, IoC, pMb); | ||
1145 | if ((pAC->Rlmt.Port[PortNumber].Net->CheckingState & | ||
1146 | SK_RLMT_RCS_REPORT_SEG) != 0) { | ||
1147 | SkRlmtCheckSeg(pAC, IoC, pAC->Rlmt.Port[PortNumber].Net->NetNumber); | ||
1148 | } | ||
1149 | } | ||
1150 | else { | ||
1151 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, | ||
1152 | ("SkRlmtPacketReceive: Unknown Packet Type.\n")) | ||
1153 | |||
1154 | /* Unknown packet. */ | ||
1155 | SkDrvFreeRlmtMbuf(pAC, IoC, pMb); | ||
1156 | } | ||
1157 | return; | ||
1158 | } /* SkRlmtPacketReceive */ | ||
1159 | |||
1160 | |||
1161 | /****************************************************************************** | ||
1162 | * | ||
1163 | * SkRlmtCheckPort - check if a port works | ||
1164 | * | ||
1165 | * Description: | ||
1166 | * This routine checks if a port whose link is up received something | ||
1167 | * and if it seems to transmit successfully. | ||
1168 | * | ||
1169 | * # PortState: PsInit, PsLinkDown, PsDown, PsGoingUp, PsUp | ||
1170 | * # PortCheckingState (Bitfield): ChkTx, ChkRx, ChkSeg | ||
1171 | * # RlmtCheckingState (Bitfield): ChkSeg, StartChkSeg, ReportSeg | ||
1172 | * | ||
1173 | * if (Rx - RxBpdu == 0) { # No rx. | ||
1174 | * if (state == PsUp) { | ||
1175 | * PortCheckingState |= ChkRx | ||
1176 | * } | ||
1177 | * if (ModeCheckSeg && (Timeout == | ||
1178 | * TO_SHORTEN(RLMT_DEFAULT_TIMEOUT))) { | ||
1179 | * RlmtCheckingState |= ChkSeg) | ||
1180 | * PortCheckingState |= ChkSeg | ||
1181 | * } | ||
1182 | * NewTimeout = TO_SHORTEN(Timeout) | ||
1183 | * if (NewTimeout < RLMT_MIN_TIMEOUT) { | ||
1184 | * NewTimeout = RLMT_MIN_TIMEOUT | ||
1185 | * PortState = PsDown | ||
1186 | * ... | ||
1187 | * } | ||
1188 | * } | ||
1189 | * else { # something was received | ||
1190 | * # Set counter to 0 at LinkDown? | ||
1191 | * # No - rx may be reported after LinkDown ??? | ||
1192 | * PortCheckingState &= ~ChkRx | ||
1193 | * NewTimeout = RLMT_DEFAULT_TIMEOUT | ||
1194 | * if (RxAck == 0) { | ||
1195 | * possible reasons: | ||
1196 | * is my tx line bad? -- | ||
1197 | * send RLMT multicast and report | ||
1198 | * back internally? (only possible | ||
1199 | * between ports on same adapter) | ||
1200 | * } | ||
1201 | * if (RxChk == 0) { | ||
1202 | * possible reasons: | ||
1203 | * - tx line of port set to check me | ||
1204 | * maybe bad | ||
1205 | * - no other port/adapter available or set | ||
1206 | * to check me | ||
1207 | * - adapter checking me has a longer | ||
1208 | * timeout | ||
1209 | * ??? anything that can be done here? | ||
1210 | * } | ||
1211 | * } | ||
1212 | * | ||
1213 | * Context: | ||
1214 | * runtime, pageable? | ||
1215 | * | ||
1216 | * Returns: | ||
1217 | * New timeout value. | ||
1218 | */ | ||
1219 | RLMT_STATIC SK_U32 SkRlmtCheckPort( | ||
1220 | SK_AC *pAC, /* Adapter Context */ | ||
1221 | SK_IOC IoC, /* I/O Context */ | ||
1222 | SK_U32 PortNumber) /* Port to check */ | ||
1223 | { | ||
1224 | unsigned i; | ||
1225 | SK_U32 NewTimeout; | ||
1226 | SK_RLMT_PORT *pRPort; | ||
1227 | SK_EVPARA Para; | ||
1228 | |||
1229 | pRPort = &pAC->Rlmt.Port[PortNumber]; | ||
1230 | |||
1231 | if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) == 0) { | ||
1232 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
1233 | ("SkRlmtCheckPort %d: No (%d) receives in last time slot.\n", | ||
1234 | PortNumber, pRPort->PacketsPerTimeSlot)) | ||
1235 | |||
1236 | /* | ||
1237 | * Check segmentation if there was no receive at least twice | ||
1238 | * in a row (PortNoRx is already set) and the segmentation | ||
1239 | * check is not currently running. | ||
1240 | */ | ||
1241 | |||
1242 | if (pRPort->PortNoRx && (pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) && | ||
1243 | (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) && | ||
1244 | !(pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEG)) { | ||
1245 | pAC->Rlmt.Port[PortNumber].Net->CheckingState |= | ||
1246 | SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG; | ||
1247 | } | ||
1248 | |||
1249 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
1250 | ("SkRlmtCheckPort: PortsSuspect %d, PcsRx %d.\n", | ||
1251 | pRPort->PortsSuspect, pRPort->CheckingState & SK_RLMT_PCS_RX)) | ||
1252 | |||
1253 | if (pRPort->PortState != SK_RLMT_PS_DOWN) { | ||
1254 | NewTimeout = TO_SHORTEN(pAC->Rlmt.Port[PortNumber].Net->TimeoutValue); | ||
1255 | if (NewTimeout < SK_RLMT_MIN_TO_VAL) { | ||
1256 | NewTimeout = SK_RLMT_MIN_TO_VAL; | ||
1257 | } | ||
1258 | |||
1259 | if (!(pRPort->CheckingState & SK_RLMT_PCS_RX)) { | ||
1260 | Para.Para32[0] = PortNumber; | ||
1261 | pRPort->CheckingState |= SK_RLMT_PCS_RX; | ||
1262 | |||
1263 | /* | ||
1264 | * What shall we do if the port checked by this one receives | ||
1265 | * our request frames? What's bad - our rx line or his tx line? | ||
1266 | */ | ||
1267 | Para.Para32[1] = (SK_U32)-1; | ||
1268 | SkTimerStart(pAC, IoC, &pRPort->DownRxTimer, | ||
1269 | SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT, | ||
1270 | SK_RLMT_PORTDOWN_RX_TIM, Para); | ||
1271 | |||
1272 | for (i = 0; i < pRPort->PortsChecked; i++) { | ||
1273 | if (pRPort->PortCheck[i].SuspectTx) { | ||
1274 | continue; | ||
1275 | } | ||
1276 | pRPort->PortCheck[i].SuspectTx = SK_TRUE; | ||
1277 | pRPort->PortsSuspect++; | ||
1278 | if ((Para.pParaPtr = | ||
1279 | SkRlmtBuildPacket(pAC, IoC, PortNumber, SK_PACKET_CHECK_TX, | ||
1280 | &pAC->Addr.Port[PortNumber].CurrentMacAddress, | ||
1281 | &pRPort->PortCheck[i].CheckAddr)) != NULL) { | ||
1282 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); | ||
1283 | } | ||
1284 | } | ||
1285 | } | ||
1286 | } | ||
1287 | else { /* PortDown -- or all partners suspect. */ | ||
1288 | NewTimeout = SK_RLMT_DEF_TO_VAL; | ||
1289 | } | ||
1290 | pRPort->PortNoRx = SK_TRUE; | ||
1291 | } | ||
1292 | else { /* A non-BPDU packet was received. */ | ||
1293 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
1294 | ("SkRlmtCheckPort %d: %d (%d) receives in last time slot.\n", | ||
1295 | PortNumber, | ||
1296 | pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot, | ||
1297 | pRPort->PacketsPerTimeSlot)) | ||
1298 | |||
1299 | SkRlmtPortReceives(pAC, IoC, PortNumber); | ||
1300 | if (pAC->Rlmt.CheckSwitch) { | ||
1301 | SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber); | ||
1302 | } | ||
1303 | |||
1304 | NewTimeout = SK_RLMT_DEF_TO_VAL; | ||
1305 | } | ||
1306 | |||
1307 | return (NewTimeout); | ||
1308 | } /* SkRlmtCheckPort */ | ||
1309 | |||
1310 | |||
1311 | /****************************************************************************** | ||
1312 | * | ||
1313 | * SkRlmtSelectBcRx - select new active port, criteria 1 (CLP) | ||
1314 | * | ||
1315 | * Description: | ||
1316 | * This routine selects the port that received a broadcast frame | ||
1317 | * substantially later than all other ports. | ||
1318 | * | ||
1319 | * Context: | ||
1320 | * runtime, pageable? | ||
1321 | * | ||
1322 | * Returns: | ||
1323 | * SK_BOOL | ||
1324 | */ | ||
1325 | RLMT_STATIC SK_BOOL SkRlmtSelectBcRx( | ||
1326 | SK_AC *pAC, /* Adapter Context */ | ||
1327 | SK_IOC IoC, /* I/O Context */ | ||
1328 | SK_U32 Active, /* Active port */ | ||
1329 | SK_U32 PrefPort, /* Preferred port */ | ||
1330 | SK_U32 *pSelect) /* New active port */ | ||
1331 | { | ||
1332 | SK_U64 BcTimeStamp; | ||
1333 | SK_U32 i; | ||
1334 | SK_BOOL PortFound; | ||
1335 | |||
1336 | BcTimeStamp = 0; /* Not totally necessary, but feeling better. */ | ||
1337 | PortFound = SK_FALSE; | ||
1338 | |||
1339 | /* Select port with the latest TimeStamp. */ | ||
1340 | for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { | ||
1341 | |||
1342 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
1343 | ("TimeStamp Port %d (Down: %d, NoRx: %d): %08x %08x.\n", | ||
1344 | i, | ||
1345 | pAC->Rlmt.Port[i].PortDown, pAC->Rlmt.Port[i].PortNoRx, | ||
1346 | *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_HI32), | ||
1347 | *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_LO32))) | ||
1348 | |||
1349 | if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx) { | ||
1350 | if (!PortFound || pAC->Rlmt.Port[i].BcTimeStamp > BcTimeStamp) { | ||
1351 | BcTimeStamp = pAC->Rlmt.Port[i].BcTimeStamp; | ||
1352 | *pSelect = i; | ||
1353 | PortFound = SK_TRUE; | ||
1354 | } | ||
1355 | } | ||
1356 | } | ||
1357 | |||
1358 | if (PortFound) { | ||
1359 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
1360 | ("Port %d received the last broadcast.\n", *pSelect)) | ||
1361 | |||
1362 | /* Look if another port's time stamp is similar. */ | ||
1363 | for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { | ||
1364 | if (i == *pSelect) { | ||
1365 | continue; | ||
1366 | } | ||
1367 | if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx && | ||
1368 | (pAC->Rlmt.Port[i].BcTimeStamp > | ||
1369 | BcTimeStamp - SK_RLMT_BC_DELTA || | ||
1370 | pAC->Rlmt.Port[i].BcTimeStamp + | ||
1371 | SK_RLMT_BC_DELTA > BcTimeStamp)) { | ||
1372 | PortFound = SK_FALSE; | ||
1373 | |||
1374 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
1375 | ("Port %d received a broadcast at a similar time.\n", i)) | ||
1376 | break; | ||
1377 | } | ||
1378 | } | ||
1379 | } | ||
1380 | |||
1381 | #ifdef DEBUG | ||
1382 | if (PortFound) { | ||
1383 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
1384 | ("SK_RLMT_SELECT_BCRX found Port %d receiving the substantially " | ||
1385 | "latest broadcast (%u).\n", | ||
1386 | *pSelect, | ||
1387 | BcTimeStamp - pAC->Rlmt.Port[1 - *pSelect].BcTimeStamp)) | ||
1388 | } | ||
1389 | #endif /* DEBUG */ | ||
1390 | |||
1391 | return (PortFound); | ||
1392 | } /* SkRlmtSelectBcRx */ | ||
1393 | |||
1394 | |||
1395 | /****************************************************************************** | ||
1396 | * | ||
1397 | * SkRlmtSelectNotSuspect - select new active port, criteria 2 (CLP) | ||
1398 | * | ||
1399 | * Description: | ||
1400 | * This routine selects a good port (it is PortUp && !SuspectRx). | ||
1401 | * | ||
1402 | * Context: | ||
1403 | * runtime, pageable? | ||
1404 | * | ||
1405 | * Returns: | ||
1406 | * SK_BOOL | ||
1407 | */ | ||
1408 | RLMT_STATIC SK_BOOL SkRlmtSelectNotSuspect( | ||
1409 | SK_AC *pAC, /* Adapter Context */ | ||
1410 | SK_IOC IoC, /* I/O Context */ | ||
1411 | SK_U32 Active, /* Active port */ | ||
1412 | SK_U32 PrefPort, /* Preferred port */ | ||
1413 | SK_U32 *pSelect) /* New active port */ | ||
1414 | { | ||
1415 | SK_U32 i; | ||
1416 | SK_BOOL PortFound; | ||
1417 | |||
1418 | PortFound = SK_FALSE; | ||
1419 | |||
1420 | /* Select first port that is PortUp && !SuspectRx. */ | ||
1421 | for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { | ||
1422 | if (!pAC->Rlmt.Port[i].PortDown && | ||
1423 | !(pAC->Rlmt.Port[i].CheckingState & SK_RLMT_PCS_RX)) { | ||
1424 | *pSelect = i; | ||
1425 | if (!pAC->Rlmt.Port[Active].PortDown && | ||
1426 | !(pAC->Rlmt.Port[Active].CheckingState & SK_RLMT_PCS_RX)) { | ||
1427 | *pSelect = Active; | ||
1428 | } | ||
1429 | if (!pAC->Rlmt.Port[PrefPort].PortDown && | ||
1430 | !(pAC->Rlmt.Port[PrefPort].CheckingState & SK_RLMT_PCS_RX)) { | ||
1431 | *pSelect = PrefPort; | ||
1432 | } | ||
1433 | PortFound = SK_TRUE; | ||
1434 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
1435 | ("SK_RLMT_SELECT_NOTSUSPECT found Port %d up and not check RX.\n", | ||
1436 | *pSelect)) | ||
1437 | break; | ||
1438 | } | ||
1439 | } | ||
1440 | return (PortFound); | ||
1441 | } /* SkRlmtSelectNotSuspect */ | ||
1442 | |||
1443 | |||
1444 | /****************************************************************************** | ||
1445 | * | ||
1446 | * SkRlmtSelectUp - select new active port, criteria 3, 4 (CLP) | ||
1447 | * | ||
1448 | * Description: | ||
1449 | * This routine selects a port that is up. | ||
1450 | * | ||
1451 | * Context: | ||
1452 | * runtime, pageable? | ||
1453 | * | ||
1454 | * Returns: | ||
1455 | * SK_BOOL | ||
1456 | */ | ||
1457 | RLMT_STATIC SK_BOOL SkRlmtSelectUp( | ||
1458 | SK_AC *pAC, /* Adapter Context */ | ||
1459 | SK_IOC IoC, /* I/O Context */ | ||
1460 | SK_U32 Active, /* Active port */ | ||
1461 | SK_U32 PrefPort, /* Preferred port */ | ||
1462 | SK_U32 *pSelect, /* New active port */ | ||
1463 | SK_BOOL AutoNegDone) /* Successfully auto-negotiated? */ | ||
1464 | { | ||
1465 | SK_U32 i; | ||
1466 | SK_BOOL PortFound; | ||
1467 | |||
1468 | PortFound = SK_FALSE; | ||
1469 | |||
1470 | /* Select first port that is PortUp. */ | ||
1471 | for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { | ||
1472 | if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_UP && | ||
1473 | pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) { | ||
1474 | *pSelect = i; | ||
1475 | if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_UP && | ||
1476 | pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) { | ||
1477 | *pSelect = Active; | ||
1478 | } | ||
1479 | if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_UP && | ||
1480 | pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) { | ||
1481 | *pSelect = PrefPort; | ||
1482 | } | ||
1483 | PortFound = SK_TRUE; | ||
1484 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
1485 | ("SK_RLMT_SELECT_UP found Port %d up.\n", *pSelect)) | ||
1486 | break; | ||
1487 | } | ||
1488 | } | ||
1489 | return (PortFound); | ||
1490 | } /* SkRlmtSelectUp */ | ||
1491 | |||
1492 | |||
1493 | /****************************************************************************** | ||
1494 | * | ||
1495 | * SkRlmtSelectGoingUp - select new active port, criteria 5, 6 (CLP) | ||
1496 | * | ||
1497 | * Description: | ||
1498 | * This routine selects the port that is going up for the longest time. | ||
1499 | * | ||
1500 | * Context: | ||
1501 | * runtime, pageable? | ||
1502 | * | ||
1503 | * Returns: | ||
1504 | * SK_BOOL | ||
1505 | */ | ||
1506 | RLMT_STATIC SK_BOOL SkRlmtSelectGoingUp( | ||
1507 | SK_AC *pAC, /* Adapter Context */ | ||
1508 | SK_IOC IoC, /* I/O Context */ | ||
1509 | SK_U32 Active, /* Active port */ | ||
1510 | SK_U32 PrefPort, /* Preferred port */ | ||
1511 | SK_U32 *pSelect, /* New active port */ | ||
1512 | SK_BOOL AutoNegDone) /* Successfully auto-negotiated? */ | ||
1513 | { | ||
1514 | SK_U64 GuTimeStamp; | ||
1515 | SK_U32 i; | ||
1516 | SK_BOOL PortFound; | ||
1517 | |||
1518 | GuTimeStamp = 0; | ||
1519 | PortFound = SK_FALSE; | ||
1520 | |||
1521 | /* Select port that is PortGoingUp for the longest time. */ | ||
1522 | for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { | ||
1523 | if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP && | ||
1524 | pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) { | ||
1525 | GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp; | ||
1526 | *pSelect = i; | ||
1527 | PortFound = SK_TRUE; | ||
1528 | break; | ||
1529 | } | ||
1530 | } | ||
1531 | |||
1532 | if (!PortFound) { | ||
1533 | return (SK_FALSE); | ||
1534 | } | ||
1535 | |||
1536 | for (i = *pSelect + 1; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { | ||
1537 | if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP && | ||
1538 | pAC->Rlmt.Port[i].GuTimeStamp < GuTimeStamp && | ||
1539 | pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) { | ||
1540 | GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp; | ||
1541 | *pSelect = i; | ||
1542 | } | ||
1543 | } | ||
1544 | |||
1545 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
1546 | ("SK_RLMT_SELECT_GOINGUP found Port %d going up.\n", *pSelect)) | ||
1547 | return (SK_TRUE); | ||
1548 | } /* SkRlmtSelectGoingUp */ | ||
1549 | |||
1550 | |||
1551 | /****************************************************************************** | ||
1552 | * | ||
1553 | * SkRlmtSelectDown - select new active port, criteria 7, 8 (CLP) | ||
1554 | * | ||
1555 | * Description: | ||
1556 | * This routine selects a port that is down. | ||
1557 | * | ||
1558 | * Context: | ||
1559 | * runtime, pageable? | ||
1560 | * | ||
1561 | * Returns: | ||
1562 | * SK_BOOL | ||
1563 | */ | ||
1564 | RLMT_STATIC SK_BOOL SkRlmtSelectDown( | ||
1565 | SK_AC *pAC, /* Adapter Context */ | ||
1566 | SK_IOC IoC, /* I/O Context */ | ||
1567 | SK_U32 Active, /* Active port */ | ||
1568 | SK_U32 PrefPort, /* Preferred port */ | ||
1569 | SK_U32 *pSelect, /* New active port */ | ||
1570 | SK_BOOL AutoNegDone) /* Successfully auto-negotiated? */ | ||
1571 | { | ||
1572 | SK_U32 i; | ||
1573 | SK_BOOL PortFound; | ||
1574 | |||
1575 | PortFound = SK_FALSE; | ||
1576 | |||
1577 | /* Select first port that is PortDown. */ | ||
1578 | for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { | ||
1579 | if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_DOWN && | ||
1580 | pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) { | ||
1581 | *pSelect = i; | ||
1582 | if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_DOWN && | ||
1583 | pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) { | ||
1584 | *pSelect = Active; | ||
1585 | } | ||
1586 | if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_DOWN && | ||
1587 | pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) { | ||
1588 | *pSelect = PrefPort; | ||
1589 | } | ||
1590 | PortFound = SK_TRUE; | ||
1591 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
1592 | ("SK_RLMT_SELECT_DOWN found Port %d down.\n", *pSelect)) | ||
1593 | break; | ||
1594 | } | ||
1595 | } | ||
1596 | return (PortFound); | ||
1597 | } /* SkRlmtSelectDown */ | ||
1598 | |||
1599 | |||
1600 | /****************************************************************************** | ||
1601 | * | ||
1602 | * SkRlmtCheckSwitch - select new active port and switch to it | ||
1603 | * | ||
1604 | * Description: | ||
1605 | * This routine decides which port should be the active one and queues | ||
1606 | * port switching if necessary. | ||
1607 | * | ||
1608 | * Context: | ||
1609 | * runtime, pageable? | ||
1610 | * | ||
1611 | * Returns: | ||
1612 | * Nothing. | ||
1613 | */ | ||
1614 | RLMT_STATIC void SkRlmtCheckSwitch( | ||
1615 | SK_AC *pAC, /* Adapter Context */ | ||
1616 | SK_IOC IoC, /* I/O Context */ | ||
1617 | SK_U32 NetIdx) /* Net index */ | ||
1618 | { | ||
1619 | SK_EVPARA Para; | ||
1620 | SK_U32 Active; | ||
1621 | SK_U32 PrefPort; | ||
1622 | SK_U32 i; | ||
1623 | SK_BOOL PortFound; | ||
1624 | |||
1625 | Active = pAC->Rlmt.Net[NetIdx].ActivePort; /* Index of active port. */ | ||
1626 | PrefPort = pAC->Rlmt.Net[NetIdx].PrefPort; /* Index of preferred port. */ | ||
1627 | PortFound = SK_FALSE; | ||
1628 | pAC->Rlmt.CheckSwitch = SK_FALSE; | ||
1629 | |||
1630 | #if 0 /* RW 2001/10/18 - active port becomes always prefered one */ | ||
1631 | if (pAC->Rlmt.Net[NetIdx].Preference == 0xFFFFFFFF) { /* Automatic */ | ||
1632 | /* disable auto-fail back */ | ||
1633 | PrefPort = Active; | ||
1634 | } | ||
1635 | #endif | ||
1636 | |||
1637 | if (pAC->Rlmt.Net[NetIdx].LinksUp == 0) { | ||
1638 | /* Last link went down - shut down the net. */ | ||
1639 | pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_DOWN; | ||
1640 | Para.Para32[0] = SK_RLMT_NET_DOWN_TEMP; | ||
1641 | Para.Para32[1] = NetIdx; | ||
1642 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para); | ||
1643 | |||
1644 | Para.Para32[0] = pAC->Rlmt.Net[NetIdx]. | ||
1645 | Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber; | ||
1646 | Para.Para32[1] = NetIdx; | ||
1647 | SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para); | ||
1648 | return; | ||
1649 | } /* pAC->Rlmt.LinksUp == 0 */ | ||
1650 | else if (pAC->Rlmt.Net[NetIdx].LinksUp == 1 && | ||
1651 | pAC->Rlmt.Net[NetIdx].RlmtState == SK_RLMT_RS_NET_DOWN) { | ||
1652 | /* First link came up - get the net up. */ | ||
1653 | pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_UP; | ||
1654 | |||
1655 | /* | ||
1656 | * If pAC->Rlmt.ActivePort != Para.Para32[0], | ||
1657 | * the DRV switches to the port that came up. | ||
1658 | */ | ||
1659 | for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) { | ||
1660 | if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) { | ||
1661 | if (!pAC->Rlmt.Net[NetIdx].Port[Active]->LinkDown) { | ||
1662 | i = Active; | ||
1663 | } | ||
1664 | if (!pAC->Rlmt.Net[NetIdx].Port[PrefPort]->LinkDown) { | ||
1665 | i = PrefPort; | ||
1666 | } | ||
1667 | PortFound = SK_TRUE; | ||
1668 | break; | ||
1669 | } | ||
1670 | } | ||
1671 | |||
1672 | if (PortFound) { | ||
1673 | Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber; | ||
1674 | Para.Para32[1] = NetIdx; | ||
1675 | SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para); | ||
1676 | |||
1677 | pAC->Rlmt.Net[NetIdx].ActivePort = i; | ||
1678 | Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber; | ||
1679 | Para.Para32[1] = NetIdx; | ||
1680 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_UP, Para); | ||
1681 | |||
1682 | if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 && | ||
1683 | (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, | ||
1684 | pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber, | ||
1685 | SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx]. | ||
1686 | CurrentMacAddress, &SkRlmtMcAddr)) != NULL) { | ||
1687 | /* | ||
1688 | * Send announce packet to RLMT multicast address to force | ||
1689 | * switches to learn the new location of the logical MAC address. | ||
1690 | */ | ||
1691 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); | ||
1692 | } | ||
1693 | } | ||
1694 | else { | ||
1695 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E007, SKERR_RLMT_E007_MSG); | ||
1696 | } | ||
1697 | |||
1698 | return; | ||
1699 | } /* LinksUp == 1 && RlmtState == SK_RLMT_RS_NET_DOWN */ | ||
1700 | else { /* Cannot be reached in dual-net mode. */ | ||
1701 | Para.Para32[0] = Active; | ||
1702 | |||
1703 | /* | ||
1704 | * Preselection: | ||
1705 | * If RLMT Mode != CheckLinkState | ||
1706 | * select port that received a broadcast frame substantially later | ||
1707 | * than all other ports | ||
1708 | * else select first port that is not SuspectRx | ||
1709 | * else select first port that is PortUp | ||
1710 | * else select port that is PortGoingUp for the longest time | ||
1711 | * else select first port that is PortDown | ||
1712 | * else stop. | ||
1713 | * | ||
1714 | * For the preselected port: | ||
1715 | * If ActivePort is equal in quality, select ActivePort. | ||
1716 | * | ||
1717 | * If PrefPort is equal in quality, select PrefPort. | ||
1718 | * | ||
1719 | * If ActivePort != SelectedPort, | ||
1720 | * If old ActivePort is LinkDown, | ||
1721 | * SwitchHard | ||
1722 | * else | ||
1723 | * SwitchSoft | ||
1724 | */ | ||
1725 | /* check of ChgBcPrio flag added */ | ||
1726 | if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) && | ||
1727 | (!pAC->Rlmt.Net[0].ChgBcPrio)) { | ||
1728 | |||
1729 | if (!PortFound) { | ||
1730 | PortFound = SkRlmtSelectBcRx( | ||
1731 | pAC, IoC, Active, PrefPort, &Para.Para32[1]); | ||
1732 | } | ||
1733 | |||
1734 | if (!PortFound) { | ||
1735 | PortFound = SkRlmtSelectNotSuspect( | ||
1736 | pAC, IoC, Active, PrefPort, &Para.Para32[1]); | ||
1737 | } | ||
1738 | } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */ | ||
1739 | |||
1740 | /* with changed priority for last broadcast received */ | ||
1741 | if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) && | ||
1742 | (pAC->Rlmt.Net[0].ChgBcPrio)) { | ||
1743 | if (!PortFound) { | ||
1744 | PortFound = SkRlmtSelectNotSuspect( | ||
1745 | pAC, IoC, Active, PrefPort, &Para.Para32[1]); | ||
1746 | } | ||
1747 | |||
1748 | if (!PortFound) { | ||
1749 | PortFound = SkRlmtSelectBcRx( | ||
1750 | pAC, IoC, Active, PrefPort, &Para.Para32[1]); | ||
1751 | } | ||
1752 | } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */ | ||
1753 | |||
1754 | if (!PortFound) { | ||
1755 | PortFound = SkRlmtSelectUp( | ||
1756 | pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS); | ||
1757 | } | ||
1758 | |||
1759 | if (!PortFound) { | ||
1760 | PortFound = SkRlmtSelectUp( | ||
1761 | pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED); | ||
1762 | } | ||
1763 | |||
1764 | if (!PortFound) { | ||
1765 | PortFound = SkRlmtSelectGoingUp( | ||
1766 | pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS); | ||
1767 | } | ||
1768 | |||
1769 | if (!PortFound) { | ||
1770 | PortFound = SkRlmtSelectGoingUp( | ||
1771 | pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED); | ||
1772 | } | ||
1773 | |||
1774 | if (pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) { | ||
1775 | if (!PortFound) { | ||
1776 | PortFound = SkRlmtSelectDown(pAC, IoC, | ||
1777 | Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS); | ||
1778 | } | ||
1779 | |||
1780 | if (!PortFound) { | ||
1781 | PortFound = SkRlmtSelectDown(pAC, IoC, | ||
1782 | Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED); | ||
1783 | } | ||
1784 | } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */ | ||
1785 | |||
1786 | if (PortFound) { | ||
1787 | |||
1788 | if (Para.Para32[1] != Active) { | ||
1789 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
1790 | ("Active: %d, Para1: %d.\n", Active, Para.Para32[1])) | ||
1791 | pAC->Rlmt.Net[NetIdx].ActivePort = Para.Para32[1]; | ||
1792 | Para.Para32[0] = pAC->Rlmt.Net[NetIdx]. | ||
1793 | Port[Para.Para32[0]]->PortNumber; | ||
1794 | Para.Para32[1] = pAC->Rlmt.Net[NetIdx]. | ||
1795 | Port[Para.Para32[1]]->PortNumber; | ||
1796 | SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[1], SK_LED_ACTIVE); | ||
1797 | if (pAC->Rlmt.Port[Active].LinkDown) { | ||
1798 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_HARD, Para); | ||
1799 | } | ||
1800 | else { | ||
1801 | SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY); | ||
1802 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_SOFT, Para); | ||
1803 | } | ||
1804 | Para.Para32[1] = NetIdx; | ||
1805 | Para.Para32[0] = | ||
1806 | pAC->Rlmt.Net[NetIdx].Port[Para.Para32[0]]->PortNumber; | ||
1807 | SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para); | ||
1808 | Para.Para32[0] = pAC->Rlmt.Net[NetIdx]. | ||
1809 | Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber; | ||
1810 | SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para); | ||
1811 | if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 && | ||
1812 | (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, Para.Para32[0], | ||
1813 | SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].CurrentMacAddress, | ||
1814 | &SkRlmtMcAddr)) != NULL) { | ||
1815 | /* | ||
1816 | * Send announce packet to RLMT multicast address to force | ||
1817 | * switches to learn the new location of the logical | ||
1818 | * MAC address. | ||
1819 | */ | ||
1820 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); | ||
1821 | } /* (Para.pParaPtr = SkRlmtBuildPacket(...)) != NULL */ | ||
1822 | } /* Para.Para32[1] != Active */ | ||
1823 | } /* PortFound */ | ||
1824 | else { | ||
1825 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E004, SKERR_RLMT_E004_MSG); | ||
1826 | } | ||
1827 | } /* LinksUp > 1 || LinksUp == 1 && RlmtState != SK_RLMT_RS_NET_DOWN */ | ||
1828 | return; | ||
1829 | } /* SkRlmtCheckSwitch */ | ||
1830 | |||
1831 | |||
1832 | /****************************************************************************** | ||
1833 | * | ||
1834 | * SkRlmtCheckSeg - Report if segmentation is detected | ||
1835 | * | ||
1836 | * Description: | ||
1837 | * This routine checks if the ports see different root bridges and reports | ||
1838 | * segmentation in such a case. | ||
1839 | * | ||
1840 | * Context: | ||
1841 | * runtime, pageable? | ||
1842 | * | ||
1843 | * Returns: | ||
1844 | * Nothing. | ||
1845 | */ | ||
1846 | RLMT_STATIC void SkRlmtCheckSeg( | ||
1847 | SK_AC *pAC, /* Adapter Context */ | ||
1848 | SK_IOC IoC, /* I/O Context */ | ||
1849 | SK_U32 NetIdx) /* Net number */ | ||
1850 | { | ||
1851 | SK_EVPARA Para; | ||
1852 | SK_RLMT_NET *pNet; | ||
1853 | SK_U32 i, j; | ||
1854 | SK_BOOL Equal; | ||
1855 | |||
1856 | pNet = &pAC->Rlmt.Net[NetIdx]; | ||
1857 | pNet->RootIdSet = SK_FALSE; | ||
1858 | Equal = SK_TRUE; | ||
1859 | |||
1860 | for (i = 0; i < pNet->NumPorts; i++) { | ||
1861 | if (pNet->Port[i]->LinkDown || !pNet->Port[i]->RootIdSet) { | ||
1862 | continue; | ||
1863 | } | ||
1864 | |||
1865 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP, | ||
1866 | ("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n", i, | ||
1867 | pNet->Port[i]->Root.Id[0], pNet->Port[i]->Root.Id[1], | ||
1868 | pNet->Port[i]->Root.Id[2], pNet->Port[i]->Root.Id[3], | ||
1869 | pNet->Port[i]->Root.Id[4], pNet->Port[i]->Root.Id[5], | ||
1870 | pNet->Port[i]->Root.Id[6], pNet->Port[i]->Root.Id[7])) | ||
1871 | |||
1872 | if (!pNet->RootIdSet) { | ||
1873 | pNet->Root = pNet->Port[i]->Root; | ||
1874 | pNet->RootIdSet = SK_TRUE; | ||
1875 | continue; | ||
1876 | } | ||
1877 | |||
1878 | for (j = 0; j < 8; j ++) { | ||
1879 | Equal &= pNet->Port[i]->Root.Id[j] == pNet->Root.Id[j]; | ||
1880 | if (!Equal) { | ||
1881 | break; | ||
1882 | } | ||
1883 | } | ||
1884 | |||
1885 | if (!Equal) { | ||
1886 | SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E005, SKERR_RLMT_E005_MSG); | ||
1887 | Para.Para32[0] = NetIdx; | ||
1888 | Para.Para32[1] = (SK_U32)-1; | ||
1889 | SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SEGMENTATION, Para); | ||
1890 | |||
1891 | pNet->CheckingState &= ~SK_RLMT_RCS_REPORT_SEG; | ||
1892 | |||
1893 | /* 2000-03-06 RA: New. */ | ||
1894 | Para.Para32[0] = NetIdx; | ||
1895 | Para.Para32[1] = (SK_U32)-1; | ||
1896 | SkTimerStart(pAC, IoC, &pNet->SegTimer, SK_RLMT_SEG_TO_VAL, | ||
1897 | SKGE_RLMT, SK_RLMT_SEG_TIM, Para); | ||
1898 | break; | ||
1899 | } | ||
1900 | } /* for (i = 0; i < pNet->NumPorts; i++) */ | ||
1901 | |||
1902 | /* 2000-03-06 RA: Moved here. */ | ||
1903 | /* Segmentation check not running anymore. */ | ||
1904 | pNet->CheckingState &= ~SK_RLMT_RCS_SEG; | ||
1905 | |||
1906 | } /* SkRlmtCheckSeg */ | ||
1907 | |||
1908 | |||
1909 | /****************************************************************************** | ||
1910 | * | ||
1911 | * SkRlmtPortStart - initialize port variables and start port | ||
1912 | * | ||
1913 | * Description: | ||
1914 | * This routine initializes a port's variables and issues a PORT_START | ||
1915 | * to the HWAC module. This handles retries if the start fails or the | ||
1916 | * link eventually goes down. | ||
1917 | * | ||
1918 | * Context: | ||
1919 | * runtime, pageable? | ||
1920 | * | ||
1921 | * Returns: | ||
1922 | * Nothing | ||
1923 | */ | ||
1924 | RLMT_STATIC void SkRlmtPortStart( | ||
1925 | SK_AC *pAC, /* Adapter Context */ | ||
1926 | SK_IOC IoC, /* I/O Context */ | ||
1927 | SK_U32 PortNumber) /* Port number */ | ||
1928 | { | ||
1929 | SK_EVPARA Para; | ||
1930 | |||
1931 | pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_LINK_DOWN; | ||
1932 | pAC->Rlmt.Port[PortNumber].PortStarted = SK_TRUE; | ||
1933 | pAC->Rlmt.Port[PortNumber].LinkDown = SK_TRUE; | ||
1934 | pAC->Rlmt.Port[PortNumber].PortDown = SK_TRUE; | ||
1935 | pAC->Rlmt.Port[PortNumber].CheckingState = 0; | ||
1936 | pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE; | ||
1937 | Para.Para32[0] = PortNumber; | ||
1938 | Para.Para32[1] = (SK_U32)-1; | ||
1939 | SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para); | ||
1940 | } /* SkRlmtPortStart */ | ||
1941 | |||
1942 | |||
1943 | /****************************************************************************** | ||
1944 | * | ||
1945 | * SkRlmtEvtPortStartTim - PORT_START_TIM | ||
1946 | * | ||
1947 | * Description: | ||
1948 | * This routine handles PORT_START_TIM events. | ||
1949 | * | ||
1950 | * Context: | ||
1951 | * runtime, pageable? | ||
1952 | * may be called after SK_INIT_IO | ||
1953 | * | ||
1954 | * Returns: | ||
1955 | * Nothing | ||
1956 | */ | ||
1957 | RLMT_STATIC void SkRlmtEvtPortStartTim( | ||
1958 | SK_AC *pAC, /* Adapter Context */ | ||
1959 | SK_IOC IoC, /* I/O Context */ | ||
1960 | SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */ | ||
1961 | { | ||
1962 | SK_U32 i; | ||
1963 | |||
1964 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
1965 | ("SK_RLMT_PORTSTART_TIMEOUT Port %d Event BEGIN.\n", Para.Para32[0])) | ||
1966 | |||
1967 | if (Para.Para32[1] != (SK_U32)-1) { | ||
1968 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
1969 | ("Bad Parameter.\n")) | ||
1970 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
1971 | ("SK_RLMT_PORTSTART_TIMEOUT Event EMPTY.\n")) | ||
1972 | return; | ||
1973 | } | ||
1974 | |||
1975 | /* | ||
1976 | * Used to start non-preferred ports if the preferred one | ||
1977 | * does not come up. | ||
1978 | * This timeout needs only be set when starting the first | ||
1979 | * (preferred) port. | ||
1980 | */ | ||
1981 | if (pAC->Rlmt.Port[Para.Para32[0]].LinkDown) { | ||
1982 | /* PORT_START failed. */ | ||
1983 | for (i = 0; i < pAC->Rlmt.Port[Para.Para32[0]].Net->NumPorts; i++) { | ||
1984 | if (!pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortStarted) { | ||
1985 | SkRlmtPortStart(pAC, IoC, | ||
1986 | pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortNumber); | ||
1987 | } | ||
1988 | } | ||
1989 | } | ||
1990 | |||
1991 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
1992 | ("SK_RLMT_PORTSTART_TIMEOUT Event END.\n")) | ||
1993 | } /* SkRlmtEvtPortStartTim */ | ||
1994 | |||
1995 | |||
1996 | /****************************************************************************** | ||
1997 | * | ||
1998 | * SkRlmtEvtLinkUp - LINK_UP | ||
1999 | * | ||
2000 | * Description: | ||
2001 | * This routine handles LLINK_UP events. | ||
2002 | * | ||
2003 | * Context: | ||
2004 | * runtime, pageable? | ||
2005 | * may be called after SK_INIT_IO | ||
2006 | * | ||
2007 | * Returns: | ||
2008 | * Nothing | ||
2009 | */ | ||
2010 | RLMT_STATIC void SkRlmtEvtLinkUp( | ||
2011 | SK_AC *pAC, /* Adapter Context */ | ||
2012 | SK_IOC IoC, /* I/O Context */ | ||
2013 | SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 Undefined */ | ||
2014 | { | ||
2015 | SK_U32 i; | ||
2016 | SK_RLMT_PORT *pRPort; | ||
2017 | SK_EVPARA Para2; | ||
2018 | |||
2019 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2020 | ("SK_RLMT_LINK_UP Port %d Event BEGIN.\n", Para.Para32[0])) | ||
2021 | |||
2022 | pRPort = &pAC->Rlmt.Port[Para.Para32[0]]; | ||
2023 | if (!pRPort->PortStarted) { | ||
2024 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E008, SKERR_RLMT_E008_MSG); | ||
2025 | |||
2026 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2027 | ("SK_RLMT_LINK_UP Event EMPTY.\n")) | ||
2028 | return; | ||
2029 | } | ||
2030 | |||
2031 | if (!pRPort->LinkDown) { | ||
2032 | /* RA;:;: Any better solution? */ | ||
2033 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2034 | ("SK_RLMT_LINK_UP Event EMPTY.\n")) | ||
2035 | return; | ||
2036 | } | ||
2037 | |||
2038 | SkTimerStop(pAC, IoC, &pRPort->UpTimer); | ||
2039 | SkTimerStop(pAC, IoC, &pRPort->DownRxTimer); | ||
2040 | SkTimerStop(pAC, IoC, &pRPort->DownTxTimer); | ||
2041 | |||
2042 | /* Do something if timer already fired? */ | ||
2043 | |||
2044 | pRPort->LinkDown = SK_FALSE; | ||
2045 | pRPort->PortState = SK_RLMT_PS_GOING_UP; | ||
2046 | pRPort->GuTimeStamp = SkOsGetTime(pAC); | ||
2047 | pRPort->BcTimeStamp = 0; | ||
2048 | pRPort->Net->LinksUp++; | ||
2049 | if (pRPort->Net->LinksUp == 1) { | ||
2050 | SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_ACTIVE); | ||
2051 | } | ||
2052 | else { | ||
2053 | SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY); | ||
2054 | } | ||
2055 | |||
2056 | for (i = 0; i < pRPort->Net->NumPorts; i++) { | ||
2057 | if (!pRPort->Net->Port[i]->PortStarted) { | ||
2058 | SkRlmtPortStart(pAC, IoC, pRPort->Net->Port[i]->PortNumber); | ||
2059 | } | ||
2060 | } | ||
2061 | |||
2062 | SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber); | ||
2063 | |||
2064 | if (pRPort->Net->LinksUp >= 2) { | ||
2065 | if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) { | ||
2066 | /* Build the check chain. */ | ||
2067 | SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber); | ||
2068 | } | ||
2069 | } | ||
2070 | |||
2071 | /* If the first link comes up, start the periodical RLMT timeout. */ | ||
2072 | if (pRPort->Net->NumPorts > 1 && pRPort->Net->LinksUp == 1 && | ||
2073 | (pRPort->Net->RlmtMode & SK_RLMT_CHECK_OTHERS) != 0) { | ||
2074 | Para2.Para32[0] = pRPort->Net->NetNumber; | ||
2075 | Para2.Para32[1] = (SK_U32)-1; | ||
2076 | SkTimerStart(pAC, IoC, &pRPort->Net->LocTimer, | ||
2077 | pRPort->Net->TimeoutValue, SKGE_RLMT, SK_RLMT_TIM, Para2); | ||
2078 | } | ||
2079 | |||
2080 | Para2 = Para; | ||
2081 | Para2.Para32[1] = (SK_U32)-1; | ||
2082 | SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL, | ||
2083 | SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para2); | ||
2084 | |||
2085 | /* Later: if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LOC_LINK) && */ | ||
2086 | if ((pRPort->Net->RlmtMode & SK_RLMT_TRANSPARENT) == 0 && | ||
2087 | (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LINK) != 0 && | ||
2088 | (Para2.pParaPtr = | ||
2089 | SkRlmtBuildPacket(pAC, IoC, Para.Para32[0], SK_PACKET_ANNOUNCE, | ||
2090 | &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress, &SkRlmtMcAddr) | ||
2091 | ) != NULL) { | ||
2092 | /* Send "new" packet to RLMT multicast address. */ | ||
2093 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2); | ||
2094 | } | ||
2095 | |||
2096 | if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_SEG) { | ||
2097 | if ((Para2.pParaPtr = | ||
2098 | SkRlmtBuildSpanningTreePacket(pAC, IoC, Para.Para32[0])) != NULL) { | ||
2099 | pAC->Rlmt.Port[Para.Para32[0]].RootIdSet = SK_FALSE; | ||
2100 | pRPort->Net->CheckingState |= | ||
2101 | SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG; | ||
2102 | |||
2103 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2); | ||
2104 | |||
2105 | Para.Para32[1] = (SK_U32)-1; | ||
2106 | SkTimerStart(pAC, IoC, &pRPort->Net->SegTimer, | ||
2107 | SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para); | ||
2108 | } | ||
2109 | } | ||
2110 | |||
2111 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2112 | ("SK_RLMT_LINK_UP Event END.\n")) | ||
2113 | } /* SkRlmtEvtLinkUp */ | ||
2114 | |||
2115 | |||
2116 | /****************************************************************************** | ||
2117 | * | ||
2118 | * SkRlmtEvtPortUpTim - PORT_UP_TIM | ||
2119 | * | ||
2120 | * Description: | ||
2121 | * This routine handles PORT_UP_TIM events. | ||
2122 | * | ||
2123 | * Context: | ||
2124 | * runtime, pageable? | ||
2125 | * may be called after SK_INIT_IO | ||
2126 | * | ||
2127 | * Returns: | ||
2128 | * Nothing | ||
2129 | */ | ||
2130 | RLMT_STATIC void SkRlmtEvtPortUpTim( | ||
2131 | SK_AC *pAC, /* Adapter Context */ | ||
2132 | SK_IOC IoC, /* I/O Context */ | ||
2133 | SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */ | ||
2134 | { | ||
2135 | SK_RLMT_PORT *pRPort; | ||
2136 | |||
2137 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2138 | ("SK_RLMT_PORTUP_TIM Port %d Event BEGIN.\n", Para.Para32[0])) | ||
2139 | |||
2140 | if (Para.Para32[1] != (SK_U32)-1) { | ||
2141 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2142 | ("Bad Parameter.\n")) | ||
2143 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2144 | ("SK_RLMT_PORTUP_TIM Event EMPTY.\n")) | ||
2145 | return; | ||
2146 | } | ||
2147 | |||
2148 | pRPort = &pAC->Rlmt.Port[Para.Para32[0]]; | ||
2149 | if (pRPort->LinkDown || (pRPort->PortState == SK_RLMT_PS_UP)) { | ||
2150 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2151 | ("SK_RLMT_PORTUP_TIM Port %d Event EMPTY.\n", Para.Para32[0])) | ||
2152 | return; | ||
2153 | } | ||
2154 | |||
2155 | pRPort->PortDown = SK_FALSE; | ||
2156 | pRPort->PortState = SK_RLMT_PS_UP; | ||
2157 | pRPort->Net->PortsUp++; | ||
2158 | if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) { | ||
2159 | if (pAC->Rlmt.NumNets <= 1) { | ||
2160 | SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber); | ||
2161 | } | ||
2162 | SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_UP, Para); | ||
2163 | } | ||
2164 | |||
2165 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2166 | ("SK_RLMT_PORTUP_TIM Event END.\n")) | ||
2167 | } /* SkRlmtEvtPortUpTim */ | ||
2168 | |||
2169 | |||
2170 | /****************************************************************************** | ||
2171 | * | ||
2172 | * SkRlmtEvtPortDownTim - PORT_DOWN_* | ||
2173 | * | ||
2174 | * Description: | ||
2175 | * This routine handles PORT_DOWN_* events. | ||
2176 | * | ||
2177 | * Context: | ||
2178 | * runtime, pageable? | ||
2179 | * may be called after SK_INIT_IO | ||
2180 | * | ||
2181 | * Returns: | ||
2182 | * Nothing | ||
2183 | */ | ||
2184 | RLMT_STATIC void SkRlmtEvtPortDownX( | ||
2185 | SK_AC *pAC, /* Adapter Context */ | ||
2186 | SK_IOC IoC, /* I/O Context */ | ||
2187 | SK_U32 Event, /* Event code */ | ||
2188 | SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */ | ||
2189 | { | ||
2190 | SK_RLMT_PORT *pRPort; | ||
2191 | |||
2192 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2193 | ("SK_RLMT_PORTDOWN* Port %d Event (%d) BEGIN.\n", | ||
2194 | Para.Para32[0], Event)) | ||
2195 | |||
2196 | if (Para.Para32[1] != (SK_U32)-1) { | ||
2197 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2198 | ("Bad Parameter.\n")) | ||
2199 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2200 | ("SK_RLMT_PORTDOWN* Event EMPTY.\n")) | ||
2201 | return; | ||
2202 | } | ||
2203 | |||
2204 | pRPort = &pAC->Rlmt.Port[Para.Para32[0]]; | ||
2205 | if (!pRPort->PortStarted || (Event == SK_RLMT_PORTDOWN_TX_TIM && | ||
2206 | !(pRPort->CheckingState & SK_RLMT_PCS_TX))) { | ||
2207 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2208 | ("SK_RLMT_PORTDOWN* Event (%d) EMPTY.\n", Event)) | ||
2209 | return; | ||
2210 | } | ||
2211 | |||
2212 | /* Stop port's timers. */ | ||
2213 | SkTimerStop(pAC, IoC, &pRPort->UpTimer); | ||
2214 | SkTimerStop(pAC, IoC, &pRPort->DownRxTimer); | ||
2215 | SkTimerStop(pAC, IoC, &pRPort->DownTxTimer); | ||
2216 | |||
2217 | if (pRPort->PortState != SK_RLMT_PS_LINK_DOWN) { | ||
2218 | pRPort->PortState = SK_RLMT_PS_DOWN; | ||
2219 | } | ||
2220 | |||
2221 | if (!pRPort->PortDown) { | ||
2222 | pRPort->Net->PortsUp--; | ||
2223 | pRPort->PortDown = SK_TRUE; | ||
2224 | SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_DOWN, Para); | ||
2225 | } | ||
2226 | |||
2227 | pRPort->PacketsPerTimeSlot = 0; | ||
2228 | /* pRPort->DataPacketsPerTimeSlot = 0; */ | ||
2229 | pRPort->BpduPacketsPerTimeSlot = 0; | ||
2230 | pRPort->BcTimeStamp = 0; | ||
2231 | |||
2232 | /* | ||
2233 | * RA;:;: To be checked: | ||
2234 | * - actions at RLMT_STOP: We should not switch anymore. | ||
2235 | */ | ||
2236 | if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) { | ||
2237 | if (Para.Para32[0] == | ||
2238 | pRPort->Net->Port[pRPort->Net->ActivePort]->PortNumber) { | ||
2239 | /* Active Port went down. */ | ||
2240 | SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber); | ||
2241 | } | ||
2242 | } | ||
2243 | |||
2244 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2245 | ("SK_RLMT_PORTDOWN* Event (%d) END.\n", Event)) | ||
2246 | } /* SkRlmtEvtPortDownX */ | ||
2247 | |||
2248 | |||
2249 | /****************************************************************************** | ||
2250 | * | ||
2251 | * SkRlmtEvtLinkDown - LINK_DOWN | ||
2252 | * | ||
2253 | * Description: | ||
2254 | * This routine handles LINK_DOWN events. | ||
2255 | * | ||
2256 | * Context: | ||
2257 | * runtime, pageable? | ||
2258 | * may be called after SK_INIT_IO | ||
2259 | * | ||
2260 | * Returns: | ||
2261 | * Nothing | ||
2262 | */ | ||
2263 | RLMT_STATIC void SkRlmtEvtLinkDown( | ||
2264 | SK_AC *pAC, /* Adapter Context */ | ||
2265 | SK_IOC IoC, /* I/O Context */ | ||
2266 | SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 Undefined */ | ||
2267 | { | ||
2268 | SK_RLMT_PORT *pRPort; | ||
2269 | |||
2270 | pRPort = &pAC->Rlmt.Port[Para.Para32[0]]; | ||
2271 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2272 | ("SK_RLMT_LINK_DOWN Port %d Event BEGIN.\n", Para.Para32[0])) | ||
2273 | |||
2274 | if (!pAC->Rlmt.Port[Para.Para32[0]].LinkDown) { | ||
2275 | pRPort->Net->LinksUp--; | ||
2276 | pRPort->LinkDown = SK_TRUE; | ||
2277 | pRPort->PortState = SK_RLMT_PS_LINK_DOWN; | ||
2278 | SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_OFF); | ||
2279 | |||
2280 | if ((pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) != 0) { | ||
2281 | /* Build the check chain. */ | ||
2282 | SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber); | ||
2283 | } | ||
2284 | |||
2285 | /* Ensure that port is marked down. */ | ||
2286 | Para.Para32[1] = -1; | ||
2287 | (void)SkRlmtEvent(pAC, IoC, SK_RLMT_PORTDOWN, Para); | ||
2288 | } | ||
2289 | |||
2290 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2291 | ("SK_RLMT_LINK_DOWN Event END.\n")) | ||
2292 | } /* SkRlmtEvtLinkDown */ | ||
2293 | |||
2294 | |||
2295 | /****************************************************************************** | ||
2296 | * | ||
2297 | * SkRlmtEvtPortAddr - PORT_ADDR | ||
2298 | * | ||
2299 | * Description: | ||
2300 | * This routine handles PORT_ADDR events. | ||
2301 | * | ||
2302 | * Context: | ||
2303 | * runtime, pageable? | ||
2304 | * may be called after SK_INIT_IO | ||
2305 | * | ||
2306 | * Returns: | ||
2307 | * Nothing | ||
2308 | */ | ||
2309 | RLMT_STATIC void SkRlmtEvtPortAddr( | ||
2310 | SK_AC *pAC, /* Adapter Context */ | ||
2311 | SK_IOC IoC, /* I/O Context */ | ||
2312 | SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */ | ||
2313 | { | ||
2314 | SK_U32 i, j; | ||
2315 | SK_RLMT_PORT *pRPort; | ||
2316 | SK_MAC_ADDR *pOldMacAddr; | ||
2317 | SK_MAC_ADDR *pNewMacAddr; | ||
2318 | |||
2319 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2320 | ("SK_RLMT_PORT_ADDR Port %d Event BEGIN.\n", Para.Para32[0])) | ||
2321 | |||
2322 | if (Para.Para32[1] != (SK_U32)-1) { | ||
2323 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2324 | ("Bad Parameter.\n")) | ||
2325 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2326 | ("SK_RLMT_PORT_ADDR Event EMPTY.\n")) | ||
2327 | return; | ||
2328 | } | ||
2329 | |||
2330 | /* Port's physical MAC address changed. */ | ||
2331 | pOldMacAddr = &pAC->Addr.Port[Para.Para32[0]].PreviousMacAddress; | ||
2332 | pNewMacAddr = &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress; | ||
2333 | |||
2334 | /* | ||
2335 | * NOTE: This is not scalable for solutions where ports are | ||
2336 | * checked remotely. There, we need to send an RLMT | ||
2337 | * address change packet - and how do we ensure delivery? | ||
2338 | */ | ||
2339 | for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { | ||
2340 | pRPort = &pAC->Rlmt.Port[i]; | ||
2341 | for (j = 0; j < pRPort->PortsChecked; j++) { | ||
2342 | if (SK_ADDR_EQUAL( | ||
2343 | pRPort->PortCheck[j].CheckAddr.a, pOldMacAddr->a)) { | ||
2344 | pRPort->PortCheck[j].CheckAddr = *pNewMacAddr; | ||
2345 | } | ||
2346 | } | ||
2347 | } | ||
2348 | |||
2349 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2350 | ("SK_RLMT_PORT_ADDR Event END.\n")) | ||
2351 | } /* SkRlmtEvtPortAddr */ | ||
2352 | |||
2353 | |||
2354 | /****************************************************************************** | ||
2355 | * | ||
2356 | * SkRlmtEvtStart - START | ||
2357 | * | ||
2358 | * Description: | ||
2359 | * This routine handles START events. | ||
2360 | * | ||
2361 | * Context: | ||
2362 | * runtime, pageable? | ||
2363 | * may be called after SK_INIT_IO | ||
2364 | * | ||
2365 | * Returns: | ||
2366 | * Nothing | ||
2367 | */ | ||
2368 | RLMT_STATIC void SkRlmtEvtStart( | ||
2369 | SK_AC *pAC, /* Adapter Context */ | ||
2370 | SK_IOC IoC, /* I/O Context */ | ||
2371 | SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */ | ||
2372 | { | ||
2373 | SK_EVPARA Para2; | ||
2374 | SK_U32 PortIdx; | ||
2375 | SK_U32 PortNumber; | ||
2376 | |||
2377 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2378 | ("SK_RLMT_START Net %d Event BEGIN.\n", Para.Para32[0])) | ||
2379 | |||
2380 | if (Para.Para32[1] != (SK_U32)-1) { | ||
2381 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2382 | ("Bad Parameter.\n")) | ||
2383 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2384 | ("SK_RLMT_START Event EMPTY.\n")) | ||
2385 | return; | ||
2386 | } | ||
2387 | |||
2388 | if (Para.Para32[0] >= pAC->Rlmt.NumNets) { | ||
2389 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2390 | ("Bad NetNumber %d.\n", Para.Para32[0])) | ||
2391 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2392 | ("SK_RLMT_START Event EMPTY.\n")) | ||
2393 | return; | ||
2394 | } | ||
2395 | |||
2396 | if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState != SK_RLMT_RS_INIT) { | ||
2397 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2398 | ("SK_RLMT_START Event EMPTY.\n")) | ||
2399 | return; | ||
2400 | } | ||
2401 | |||
2402 | if (pAC->Rlmt.NetsStarted >= pAC->Rlmt.NumNets) { | ||
2403 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2404 | ("All nets should have been started.\n")) | ||
2405 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2406 | ("SK_RLMT_START Event EMPTY.\n")) | ||
2407 | return; | ||
2408 | } | ||
2409 | |||
2410 | if (pAC->Rlmt.Net[Para.Para32[0]].PrefPort >= | ||
2411 | pAC->Rlmt.Net[Para.Para32[0]].NumPorts) { | ||
2412 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E009, SKERR_RLMT_E009_MSG); | ||
2413 | |||
2414 | /* Change PrefPort to internal default. */ | ||
2415 | Para2.Para32[0] = 0xFFFFFFFF; | ||
2416 | Para2.Para32[1] = Para.Para32[0]; | ||
2417 | (void)SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE, Para2); | ||
2418 | } | ||
2419 | |||
2420 | PortIdx = pAC->Rlmt.Net[Para.Para32[0]].PrefPort; | ||
2421 | PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[PortIdx]->PortNumber; | ||
2422 | |||
2423 | pAC->Rlmt.Net[Para.Para32[0]].LinksUp = 0; | ||
2424 | pAC->Rlmt.Net[Para.Para32[0]].PortsUp = 0; | ||
2425 | pAC->Rlmt.Net[Para.Para32[0]].CheckingState = 0; | ||
2426 | pAC->Rlmt.Net[Para.Para32[0]].RlmtState = SK_RLMT_RS_NET_DOWN; | ||
2427 | |||
2428 | /* Start preferred port. */ | ||
2429 | SkRlmtPortStart(pAC, IoC, PortNumber); | ||
2430 | |||
2431 | /* Start Timer (for first port only). */ | ||
2432 | Para2.Para32[0] = PortNumber; | ||
2433 | Para2.Para32[1] = (SK_U32)-1; | ||
2434 | SkTimerStart(pAC, IoC, &pAC->Rlmt.Port[PortNumber].UpTimer, | ||
2435 | SK_RLMT_PORTSTART_TIM_VAL, SKGE_RLMT, SK_RLMT_PORTSTART_TIM, Para2); | ||
2436 | |||
2437 | pAC->Rlmt.NetsStarted++; | ||
2438 | |||
2439 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2440 | ("SK_RLMT_START Event END.\n")) | ||
2441 | } /* SkRlmtEvtStart */ | ||
2442 | |||
2443 | |||
2444 | /****************************************************************************** | ||
2445 | * | ||
2446 | * SkRlmtEvtStop - STOP | ||
2447 | * | ||
2448 | * Description: | ||
2449 | * This routine handles STOP events. | ||
2450 | * | ||
2451 | * Context: | ||
2452 | * runtime, pageable? | ||
2453 | * may be called after SK_INIT_IO | ||
2454 | * | ||
2455 | * Returns: | ||
2456 | * Nothing | ||
2457 | */ | ||
2458 | RLMT_STATIC void SkRlmtEvtStop( | ||
2459 | SK_AC *pAC, /* Adapter Context */ | ||
2460 | SK_IOC IoC, /* I/O Context */ | ||
2461 | SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */ | ||
2462 | { | ||
2463 | SK_EVPARA Para2; | ||
2464 | SK_U32 PortNumber; | ||
2465 | SK_U32 i; | ||
2466 | |||
2467 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2468 | ("SK_RLMT_STOP Net %d Event BEGIN.\n", Para.Para32[0])) | ||
2469 | |||
2470 | if (Para.Para32[1] != (SK_U32)-1) { | ||
2471 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2472 | ("Bad Parameter.\n")) | ||
2473 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2474 | ("SK_RLMT_STOP Event EMPTY.\n")) | ||
2475 | return; | ||
2476 | } | ||
2477 | |||
2478 | if (Para.Para32[0] >= pAC->Rlmt.NumNets) { | ||
2479 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2480 | ("Bad NetNumber %d.\n", Para.Para32[0])) | ||
2481 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2482 | ("SK_RLMT_STOP Event EMPTY.\n")) | ||
2483 | return; | ||
2484 | } | ||
2485 | |||
2486 | if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState == SK_RLMT_RS_INIT) { | ||
2487 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2488 | ("SK_RLMT_STOP Event EMPTY.\n")) | ||
2489 | return; | ||
2490 | } | ||
2491 | |||
2492 | if (pAC->Rlmt.NetsStarted == 0) { | ||
2493 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2494 | ("All nets are stopped.\n")) | ||
2495 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2496 | ("SK_RLMT_STOP Event EMPTY.\n")) | ||
2497 | return; | ||
2498 | } | ||
2499 | |||
2500 | /* Stop RLMT timers. */ | ||
2501 | SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer); | ||
2502 | SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].SegTimer); | ||
2503 | |||
2504 | /* Stop net. */ | ||
2505 | pAC->Rlmt.Net[Para.Para32[0]].RlmtState = SK_RLMT_RS_INIT; | ||
2506 | pAC->Rlmt.Net[Para.Para32[0]].RootIdSet = SK_FALSE; | ||
2507 | Para2.Para32[0] = SK_RLMT_NET_DOWN_FINAL; | ||
2508 | Para2.Para32[1] = Para.Para32[0]; /* Net# */ | ||
2509 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para2); | ||
2510 | |||
2511 | /* Stop ports. */ | ||
2512 | for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) { | ||
2513 | PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber; | ||
2514 | if (pAC->Rlmt.Port[PortNumber].PortState != SK_RLMT_PS_INIT) { | ||
2515 | SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].UpTimer); | ||
2516 | SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].DownRxTimer); | ||
2517 | SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].DownTxTimer); | ||
2518 | |||
2519 | pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_INIT; | ||
2520 | pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE; | ||
2521 | pAC->Rlmt.Port[PortNumber].PortStarted = SK_FALSE; | ||
2522 | Para2.Para32[0] = PortNumber; | ||
2523 | Para2.Para32[1] = (SK_U32)-1; | ||
2524 | SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para2); | ||
2525 | } | ||
2526 | } | ||
2527 | |||
2528 | pAC->Rlmt.NetsStarted--; | ||
2529 | |||
2530 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2531 | ("SK_RLMT_STOP Event END.\n")) | ||
2532 | } /* SkRlmtEvtStop */ | ||
2533 | |||
2534 | |||
2535 | /****************************************************************************** | ||
2536 | * | ||
2537 | * SkRlmtEvtTim - TIM | ||
2538 | * | ||
2539 | * Description: | ||
2540 | * This routine handles TIM events. | ||
2541 | * | ||
2542 | * Context: | ||
2543 | * runtime, pageable? | ||
2544 | * may be called after SK_INIT_IO | ||
2545 | * | ||
2546 | * Returns: | ||
2547 | * Nothing | ||
2548 | */ | ||
2549 | RLMT_STATIC void SkRlmtEvtTim( | ||
2550 | SK_AC *pAC, /* Adapter Context */ | ||
2551 | SK_IOC IoC, /* I/O Context */ | ||
2552 | SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */ | ||
2553 | { | ||
2554 | SK_RLMT_PORT *pRPort; | ||
2555 | SK_U32 Timeout; | ||
2556 | SK_U32 NewTimeout; | ||
2557 | SK_U32 PortNumber; | ||
2558 | SK_U32 i; | ||
2559 | |||
2560 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2561 | ("SK_RLMT_TIM Event BEGIN.\n")) | ||
2562 | |||
2563 | if (Para.Para32[1] != (SK_U32)-1) { | ||
2564 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2565 | ("Bad Parameter.\n")) | ||
2566 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2567 | ("SK_RLMT_TIM Event EMPTY.\n")) | ||
2568 | return; | ||
2569 | } | ||
2570 | |||
2571 | if ((pAC->Rlmt.Net[Para.Para32[0]].RlmtMode & SK_RLMT_CHECK_OTHERS) == 0 || | ||
2572 | pAC->Rlmt.Net[Para.Para32[0]].LinksUp == 0) { | ||
2573 | /* Mode changed or all links down: No more link checking. */ | ||
2574 | return; | ||
2575 | } | ||
2576 | |||
2577 | #if 0 | ||
2578 | pAC->Rlmt.SwitchCheckCounter--; | ||
2579 | if (pAC->Rlmt.SwitchCheckCounter == 0) { | ||
2580 | pAC->Rlmt.SwitchCheckCounter; | ||
2581 | } | ||
2582 | #endif /* 0 */ | ||
2583 | |||
2584 | NewTimeout = SK_RLMT_DEF_TO_VAL; | ||
2585 | for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) { | ||
2586 | PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber; | ||
2587 | pRPort = &pAC->Rlmt.Port[PortNumber]; | ||
2588 | if (!pRPort->LinkDown) { | ||
2589 | Timeout = SkRlmtCheckPort(pAC, IoC, PortNumber); | ||
2590 | if (Timeout < NewTimeout) { | ||
2591 | NewTimeout = Timeout; | ||
2592 | } | ||
2593 | |||
2594 | /* | ||
2595 | * These counters should be set to 0 for all ports before the | ||
2596 | * first frame is sent in the next loop. | ||
2597 | */ | ||
2598 | pRPort->PacketsPerTimeSlot = 0; | ||
2599 | /* pRPort->DataPacketsPerTimeSlot = 0; */ | ||
2600 | pRPort->BpduPacketsPerTimeSlot = 0; | ||
2601 | } | ||
2602 | } | ||
2603 | pAC->Rlmt.Net[Para.Para32[0]].TimeoutValue = NewTimeout; | ||
2604 | |||
2605 | if (pAC->Rlmt.Net[Para.Para32[0]].LinksUp > 1) { | ||
2606 | /* | ||
2607 | * If checking remote ports, also send packets if | ||
2608 | * (LinksUp == 1) && | ||
2609 | * this port checks at least one (remote) port. | ||
2610 | */ | ||
2611 | |||
2612 | /* | ||
2613 | * Must be new loop, as SkRlmtCheckPort can request to | ||
2614 | * check segmentation when e.g. checking the last port. | ||
2615 | */ | ||
2616 | for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) { | ||
2617 | if (!pAC->Rlmt.Net[Para.Para32[0]].Port[i]->LinkDown) { | ||
2618 | SkRlmtSend(pAC, IoC, | ||
2619 | pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber); | ||
2620 | } | ||
2621 | } | ||
2622 | } | ||
2623 | |||
2624 | SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer, | ||
2625 | pAC->Rlmt.Net[Para.Para32[0]].TimeoutValue, SKGE_RLMT, SK_RLMT_TIM, | ||
2626 | Para); | ||
2627 | |||
2628 | if (pAC->Rlmt.Net[Para.Para32[0]].LinksUp > 1 && | ||
2629 | (pAC->Rlmt.Net[Para.Para32[0]].RlmtMode & SK_RLMT_CHECK_SEG) && | ||
2630 | (pAC->Rlmt.Net[Para.Para32[0]].CheckingState & SK_RLMT_RCS_START_SEG)) { | ||
2631 | SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].SegTimer, | ||
2632 | SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para); | ||
2633 | pAC->Rlmt.Net[Para.Para32[0]].CheckingState &= ~SK_RLMT_RCS_START_SEG; | ||
2634 | pAC->Rlmt.Net[Para.Para32[0]].CheckingState |= | ||
2635 | SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG; | ||
2636 | } | ||
2637 | |||
2638 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2639 | ("SK_RLMT_TIM Event END.\n")) | ||
2640 | } /* SkRlmtEvtTim */ | ||
2641 | |||
2642 | |||
2643 | /****************************************************************************** | ||
2644 | * | ||
2645 | * SkRlmtEvtSegTim - SEG_TIM | ||
2646 | * | ||
2647 | * Description: | ||
2648 | * This routine handles SEG_TIM events. | ||
2649 | * | ||
2650 | * Context: | ||
2651 | * runtime, pageable? | ||
2652 | * may be called after SK_INIT_IO | ||
2653 | * | ||
2654 | * Returns: | ||
2655 | * Nothing | ||
2656 | */ | ||
2657 | RLMT_STATIC void SkRlmtEvtSegTim( | ||
2658 | SK_AC *pAC, /* Adapter Context */ | ||
2659 | SK_IOC IoC, /* I/O Context */ | ||
2660 | SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */ | ||
2661 | { | ||
2662 | #ifdef xDEBUG | ||
2663 | int j; | ||
2664 | #endif /* DEBUG */ | ||
2665 | |||
2666 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2667 | ("SK_RLMT_SEG_TIM Event BEGIN.\n")) | ||
2668 | |||
2669 | if (Para.Para32[1] != (SK_U32)-1) { | ||
2670 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2671 | ("Bad Parameter.\n")) | ||
2672 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2673 | ("SK_RLMT_SEG_TIM Event EMPTY.\n")) | ||
2674 | return; | ||
2675 | } | ||
2676 | |||
2677 | #ifdef xDEBUG | ||
2678 | for (j = 0; j < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; j++) { | ||
2679 | SK_ADDR_PORT *pAPort; | ||
2680 | SK_U32 k; | ||
2681 | SK_U16 *InAddr; | ||
2682 | SK_U8 InAddr8[6]; | ||
2683 | |||
2684 | InAddr = (SK_U16 *)&InAddr8[0]; | ||
2685 | pAPort = pAC->Rlmt.Net[Para.Para32[0]].Port[j]->AddrPort; | ||
2686 | for (k = 0; k < pAPort->NextExactMatchRlmt; k++) { | ||
2687 | /* Get exact match address k from port j. */ | ||
2688 | XM_INADDR(IoC, pAC->Rlmt.Net[Para.Para32[0]].Port[j]->PortNumber, | ||
2689 | XM_EXM(k), InAddr); | ||
2690 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2691 | ("MC address %d on Port %u: %02x %02x %02x %02x %02x %02x -- %02x %02x %02x %02x %02x %02x.\n", | ||
2692 | k, pAC->Rlmt.Net[Para.Para32[0]].Port[j]->PortNumber, | ||
2693 | InAddr8[0], InAddr8[1], InAddr8[2], | ||
2694 | InAddr8[3], InAddr8[4], InAddr8[5], | ||
2695 | pAPort->Exact[k].a[0], pAPort->Exact[k].a[1], | ||
2696 | pAPort->Exact[k].a[2], pAPort->Exact[k].a[3], | ||
2697 | pAPort->Exact[k].a[4], pAPort->Exact[k].a[5])) | ||
2698 | } | ||
2699 | } | ||
2700 | #endif /* xDEBUG */ | ||
2701 | |||
2702 | SkRlmtCheckSeg(pAC, IoC, Para.Para32[0]); | ||
2703 | |||
2704 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2705 | ("SK_RLMT_SEG_TIM Event END.\n")) | ||
2706 | } /* SkRlmtEvtSegTim */ | ||
2707 | |||
2708 | |||
2709 | /****************************************************************************** | ||
2710 | * | ||
2711 | * SkRlmtEvtPacketRx - PACKET_RECEIVED | ||
2712 | * | ||
2713 | * Description: | ||
2714 | * This routine handles PACKET_RECEIVED events. | ||
2715 | * | ||
2716 | * Context: | ||
2717 | * runtime, pageable? | ||
2718 | * may be called after SK_INIT_IO | ||
2719 | * | ||
2720 | * Returns: | ||
2721 | * Nothing | ||
2722 | */ | ||
2723 | RLMT_STATIC void SkRlmtEvtPacketRx( | ||
2724 | SK_AC *pAC, /* Adapter Context */ | ||
2725 | SK_IOC IoC, /* I/O Context */ | ||
2726 | SK_EVPARA Para) /* SK_MBUF *pMb */ | ||
2727 | { | ||
2728 | SK_MBUF *pMb; | ||
2729 | SK_MBUF *pNextMb; | ||
2730 | SK_U32 NetNumber; | ||
2731 | |||
2732 | |||
2733 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2734 | ("SK_RLMT_PACKET_RECEIVED Event BEGIN.\n")) | ||
2735 | |||
2736 | /* Should we ignore frames during port switching? */ | ||
2737 | |||
2738 | #ifdef DEBUG | ||
2739 | pMb = Para.pParaPtr; | ||
2740 | if (pMb == NULL) { | ||
2741 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("No mbuf.\n")) | ||
2742 | } | ||
2743 | else if (pMb->pNext != NULL) { | ||
2744 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2745 | ("More than one mbuf or pMb->pNext not set.\n")) | ||
2746 | } | ||
2747 | #endif /* DEBUG */ | ||
2748 | |||
2749 | for (pMb = Para.pParaPtr; pMb != NULL; pMb = pNextMb) { | ||
2750 | pNextMb = pMb->pNext; | ||
2751 | pMb->pNext = NULL; | ||
2752 | |||
2753 | NetNumber = pAC->Rlmt.Port[pMb->PortIdx].Net->NetNumber; | ||
2754 | if (pAC->Rlmt.Net[NetNumber].RlmtState == SK_RLMT_RS_INIT) { | ||
2755 | SkDrvFreeRlmtMbuf(pAC, IoC, pMb); | ||
2756 | } | ||
2757 | else { | ||
2758 | SkRlmtPacketReceive(pAC, IoC, pMb); | ||
2759 | } | ||
2760 | } | ||
2761 | |||
2762 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2763 | ("SK_RLMT_PACKET_RECEIVED Event END.\n")) | ||
2764 | } /* SkRlmtEvtPacketRx */ | ||
2765 | |||
2766 | |||
2767 | /****************************************************************************** | ||
2768 | * | ||
2769 | * SkRlmtEvtStatsClear - STATS_CLEAR | ||
2770 | * | ||
2771 | * Description: | ||
2772 | * This routine handles STATS_CLEAR events. | ||
2773 | * | ||
2774 | * Context: | ||
2775 | * runtime, pageable? | ||
2776 | * may be called after SK_INIT_IO | ||
2777 | * | ||
2778 | * Returns: | ||
2779 | * Nothing | ||
2780 | */ | ||
2781 | RLMT_STATIC void SkRlmtEvtStatsClear( | ||
2782 | SK_AC *pAC, /* Adapter Context */ | ||
2783 | SK_IOC IoC, /* I/O Context */ | ||
2784 | SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */ | ||
2785 | { | ||
2786 | SK_U32 i; | ||
2787 | SK_RLMT_PORT *pRPort; | ||
2788 | |||
2789 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2790 | ("SK_RLMT_STATS_CLEAR Event BEGIN.\n")) | ||
2791 | |||
2792 | if (Para.Para32[1] != (SK_U32)-1) { | ||
2793 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2794 | ("Bad Parameter.\n")) | ||
2795 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2796 | ("SK_RLMT_STATS_CLEAR Event EMPTY.\n")) | ||
2797 | return; | ||
2798 | } | ||
2799 | |||
2800 | if (Para.Para32[0] >= pAC->Rlmt.NumNets) { | ||
2801 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2802 | ("Bad NetNumber %d.\n", Para.Para32[0])) | ||
2803 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2804 | ("SK_RLMT_STATS_CLEAR Event EMPTY.\n")) | ||
2805 | return; | ||
2806 | } | ||
2807 | |||
2808 | /* Clear statistics for logical and physical ports. */ | ||
2809 | for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) { | ||
2810 | pRPort = | ||
2811 | &pAC->Rlmt.Port[pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber]; | ||
2812 | pRPort->TxHelloCts = 0; | ||
2813 | pRPort->RxHelloCts = 0; | ||
2814 | pRPort->TxSpHelloReqCts = 0; | ||
2815 | pRPort->RxSpHelloCts = 0; | ||
2816 | } | ||
2817 | |||
2818 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2819 | ("SK_RLMT_STATS_CLEAR Event END.\n")) | ||
2820 | } /* SkRlmtEvtStatsClear */ | ||
2821 | |||
2822 | |||
2823 | /****************************************************************************** | ||
2824 | * | ||
2825 | * SkRlmtEvtStatsUpdate - STATS_UPDATE | ||
2826 | * | ||
2827 | * Description: | ||
2828 | * This routine handles STATS_UPDATE events. | ||
2829 | * | ||
2830 | * Context: | ||
2831 | * runtime, pageable? | ||
2832 | * may be called after SK_INIT_IO | ||
2833 | * | ||
2834 | * Returns: | ||
2835 | * Nothing | ||
2836 | */ | ||
2837 | RLMT_STATIC void SkRlmtEvtStatsUpdate( | ||
2838 | SK_AC *pAC, /* Adapter Context */ | ||
2839 | SK_IOC IoC, /* I/O Context */ | ||
2840 | SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */ | ||
2841 | { | ||
2842 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2843 | ("SK_RLMT_STATS_UPDATE Event BEGIN.\n")) | ||
2844 | |||
2845 | if (Para.Para32[1] != (SK_U32)-1) { | ||
2846 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2847 | ("Bad Parameter.\n")) | ||
2848 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2849 | ("SK_RLMT_STATS_UPDATE Event EMPTY.\n")) | ||
2850 | return; | ||
2851 | } | ||
2852 | |||
2853 | if (Para.Para32[0] >= pAC->Rlmt.NumNets) { | ||
2854 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2855 | ("Bad NetNumber %d.\n", Para.Para32[0])) | ||
2856 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2857 | ("SK_RLMT_STATS_UPDATE Event EMPTY.\n")) | ||
2858 | return; | ||
2859 | } | ||
2860 | |||
2861 | /* Update statistics - currently always up-to-date. */ | ||
2862 | |||
2863 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2864 | ("SK_RLMT_STATS_UPDATE Event END.\n")) | ||
2865 | } /* SkRlmtEvtStatsUpdate */ | ||
2866 | |||
2867 | |||
2868 | /****************************************************************************** | ||
2869 | * | ||
2870 | * SkRlmtEvtPrefportChange - PREFPORT_CHANGE | ||
2871 | * | ||
2872 | * Description: | ||
2873 | * This routine handles PREFPORT_CHANGE events. | ||
2874 | * | ||
2875 | * Context: | ||
2876 | * runtime, pageable? | ||
2877 | * may be called after SK_INIT_IO | ||
2878 | * | ||
2879 | * Returns: | ||
2880 | * Nothing | ||
2881 | */ | ||
2882 | RLMT_STATIC void SkRlmtEvtPrefportChange( | ||
2883 | SK_AC *pAC, /* Adapter Context */ | ||
2884 | SK_IOC IoC, /* I/O Context */ | ||
2885 | SK_EVPARA Para) /* SK_U32 PortIndex; SK_U32 NetNumber */ | ||
2886 | { | ||
2887 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2888 | ("SK_RLMT_PREFPORT_CHANGE to Port %d Event BEGIN.\n", Para.Para32[0])) | ||
2889 | |||
2890 | if (Para.Para32[1] >= pAC->Rlmt.NumNets) { | ||
2891 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2892 | ("Bad NetNumber %d.\n", Para.Para32[1])) | ||
2893 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2894 | ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n")) | ||
2895 | return; | ||
2896 | } | ||
2897 | |||
2898 | /* 0xFFFFFFFF == auto-mode. */ | ||
2899 | if (Para.Para32[0] == 0xFFFFFFFF) { | ||
2900 | pAC->Rlmt.Net[Para.Para32[1]].PrefPort = SK_RLMT_DEF_PREF_PORT; | ||
2901 | } | ||
2902 | else { | ||
2903 | if (Para.Para32[0] >= pAC->Rlmt.Net[Para.Para32[1]].NumPorts) { | ||
2904 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E010, SKERR_RLMT_E010_MSG); | ||
2905 | |||
2906 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2907 | ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n")) | ||
2908 | return; | ||
2909 | } | ||
2910 | |||
2911 | pAC->Rlmt.Net[Para.Para32[1]].PrefPort = Para.Para32[0]; | ||
2912 | } | ||
2913 | |||
2914 | pAC->Rlmt.Net[Para.Para32[1]].Preference = Para.Para32[0]; | ||
2915 | |||
2916 | if (pAC->Rlmt.Net[Para.Para32[1]].RlmtState != SK_RLMT_RS_INIT) { | ||
2917 | SkRlmtCheckSwitch(pAC, IoC, Para.Para32[1]); | ||
2918 | } | ||
2919 | |||
2920 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2921 | ("SK_RLMT_PREFPORT_CHANGE Event END.\n")) | ||
2922 | } /* SkRlmtEvtPrefportChange */ | ||
2923 | |||
2924 | |||
2925 | /****************************************************************************** | ||
2926 | * | ||
2927 | * SkRlmtEvtSetNets - SET_NETS | ||
2928 | * | ||
2929 | * Description: | ||
2930 | * This routine handles SET_NETS events. | ||
2931 | * | ||
2932 | * Context: | ||
2933 | * runtime, pageable? | ||
2934 | * may be called after SK_INIT_IO | ||
2935 | * | ||
2936 | * Returns: | ||
2937 | * Nothing | ||
2938 | */ | ||
2939 | RLMT_STATIC void SkRlmtEvtSetNets( | ||
2940 | SK_AC *pAC, /* Adapter Context */ | ||
2941 | SK_IOC IoC, /* I/O Context */ | ||
2942 | SK_EVPARA Para) /* SK_U32 NumNets; SK_U32 -1 */ | ||
2943 | { | ||
2944 | int i; | ||
2945 | |||
2946 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2947 | ("SK_RLMT_SET_NETS Event BEGIN.\n")) | ||
2948 | |||
2949 | if (Para.Para32[1] != (SK_U32)-1) { | ||
2950 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2951 | ("Bad Parameter.\n")) | ||
2952 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2953 | ("SK_RLMT_SET_NETS Event EMPTY.\n")) | ||
2954 | return; | ||
2955 | } | ||
2956 | |||
2957 | if (Para.Para32[0] == 0 || Para.Para32[0] > SK_MAX_NETS || | ||
2958 | Para.Para32[0] > (SK_U32)pAC->GIni.GIMacsFound) { | ||
2959 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2960 | ("Bad number of nets: %d.\n", Para.Para32[0])) | ||
2961 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2962 | ("SK_RLMT_SET_NETS Event EMPTY.\n")) | ||
2963 | return; | ||
2964 | } | ||
2965 | |||
2966 | if (Para.Para32[0] == pAC->Rlmt.NumNets) { /* No change. */ | ||
2967 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2968 | ("SK_RLMT_SET_NETS Event EMPTY.\n")) | ||
2969 | return; | ||
2970 | } | ||
2971 | |||
2972 | /* Entering and leaving dual mode only allowed while nets are stopped. */ | ||
2973 | if (pAC->Rlmt.NetsStarted > 0) { | ||
2974 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2975 | ("Changing dual mode only allowed while all nets are stopped.\n")) | ||
2976 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
2977 | ("SK_RLMT_SET_NETS Event EMPTY.\n")) | ||
2978 | return; | ||
2979 | } | ||
2980 | |||
2981 | if (Para.Para32[0] == 1) { | ||
2982 | if (pAC->Rlmt.NumNets > 1) { | ||
2983 | /* Clear logical MAC addr from second net's active port. */ | ||
2984 | (void)SkAddrOverride(pAC, IoC, pAC->Rlmt.Net[1].Port[pAC->Addr. | ||
2985 | Net[1].ActivePort]->PortNumber, NULL, SK_ADDR_CLEAR_LOGICAL); | ||
2986 | pAC->Rlmt.Net[1].NumPorts = 0; | ||
2987 | } | ||
2988 | |||
2989 | pAC->Rlmt.NumNets = Para.Para32[0]; | ||
2990 | for (i = 0; (SK_U32)i < pAC->Rlmt.NumNets; i++) { | ||
2991 | pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT; | ||
2992 | pAC->Rlmt.Net[i].RootIdSet = SK_FALSE; | ||
2993 | pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF; /* "Automatic" */ | ||
2994 | pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT; | ||
2995 | /* Just assuming. */ | ||
2996 | pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort; | ||
2997 | pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE; | ||
2998 | pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL; | ||
2999 | pAC->Rlmt.Net[i].NetNumber = i; | ||
3000 | } | ||
3001 | |||
3002 | pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[0]; | ||
3003 | pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound; | ||
3004 | |||
3005 | SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para); | ||
3006 | |||
3007 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
3008 | ("RLMT: Changed to one net with two ports.\n")) | ||
3009 | } | ||
3010 | else if (Para.Para32[0] == 2) { | ||
3011 | pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[1]; | ||
3012 | pAC->Rlmt.Net[1].NumPorts = pAC->GIni.GIMacsFound - 1; | ||
3013 | pAC->Rlmt.Net[0].NumPorts = | ||
3014 | pAC->GIni.GIMacsFound - pAC->Rlmt.Net[1].NumPorts; | ||
3015 | |||
3016 | pAC->Rlmt.NumNets = Para.Para32[0]; | ||
3017 | for (i = 0; (SK_U32)i < pAC->Rlmt.NumNets; i++) { | ||
3018 | pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT; | ||
3019 | pAC->Rlmt.Net[i].RootIdSet = SK_FALSE; | ||
3020 | pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF; /* "Automatic" */ | ||
3021 | pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT; | ||
3022 | /* Just assuming. */ | ||
3023 | pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort; | ||
3024 | pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE; | ||
3025 | pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL; | ||
3026 | |||
3027 | pAC->Rlmt.Net[i].NetNumber = i; | ||
3028 | } | ||
3029 | |||
3030 | /* Set logical MAC addr on second net's active port. */ | ||
3031 | (void)SkAddrOverride(pAC, IoC, pAC->Rlmt.Net[1].Port[pAC->Addr. | ||
3032 | Net[1].ActivePort]->PortNumber, NULL, SK_ADDR_SET_LOGICAL); | ||
3033 | |||
3034 | SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para); | ||
3035 | |||
3036 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
3037 | ("RLMT: Changed to two nets with one port each.\n")) | ||
3038 | } | ||
3039 | else { | ||
3040 | /* Not implemented for more than two nets. */ | ||
3041 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
3042 | ("SetNets not implemented for more than two nets.\n")) | ||
3043 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
3044 | ("SK_RLMT_SET_NETS Event EMPTY.\n")) | ||
3045 | return; | ||
3046 | } | ||
3047 | |||
3048 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
3049 | ("SK_RLMT_SET_NETS Event END.\n")) | ||
3050 | } /* SkRlmtSetNets */ | ||
3051 | |||
3052 | |||
3053 | /****************************************************************************** | ||
3054 | * | ||
3055 | * SkRlmtEvtModeChange - MODE_CHANGE | ||
3056 | * | ||
3057 | * Description: | ||
3058 | * This routine handles MODE_CHANGE events. | ||
3059 | * | ||
3060 | * Context: | ||
3061 | * runtime, pageable? | ||
3062 | * may be called after SK_INIT_IO | ||
3063 | * | ||
3064 | * Returns: | ||
3065 | * Nothing | ||
3066 | */ | ||
3067 | RLMT_STATIC void SkRlmtEvtModeChange( | ||
3068 | SK_AC *pAC, /* Adapter Context */ | ||
3069 | SK_IOC IoC, /* I/O Context */ | ||
3070 | SK_EVPARA Para) /* SK_U32 NewMode; SK_U32 NetNumber */ | ||
3071 | { | ||
3072 | SK_EVPARA Para2; | ||
3073 | SK_U32 i; | ||
3074 | SK_U32 PrevRlmtMode; | ||
3075 | |||
3076 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
3077 | ("SK_RLMT_MODE_CHANGE Event BEGIN.\n")) | ||
3078 | |||
3079 | if (Para.Para32[1] >= pAC->Rlmt.NumNets) { | ||
3080 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
3081 | ("Bad NetNumber %d.\n", Para.Para32[1])) | ||
3082 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
3083 | ("SK_RLMT_MODE_CHANGE Event EMPTY.\n")) | ||
3084 | return; | ||
3085 | } | ||
3086 | |||
3087 | Para.Para32[0] |= SK_RLMT_CHECK_LINK; | ||
3088 | |||
3089 | if ((pAC->Rlmt.Net[Para.Para32[1]].NumPorts == 1) && | ||
3090 | Para.Para32[0] != SK_RLMT_MODE_CLS) { | ||
3091 | pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = SK_RLMT_MODE_CLS; | ||
3092 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
3093 | ("Forced RLMT mode to CLS on single port net.\n")) | ||
3094 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
3095 | ("SK_RLMT_MODE_CHANGE Event EMPTY.\n")) | ||
3096 | return; | ||
3097 | } | ||
3098 | |||
3099 | /* Update RLMT mode. */ | ||
3100 | PrevRlmtMode = pAC->Rlmt.Net[Para.Para32[1]].RlmtMode; | ||
3101 | pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = Para.Para32[0]; | ||
3102 | |||
3103 | if ((PrevRlmtMode & SK_RLMT_CHECK_LOC_LINK) != | ||
3104 | (pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) { | ||
3105 | /* SK_RLMT_CHECK_LOC_LINK bit changed. */ | ||
3106 | if ((PrevRlmtMode & SK_RLMT_CHECK_OTHERS) == 0 && | ||
3107 | pAC->Rlmt.Net[Para.Para32[1]].NumPorts > 1 && | ||
3108 | pAC->Rlmt.Net[Para.Para32[1]].PortsUp >= 1) { | ||
3109 | /* 20001207 RA: Was "PortsUp == 1". */ | ||
3110 | Para2.Para32[0] = Para.Para32[1]; | ||
3111 | Para2.Para32[1] = (SK_U32)-1; | ||
3112 | SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[1]].LocTimer, | ||
3113 | pAC->Rlmt.Net[Para.Para32[1]].TimeoutValue, | ||
3114 | SKGE_RLMT, SK_RLMT_TIM, Para2); | ||
3115 | } | ||
3116 | } | ||
3117 | |||
3118 | if ((PrevRlmtMode & SK_RLMT_CHECK_SEG) != | ||
3119 | (pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_SEG)) { | ||
3120 | /* SK_RLMT_CHECK_SEG bit changed. */ | ||
3121 | for (i = 0; i < pAC->Rlmt.Net[Para.Para32[1]].NumPorts; i++) { | ||
3122 | (void)SkAddrMcClear(pAC, IoC, | ||
3123 | pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber, | ||
3124 | SK_ADDR_PERMANENT | SK_MC_SW_ONLY); | ||
3125 | |||
3126 | /* Add RLMT MC address. */ | ||
3127 | (void)SkAddrMcAdd(pAC, IoC, | ||
3128 | pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber, | ||
3129 | &SkRlmtMcAddr, SK_ADDR_PERMANENT); | ||
3130 | |||
3131 | if ((pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & | ||
3132 | SK_RLMT_CHECK_SEG) != 0) { | ||
3133 | /* Add BPDU MC address. */ | ||
3134 | (void)SkAddrMcAdd(pAC, IoC, | ||
3135 | pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber, | ||
3136 | &BridgeMcAddr, SK_ADDR_PERMANENT); | ||
3137 | |||
3138 | if (pAC->Rlmt.Net[Para.Para32[1]].RlmtState != SK_RLMT_RS_INIT) { | ||
3139 | if (!pAC->Rlmt.Net[Para.Para32[1]].Port[i]->LinkDown && | ||
3140 | (Para2.pParaPtr = SkRlmtBuildSpanningTreePacket( | ||
3141 | pAC, IoC, i)) != NULL) { | ||
3142 | pAC->Rlmt.Net[Para.Para32[1]].Port[i]->RootIdSet = | ||
3143 | SK_FALSE; | ||
3144 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2); | ||
3145 | } | ||
3146 | } | ||
3147 | } | ||
3148 | (void)SkAddrMcUpdate(pAC, IoC, | ||
3149 | pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber); | ||
3150 | } /* for ... */ | ||
3151 | |||
3152 | if ((pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_SEG) != 0) { | ||
3153 | Para2.Para32[0] = Para.Para32[1]; | ||
3154 | Para2.Para32[1] = (SK_U32)-1; | ||
3155 | SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[1]].SegTimer, | ||
3156 | SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para2); | ||
3157 | } | ||
3158 | } /* SK_RLMT_CHECK_SEG bit changed. */ | ||
3159 | |||
3160 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
3161 | ("SK_RLMT_MODE_CHANGE Event END.\n")) | ||
3162 | } /* SkRlmtEvtModeChange */ | ||
3163 | |||
3164 | |||
3165 | /****************************************************************************** | ||
3166 | * | ||
3167 | * SkRlmtEvent - a PORT- or an RLMT-specific event happened | ||
3168 | * | ||
3169 | * Description: | ||
3170 | * This routine calls subroutines to handle PORT- and RLMT-specific events. | ||
3171 | * | ||
3172 | * Context: | ||
3173 | * runtime, pageable? | ||
3174 | * may be called after SK_INIT_IO | ||
3175 | * | ||
3176 | * Returns: | ||
3177 | * 0 | ||
3178 | */ | ||
3179 | int SkRlmtEvent( | ||
3180 | SK_AC *pAC, /* Adapter Context */ | ||
3181 | SK_IOC IoC, /* I/O Context */ | ||
3182 | SK_U32 Event, /* Event code */ | ||
3183 | SK_EVPARA Para) /* Event-specific parameter */ | ||
3184 | { | ||
3185 | switch (Event) { | ||
3186 | |||
3187 | /* ----- PORT events ----- */ | ||
3188 | |||
3189 | case SK_RLMT_PORTSTART_TIM: /* From RLMT via TIME. */ | ||
3190 | SkRlmtEvtPortStartTim(pAC, IoC, Para); | ||
3191 | break; | ||
3192 | case SK_RLMT_LINK_UP: /* From SIRQ. */ | ||
3193 | SkRlmtEvtLinkUp(pAC, IoC, Para); | ||
3194 | break; | ||
3195 | case SK_RLMT_PORTUP_TIM: /* From RLMT via TIME. */ | ||
3196 | SkRlmtEvtPortUpTim(pAC, IoC, Para); | ||
3197 | break; | ||
3198 | case SK_RLMT_PORTDOWN: /* From RLMT. */ | ||
3199 | case SK_RLMT_PORTDOWN_RX_TIM: /* From RLMT via TIME. */ | ||
3200 | case SK_RLMT_PORTDOWN_TX_TIM: /* From RLMT via TIME. */ | ||
3201 | SkRlmtEvtPortDownX(pAC, IoC, Event, Para); | ||
3202 | break; | ||
3203 | case SK_RLMT_LINK_DOWN: /* From SIRQ. */ | ||
3204 | SkRlmtEvtLinkDown(pAC, IoC, Para); | ||
3205 | break; | ||
3206 | case SK_RLMT_PORT_ADDR: /* From ADDR. */ | ||
3207 | SkRlmtEvtPortAddr(pAC, IoC, Para); | ||
3208 | break; | ||
3209 | |||
3210 | /* ----- RLMT events ----- */ | ||
3211 | |||
3212 | case SK_RLMT_START: /* From DRV. */ | ||
3213 | SkRlmtEvtStart(pAC, IoC, Para); | ||
3214 | break; | ||
3215 | case SK_RLMT_STOP: /* From DRV. */ | ||
3216 | SkRlmtEvtStop(pAC, IoC, Para); | ||
3217 | break; | ||
3218 | case SK_RLMT_TIM: /* From RLMT via TIME. */ | ||
3219 | SkRlmtEvtTim(pAC, IoC, Para); | ||
3220 | break; | ||
3221 | case SK_RLMT_SEG_TIM: | ||
3222 | SkRlmtEvtSegTim(pAC, IoC, Para); | ||
3223 | break; | ||
3224 | case SK_RLMT_PACKET_RECEIVED: /* From DRV. */ | ||
3225 | SkRlmtEvtPacketRx(pAC, IoC, Para); | ||
3226 | break; | ||
3227 | case SK_RLMT_STATS_CLEAR: /* From PNMI. */ | ||
3228 | SkRlmtEvtStatsClear(pAC, IoC, Para); | ||
3229 | break; | ||
3230 | case SK_RLMT_STATS_UPDATE: /* From PNMI. */ | ||
3231 | SkRlmtEvtStatsUpdate(pAC, IoC, Para); | ||
3232 | break; | ||
3233 | case SK_RLMT_PREFPORT_CHANGE: /* From PNMI. */ | ||
3234 | SkRlmtEvtPrefportChange(pAC, IoC, Para); | ||
3235 | break; | ||
3236 | case SK_RLMT_MODE_CHANGE: /* From PNMI. */ | ||
3237 | SkRlmtEvtModeChange(pAC, IoC, Para); | ||
3238 | break; | ||
3239 | case SK_RLMT_SET_NETS: /* From DRV. */ | ||
3240 | SkRlmtEvtSetNets(pAC, IoC, Para); | ||
3241 | break; | ||
3242 | |||
3243 | /* ----- Unknown events ----- */ | ||
3244 | |||
3245 | default: /* Create error log entry. */ | ||
3246 | SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, | ||
3247 | ("Unknown RLMT Event %d.\n", Event)) | ||
3248 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E003, SKERR_RLMT_E003_MSG); | ||
3249 | break; | ||
3250 | } /* switch() */ | ||
3251 | |||
3252 | return (0); | ||
3253 | } /* SkRlmtEvent */ | ||
3254 | |||
3255 | #ifdef __cplusplus | ||
3256 | } | ||
3257 | #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..1e662aaebf84 --- /dev/null +++ b/drivers/net/sk98lin/skvpd.c | |||
@@ -0,0 +1,1091 @@ | |||
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 information 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 | /* | ||
136 | * Read one Stream of 'len' bytes of VPD data, starting at 'addr' from | ||
137 | * or to the I2C EEPROM. | ||
138 | * | ||
139 | * Returns number of bytes read / written. | ||
140 | */ | ||
141 | static int VpdWriteStream( | ||
142 | SK_AC *pAC, /* Adapters context */ | ||
143 | SK_IOC IoC, /* IO Context */ | ||
144 | char *buf, /* data buffer */ | ||
145 | int Addr, /* VPD start address */ | ||
146 | int Len) /* number of bytes to read / to write */ | ||
147 | { | ||
148 | int i; | ||
149 | int j; | ||
150 | SK_U16 AdrReg; | ||
151 | int Rtv; | ||
152 | SK_U8 * pComp; /* Compare pointer */ | ||
153 | SK_U8 Data; /* Input Data for Compare */ | ||
154 | |||
155 | /* Init Compare Pointer */ | ||
156 | pComp = (SK_U8 *) buf; | ||
157 | |||
158 | for (i = 0; i < Len; i++, buf++) { | ||
159 | if ((i%sizeof(SK_U32)) == 0) { | ||
160 | /* | ||
161 | * At the begin of each cycle read the Data Reg | ||
162 | * So it is initialized even if only a few bytes | ||
163 | * are written. | ||
164 | */ | ||
165 | AdrReg = (SK_U16) Addr; | ||
166 | AdrReg &= ~VPD_WRITE; /* READ operation */ | ||
167 | |||
168 | VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg); | ||
169 | |||
170 | /* Wait for termination */ | ||
171 | Rtv = VpdWait(pAC, IoC, VPD_READ); | ||
172 | if (Rtv != 0) { | ||
173 | return(i); | ||
174 | } | ||
175 | } | ||
176 | |||
177 | /* Write current Byte */ | ||
178 | VPD_OUT8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)), | ||
179 | *(SK_U8*)buf); | ||
180 | |||
181 | if (((i%sizeof(SK_U32)) == 3) || (i == (Len - 1))) { | ||
182 | /* New Address needs to be written to VPD_ADDR reg */ | ||
183 | AdrReg = (SK_U16) Addr; | ||
184 | Addr += sizeof(SK_U32); | ||
185 | AdrReg |= VPD_WRITE; /* WRITE operation */ | ||
186 | |||
187 | VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg); | ||
188 | |||
189 | /* Wait for termination */ | ||
190 | Rtv = VpdWait(pAC, IoC, VPD_WRITE); | ||
191 | if (Rtv != 0) { | ||
192 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, | ||
193 | ("Write Timed Out\n")); | ||
194 | return(i - (i%sizeof(SK_U32))); | ||
195 | } | ||
196 | |||
197 | /* | ||
198 | * Now re-read to verify | ||
199 | */ | ||
200 | AdrReg &= ~VPD_WRITE; /* READ operation */ | ||
201 | |||
202 | VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg); | ||
203 | |||
204 | /* Wait for termination */ | ||
205 | Rtv = VpdWait(pAC, IoC, VPD_READ); | ||
206 | if (Rtv != 0) { | ||
207 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, | ||
208 | ("Verify Timed Out\n")); | ||
209 | return(i - (i%sizeof(SK_U32))); | ||
210 | } | ||
211 | |||
212 | for (j = 0; j <= (int)(i%sizeof(SK_U32)); j++, pComp++) { | ||
213 | |||
214 | VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + j, &Data); | ||
215 | |||
216 | if (Data != *pComp) { | ||
217 | /* Verify Error */ | ||
218 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, | ||
219 | ("WriteStream Verify Error\n")); | ||
220 | return(i - (i%sizeof(SK_U32)) + j); | ||
221 | } | ||
222 | } | ||
223 | } | ||
224 | } | ||
225 | |||
226 | return(Len); | ||
227 | } | ||
228 | |||
229 | |||
230 | /* | ||
231 | * Read one Stream of 'len' bytes of VPD data, starting at 'addr' from | ||
232 | * or to the I2C EEPROM. | ||
233 | * | ||
234 | * Returns number of bytes read / written. | ||
235 | */ | ||
236 | static int VpdReadStream( | ||
237 | SK_AC *pAC, /* Adapters context */ | ||
238 | SK_IOC IoC, /* IO Context */ | ||
239 | char *buf, /* data buffer */ | ||
240 | int Addr, /* VPD start address */ | ||
241 | int Len) /* number of bytes to read / to write */ | ||
242 | { | ||
243 | int i; | ||
244 | SK_U16 AdrReg; | ||
245 | int Rtv; | ||
246 | |||
247 | for (i = 0; i < Len; i++, buf++) { | ||
248 | if ((i%sizeof(SK_U32)) == 0) { | ||
249 | /* New Address needs to be written to VPD_ADDR reg */ | ||
250 | AdrReg = (SK_U16) Addr; | ||
251 | Addr += sizeof(SK_U32); | ||
252 | AdrReg &= ~VPD_WRITE; /* READ operation */ | ||
253 | |||
254 | VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg); | ||
255 | |||
256 | /* Wait for termination */ | ||
257 | Rtv = VpdWait(pAC, IoC, VPD_READ); | ||
258 | if (Rtv != 0) { | ||
259 | return(i); | ||
260 | } | ||
261 | } | ||
262 | VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)), | ||
263 | (SK_U8 *)buf); | ||
264 | } | ||
265 | |||
266 | return(Len); | ||
267 | } | ||
268 | |||
269 | /* | ||
270 | * Read ore writes 'len' bytes of VPD data, starting at 'addr' from | ||
271 | * or to the I2C EEPROM. | ||
272 | * | ||
273 | * Returns number of bytes read / written. | ||
274 | */ | ||
275 | static int VpdTransferBlock( | ||
276 | SK_AC *pAC, /* Adapters context */ | ||
277 | SK_IOC IoC, /* IO Context */ | ||
278 | char *buf, /* data buffer */ | ||
279 | int addr, /* VPD start address */ | ||
280 | int len, /* number of bytes to read / to write */ | ||
281 | int dir) /* transfer direction may be VPD_READ or VPD_WRITE */ | ||
282 | { | ||
283 | int Rtv; /* Return value */ | ||
284 | int vpd_rom_size; | ||
285 | |||
286 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, | ||
287 | ("VPD %s block, addr = 0x%x, len = %d\n", | ||
288 | dir ? "write" : "read", addr, len)); | ||
289 | |||
290 | if (len == 0) | ||
291 | return(0); | ||
292 | |||
293 | vpd_rom_size = pAC->vpd.rom_size; | ||
294 | |||
295 | if (addr > vpd_rom_size - 4) { | ||
296 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, | ||
297 | ("Address error: 0x%x, exp. < 0x%x\n", | ||
298 | addr, vpd_rom_size - 4)); | ||
299 | return(0); | ||
300 | } | ||
301 | |||
302 | if (addr + len > vpd_rom_size) { | ||
303 | len = vpd_rom_size - addr; | ||
304 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, | ||
305 | ("Warning: len was cut to %d\n", len)); | ||
306 | } | ||
307 | |||
308 | if (dir == VPD_READ) { | ||
309 | Rtv = VpdReadStream(pAC, IoC, buf, addr, len); | ||
310 | } | ||
311 | else { | ||
312 | Rtv = VpdWriteStream(pAC, IoC, buf, addr, len); | ||
313 | } | ||
314 | |||
315 | return(Rtv); | ||
316 | } | ||
317 | |||
318 | #ifdef SKDIAG | ||
319 | |||
320 | /* | ||
321 | * Read 'len' bytes of VPD data, starting at 'addr'. | ||
322 | * | ||
323 | * Returns number of bytes read. | ||
324 | */ | ||
325 | int VpdReadBlock( | ||
326 | SK_AC *pAC, /* pAC pointer */ | ||
327 | SK_IOC IoC, /* IO Context */ | ||
328 | char *buf, /* buffer were the data should be stored */ | ||
329 | int addr, /* start reading at the VPD address */ | ||
330 | int len) /* number of bytes to read */ | ||
331 | { | ||
332 | return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_READ)); | ||
333 | } | ||
334 | |||
335 | /* | ||
336 | * Write 'len' bytes of *but to the VPD EEPROM, starting at 'addr'. | ||
337 | * | ||
338 | * Returns number of bytes writes. | ||
339 | */ | ||
340 | int VpdWriteBlock( | ||
341 | SK_AC *pAC, /* pAC pointer */ | ||
342 | SK_IOC IoC, /* IO Context */ | ||
343 | char *buf, /* buffer, holds the data to write */ | ||
344 | int addr, /* start writing at the VPD address */ | ||
345 | int len) /* number of bytes to write */ | ||
346 | { | ||
347 | return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_WRITE)); | ||
348 | } | ||
349 | #endif /* SKDIAG */ | ||
350 | |||
351 | /* | ||
352 | * (re)initialize the VPD buffer | ||
353 | * | ||
354 | * Reads the VPD data from the EEPROM into the VPD buffer. | ||
355 | * Get the remaining read only and read / write space. | ||
356 | * | ||
357 | * return 0: success | ||
358 | * 1: fatal VPD error | ||
359 | */ | ||
360 | static int VpdInit( | ||
361 | SK_AC *pAC, /* Adapters context */ | ||
362 | SK_IOC IoC) /* IO Context */ | ||
363 | { | ||
364 | SK_VPD_PARA *r, rp; /* RW or RV */ | ||
365 | int i; | ||
366 | unsigned char x; | ||
367 | int vpd_size; | ||
368 | SK_U16 dev_id; | ||
369 | SK_U32 our_reg2; | ||
370 | |||
371 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT, ("VpdInit .. ")); | ||
372 | |||
373 | VPD_IN16(pAC, IoC, PCI_DEVICE_ID, &dev_id); | ||
374 | |||
375 | VPD_IN32(pAC, IoC, PCI_OUR_REG_2, &our_reg2); | ||
376 | |||
377 | pAC->vpd.rom_size = 256 << ((our_reg2 & PCI_VPD_ROM_SZ) >> 14); | ||
378 | |||
379 | /* | ||
380 | * this function might get used before the hardware is initialized | ||
381 | * therefore we cannot always trust in GIChipId | ||
382 | */ | ||
383 | if (((pAC->vpd.v.vpd_status & VPD_VALID) == 0 && | ||
384 | dev_id != VPD_DEV_ID_GENESIS) || | ||
385 | ((pAC->vpd.v.vpd_status & VPD_VALID) != 0 && | ||
386 | !pAC->GIni.GIGenesis)) { | ||
387 | |||
388 | /* for Yukon the VPD size is always 256 */ | ||
389 | vpd_size = VPD_SIZE_YUKON; | ||
390 | } | ||
391 | else { | ||
392 | /* Genesis uses the maximum ROM size up to 512 for VPD */ | ||
393 | if (pAC->vpd.rom_size > VPD_SIZE_GENESIS) { | ||
394 | vpd_size = VPD_SIZE_GENESIS; | ||
395 | } | ||
396 | else { | ||
397 | vpd_size = pAC->vpd.rom_size; | ||
398 | } | ||
399 | } | ||
400 | |||
401 | /* read the VPD data into the VPD buffer */ | ||
402 | if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf, 0, vpd_size, VPD_READ) | ||
403 | != vpd_size) { | ||
404 | |||
405 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, | ||
406 | ("Block Read Error\n")); | ||
407 | return(1); | ||
408 | } | ||
409 | |||
410 | pAC->vpd.vpd_size = vpd_size; | ||
411 | |||
412 | /* Asus K8V Se Deluxe bugfix. Correct VPD content */ | ||
413 | /* MBo April 2004 */ | ||
414 | if (((unsigned char)pAC->vpd.vpd_buf[0x3f] == 0x38) && | ||
415 | ((unsigned char)pAC->vpd.vpd_buf[0x40] == 0x3c) && | ||
416 | ((unsigned char)pAC->vpd.vpd_buf[0x41] == 0x45)) { | ||
417 | printk("sk98lin: Asus mainboard with buggy VPD? " | ||
418 | "Correcting data.\n"); | ||
419 | pAC->vpd.vpd_buf[0x40] = 0x38; | ||
420 | } | ||
421 | |||
422 | |||
423 | /* find the end tag of the RO area */ | ||
424 | if (!(r = vpd_find_para(pAC, VPD_RV, &rp))) { | ||
425 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, | ||
426 | ("Encoding Error: RV Tag not found\n")); | ||
427 | return(1); | ||
428 | } | ||
429 | |||
430 | if (r->p_val + r->p_len > pAC->vpd.vpd_buf + vpd_size/2) { | ||
431 | SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL, | ||
432 | ("Encoding Error: Invalid VPD struct size\n")); | ||
433 | return(1); | ||
434 | } | ||
435 | pAC->vpd.v.vpd_free_ro = r->p_len - 1; | ||
436 | |||
437 | /* test the checksum */ | ||
438 | for (i = 0, x = 0; (unsigned)i <= (unsigned)vpd_size/2 - r->p_len; i++) { | ||
439 | x += pAC->vpd.vpd_buf[i]; | ||
440 | } | ||
441 | |||
442 | if (x != 0) { | ||
443 | /* checksum error */ | ||
444 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, | ||
445 | ("VPD Checksum Error\n")); | ||
446 | return(1); | ||
447 | } | ||
448 | |||
449 | /* find and check the end tag of the RW area */ | ||
450 | if (!(r = vpd_find_para(pAC, VPD_RW, &rp))) { | ||
451 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, | ||
452 | ("Encoding Error: RV Tag not found\n")); | ||
453 | return(1); | ||
454 | } | ||
455 | |||
456 | if (r->p_val < pAC->vpd.vpd_buf + vpd_size/2) { | ||
457 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, | ||
458 | ("Encoding Error: Invalid VPD struct size\n")); | ||
459 | return(1); | ||
460 | } | ||
461 | pAC->vpd.v.vpd_free_rw = r->p_len; | ||
462 | |||
463 | /* everything seems to be ok */ | ||
464 | if (pAC->GIni.GIChipId != 0) { | ||
465 | pAC->vpd.v.vpd_status |= VPD_VALID; | ||
466 | } | ||
467 | |||
468 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT, | ||
469 | ("done. Free RO = %d, Free RW = %d\n", | ||
470 | pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw)); | ||
471 | |||
472 | return(0); | ||
473 | } | ||
474 | |||
475 | /* | ||
476 | * find the Keyword 'key' in the VPD buffer and fills the | ||
477 | * parameter struct 'p' with it's values | ||
478 | * | ||
479 | * returns *p success | ||
480 | * 0: parameter was not found or VPD encoding error | ||
481 | */ | ||
482 | static SK_VPD_PARA *vpd_find_para( | ||
483 | SK_AC *pAC, /* common data base */ | ||
484 | const char *key, /* keyword to find (e.g. "MN") */ | ||
485 | SK_VPD_PARA *p) /* parameter description struct */ | ||
486 | { | ||
487 | char *v ; /* points to VPD buffer */ | ||
488 | int max; /* Maximum Number of Iterations */ | ||
489 | |||
490 | v = pAC->vpd.vpd_buf; | ||
491 | max = 128; | ||
492 | |||
493 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, | ||
494 | ("VPD find para %s .. ",key)); | ||
495 | |||
496 | /* check mandatory resource type ID string (Product Name) */ | ||
497 | if (*v != (char)RES_ID) { | ||
498 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, | ||
499 | ("Error: 0x%x missing\n", RES_ID)); | ||
500 | return NULL; | ||
501 | } | ||
502 | |||
503 | if (strcmp(key, VPD_NAME) == 0) { | ||
504 | p->p_len = VPD_GET_RES_LEN(v); | ||
505 | p->p_val = VPD_GET_VAL(v); | ||
506 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, | ||
507 | ("found, len = %d\n", p->p_len)); | ||
508 | return(p); | ||
509 | } | ||
510 | |||
511 | v += 3 + VPD_GET_RES_LEN(v) + 3; | ||
512 | for (;; ) { | ||
513 | if (SK_MEMCMP(key,v,2) == 0) { | ||
514 | p->p_len = VPD_GET_VPD_LEN(v); | ||
515 | p->p_val = VPD_GET_VAL(v); | ||
516 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, | ||
517 | ("found, len = %d\n",p->p_len)); | ||
518 | return(p); | ||
519 | } | ||
520 | |||
521 | /* exit when reaching the "RW" Tag or the maximum of itera. */ | ||
522 | max--; | ||
523 | if (SK_MEMCMP(VPD_RW,v,2) == 0 || max == 0) { | ||
524 | break; | ||
525 | } | ||
526 | |||
527 | if (SK_MEMCMP(VPD_RV,v,2) == 0) { | ||
528 | v += 3 + VPD_GET_VPD_LEN(v) + 3; /* skip VPD-W */ | ||
529 | } | ||
530 | else { | ||
531 | v += 3 + VPD_GET_VPD_LEN(v); | ||
532 | } | ||
533 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, | ||
534 | ("scanning '%c%c' len = %d\n",v[0],v[1],v[2])); | ||
535 | } | ||
536 | |||
537 | #ifdef DEBUG | ||
538 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, ("not found\n")); | ||
539 | if (max == 0) { | ||
540 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, | ||
541 | ("Key/Len Encoding error\n")); | ||
542 | } | ||
543 | #endif /* DEBUG */ | ||
544 | return NULL; | ||
545 | } | ||
546 | |||
547 | /* | ||
548 | * Move 'n' bytes. Begin with the last byte if 'n' is > 0, | ||
549 | * Start with the last byte if n is < 0. | ||
550 | * | ||
551 | * returns nothing | ||
552 | */ | ||
553 | static void vpd_move_para( | ||
554 | char *start, /* start of memory block */ | ||
555 | char *end, /* end of memory block to move */ | ||
556 | int n) /* number of bytes the memory block has to be moved */ | ||
557 | { | ||
558 | char *p; | ||
559 | int i; /* number of byte copied */ | ||
560 | |||
561 | if (n == 0) | ||
562 | return; | ||
563 | |||
564 | i = (int) (end - start + 1); | ||
565 | if (n < 0) { | ||
566 | p = start + n; | ||
567 | while (i != 0) { | ||
568 | *p++ = *start++; | ||
569 | i--; | ||
570 | } | ||
571 | } | ||
572 | else { | ||
573 | p = end + n; | ||
574 | while (i != 0) { | ||
575 | *p-- = *end--; | ||
576 | i--; | ||
577 | } | ||
578 | } | ||
579 | } | ||
580 | |||
581 | /* | ||
582 | * setup the VPD keyword 'key' at 'ip'. | ||
583 | * | ||
584 | * returns nothing | ||
585 | */ | ||
586 | static void vpd_insert_key( | ||
587 | const char *key, /* keyword to insert */ | ||
588 | const char *buf, /* buffer with the keyword value */ | ||
589 | int len, /* length of the value string */ | ||
590 | char *ip) /* inseration point */ | ||
591 | { | ||
592 | SK_VPD_KEY *p; | ||
593 | |||
594 | p = (SK_VPD_KEY *) ip; | ||
595 | p->p_key[0] = key[0]; | ||
596 | p->p_key[1] = key[1]; | ||
597 | p->p_len = (unsigned char) len; | ||
598 | SK_MEMCPY(&p->p_val,buf,len); | ||
599 | } | ||
600 | |||
601 | /* | ||
602 | * Setup the VPD end tag "RV" / "RW". | ||
603 | * Also correct the remaining space variables vpd_free_ro / vpd_free_rw. | ||
604 | * | ||
605 | * returns 0: success | ||
606 | * 1: encoding error | ||
607 | */ | ||
608 | static int vpd_mod_endtag( | ||
609 | SK_AC *pAC, /* common data base */ | ||
610 | char *etp) /* end pointer input position */ | ||
611 | { | ||
612 | SK_VPD_KEY *p; | ||
613 | unsigned char x; | ||
614 | int i; | ||
615 | int vpd_size; | ||
616 | |||
617 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, | ||
618 | ("VPD modify endtag at 0x%x = '%c%c'\n",etp,etp[0],etp[1])); | ||
619 | |||
620 | vpd_size = pAC->vpd.vpd_size; | ||
621 | |||
622 | p = (SK_VPD_KEY *) etp; | ||
623 | |||
624 | if (p->p_key[0] != 'R' || (p->p_key[1] != 'V' && p->p_key[1] != 'W')) { | ||
625 | /* something wrong here, encoding error */ | ||
626 | SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL, | ||
627 | ("Encoding Error: invalid end tag\n")); | ||
628 | return(1); | ||
629 | } | ||
630 | if (etp > pAC->vpd.vpd_buf + vpd_size/2) { | ||
631 | /* create "RW" tag */ | ||
632 | p->p_len = (unsigned char)(pAC->vpd.vpd_buf+vpd_size-etp-3-1); | ||
633 | pAC->vpd.v.vpd_free_rw = (int) p->p_len; | ||
634 | i = pAC->vpd.v.vpd_free_rw; | ||
635 | etp += 3; | ||
636 | } | ||
637 | else { | ||
638 | /* create "RV" tag */ | ||
639 | p->p_len = (unsigned char)(pAC->vpd.vpd_buf+vpd_size/2-etp-3); | ||
640 | pAC->vpd.v.vpd_free_ro = (int) p->p_len - 1; | ||
641 | |||
642 | /* setup checksum */ | ||
643 | for (i = 0, x = 0; i < vpd_size/2 - p->p_len; i++) { | ||
644 | x += pAC->vpd.vpd_buf[i]; | ||
645 | } | ||
646 | p->p_val = (char) 0 - x; | ||
647 | i = pAC->vpd.v.vpd_free_ro; | ||
648 | etp += 4; | ||
649 | } | ||
650 | while (i) { | ||
651 | *etp++ = 0x00; | ||
652 | i--; | ||
653 | } | ||
654 | |||
655 | return(0); | ||
656 | } | ||
657 | |||
658 | /* | ||
659 | * Insert a VPD keyword into the VPD buffer. | ||
660 | * | ||
661 | * The keyword 'key' is inserted at the position 'ip' in the | ||
662 | * VPD buffer. | ||
663 | * The keywords behind the input position will | ||
664 | * be moved. The VPD end tag "RV" or "RW" is generated again. | ||
665 | * | ||
666 | * returns 0: success | ||
667 | * 2: value string was cut | ||
668 | * 4: VPD full, keyword was not written | ||
669 | * 6: fatal VPD error | ||
670 | * | ||
671 | */ | ||
672 | static int VpdSetupPara( | ||
673 | SK_AC *pAC, /* common data base */ | ||
674 | const char *key, /* keyword to insert */ | ||
675 | const char *buf, /* buffer with the keyword value */ | ||
676 | int len, /* length of the keyword value */ | ||
677 | int type, /* VPD_RO_KEY or VPD_RW_KEY */ | ||
678 | int op) /* operation to do: ADD_KEY or OWR_KEY */ | ||
679 | { | ||
680 | SK_VPD_PARA vp; | ||
681 | char *etp; /* end tag position */ | ||
682 | int free; /* remaining space in selected area */ | ||
683 | char *ip; /* input position inside the VPD buffer */ | ||
684 | int rtv; /* return code */ | ||
685 | int head; /* additional haeder bytes to move */ | ||
686 | int found; /* additinoal bytes if the keyword was found */ | ||
687 | int vpd_size; | ||
688 | |||
689 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, | ||
690 | ("VPD setup para key = %s, val = %s\n",key,buf)); | ||
691 | |||
692 | vpd_size = pAC->vpd.vpd_size; | ||
693 | |||
694 | rtv = 0; | ||
695 | ip = NULL; | ||
696 | if (type == VPD_RW_KEY) { | ||
697 | /* end tag is "RW" */ | ||
698 | free = pAC->vpd.v.vpd_free_rw; | ||
699 | etp = pAC->vpd.vpd_buf + (vpd_size - free - 1 - 3); | ||
700 | } | ||
701 | else { | ||
702 | /* end tag is "RV" */ | ||
703 | free = pAC->vpd.v.vpd_free_ro; | ||
704 | etp = pAC->vpd.vpd_buf + (vpd_size/2 - free - 4); | ||
705 | } | ||
706 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, | ||
707 | ("Free RO = %d, Free RW = %d\n", | ||
708 | pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw)); | ||
709 | |||
710 | head = 0; | ||
711 | found = 0; | ||
712 | if (op == OWR_KEY) { | ||
713 | if (vpd_find_para(pAC, key, &vp)) { | ||
714 | found = 3; | ||
715 | ip = vp.p_val - 3; | ||
716 | free += vp.p_len + 3; | ||
717 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, | ||
718 | ("Overwrite Key\n")); | ||
719 | } | ||
720 | else { | ||
721 | op = ADD_KEY; | ||
722 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, | ||
723 | ("Add Key\n")); | ||
724 | } | ||
725 | } | ||
726 | if (op == ADD_KEY) { | ||
727 | ip = etp; | ||
728 | vp.p_len = 0; | ||
729 | head = 3; | ||
730 | } | ||
731 | |||
732 | if (len + 3 > free) { | ||
733 | if (free < 7) { | ||
734 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, | ||
735 | ("VPD Buffer Overflow, keyword not written\n")); | ||
736 | return(4); | ||
737 | } | ||
738 | /* cut it again */ | ||
739 | len = free - 3; | ||
740 | rtv = 2; | ||
741 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, | ||
742 | ("VPD Buffer Full, Keyword was cut\n")); | ||
743 | } | ||
744 | |||
745 | vpd_move_para(ip + vp.p_len + found, etp+2, len-vp.p_len+head); | ||
746 | vpd_insert_key(key, buf, len, ip); | ||
747 | if (vpd_mod_endtag(pAC, etp + len - vp.p_len + head)) { | ||
748 | pAC->vpd.v.vpd_status &= ~VPD_VALID; | ||
749 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, | ||
750 | ("VPD Encoding Error\n")); | ||
751 | return(6); | ||
752 | } | ||
753 | |||
754 | return(rtv); | ||
755 | } | ||
756 | |||
757 | |||
758 | /* | ||
759 | * Read the contents of the VPD EEPROM and copy it to the | ||
760 | * VPD buffer if not already done. | ||
761 | * | ||
762 | * return: A pointer to the vpd_status structure. The structure contains | ||
763 | * this fields. | ||
764 | */ | ||
765 | SK_VPD_STATUS *VpdStat( | ||
766 | SK_AC *pAC, /* Adapters context */ | ||
767 | SK_IOC IoC) /* IO Context */ | ||
768 | { | ||
769 | if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { | ||
770 | (void)VpdInit(pAC, IoC); | ||
771 | } | ||
772 | return(&pAC->vpd.v); | ||
773 | } | ||
774 | |||
775 | |||
776 | /* | ||
777 | * Read the contents of the VPD EEPROM and copy it to the VPD | ||
778 | * buffer if not already done. | ||
779 | * Scan the VPD buffer for VPD keywords and create the VPD | ||
780 | * keyword list by copying the keywords to 'buf', all after | ||
781 | * each other and terminated with a '\0'. | ||
782 | * | ||
783 | * Exceptions: o The Resource Type ID String (product name) is called "Name" | ||
784 | * o The VPD end tags 'RV' and 'RW' are not listed | ||
785 | * | ||
786 | * The number of copied keywords is counted in 'elements'. | ||
787 | * | ||
788 | * returns 0: success | ||
789 | * 2: buffer overfull, one or more keywords are missing | ||
790 | * 6: fatal VPD error | ||
791 | * | ||
792 | * example values after returning: | ||
793 | * | ||
794 | * buf = "Name\0PN\0EC\0MN\0SN\0CP\0VF\0VL\0YA\0" | ||
795 | * *len = 30 | ||
796 | * *elements = 9 | ||
797 | */ | ||
798 | int VpdKeys( | ||
799 | SK_AC *pAC, /* common data base */ | ||
800 | SK_IOC IoC, /* IO Context */ | ||
801 | char *buf, /* buffer where to copy the keywords */ | ||
802 | int *len, /* buffer length */ | ||
803 | int *elements) /* number of keywords returned */ | ||
804 | { | ||
805 | char *v; | ||
806 | int n; | ||
807 | |||
808 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("list VPD keys .. ")); | ||
809 | *elements = 0; | ||
810 | if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { | ||
811 | if (VpdInit(pAC, IoC) != 0) { | ||
812 | *len = 0; | ||
813 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, | ||
814 | ("VPD Init Error, terminated\n")); | ||
815 | return(6); | ||
816 | } | ||
817 | } | ||
818 | |||
819 | if ((signed)strlen(VPD_NAME) + 1 <= *len) { | ||
820 | v = pAC->vpd.vpd_buf; | ||
821 | strcpy(buf,VPD_NAME); | ||
822 | n = strlen(VPD_NAME) + 1; | ||
823 | buf += n; | ||
824 | *elements = 1; | ||
825 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, | ||
826 | ("'%c%c' ",v[0],v[1])); | ||
827 | } | ||
828 | else { | ||
829 | *len = 0; | ||
830 | SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, | ||
831 | ("buffer overflow\n")); | ||
832 | return(2); | ||
833 | } | ||
834 | |||
835 | v += 3 + VPD_GET_RES_LEN(v) + 3; | ||
836 | for (;; ) { | ||
837 | /* exit when reaching the "RW" Tag */ | ||
838 | if (SK_MEMCMP(VPD_RW,v,2) == 0) { | ||
839 | break; | ||
840 | } | ||
841 | |||
842 | if (SK_MEMCMP(VPD_RV,v,2) == 0) { | ||
843 | v += 3 + VPD_GET_VPD_LEN(v) + 3; /* skip VPD-W */ | ||
844 | continue; | ||
845 | } | ||
846 | |||
847 | if (n+3 <= *len) { | ||
848 | SK_MEMCPY(buf,v,2); | ||
849 | buf += 2; | ||
850 | *buf++ = '\0'; | ||
851 | n += 3; | ||
852 | v += 3 + VPD_GET_VPD_LEN(v); | ||
853 | *elements += 1; | ||
854 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, | ||
855 | ("'%c%c' ",v[0],v[1])); | ||
856 | } | ||
857 | else { | ||
858 | *len = n; | ||
859 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, | ||
860 | ("buffer overflow\n")); | ||
861 | return(2); | ||
862 | } | ||
863 | } | ||
864 | |||
865 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("\n")); | ||
866 | *len = n; | ||
867 | return(0); | ||
868 | } | ||
869 | |||
870 | |||
871 | /* | ||
872 | * Read the contents of the VPD EEPROM and copy it to the | ||
873 | * VPD buffer if not already done. Search for the VPD keyword | ||
874 | * 'key' and copy its value to 'buf'. Add a terminating '\0'. | ||
875 | * If the value does not fit into the buffer cut it after | ||
876 | * 'len' - 1 bytes. | ||
877 | * | ||
878 | * returns 0: success | ||
879 | * 1: keyword not found | ||
880 | * 2: value string was cut | ||
881 | * 3: VPD transfer timeout | ||
882 | * 6: fatal VPD error | ||
883 | */ | ||
884 | int VpdRead( | ||
885 | SK_AC *pAC, /* common data base */ | ||
886 | SK_IOC IoC, /* IO Context */ | ||
887 | const char *key, /* keyword to read (e.g. "MN") */ | ||
888 | char *buf, /* buffer where to copy the keyword value */ | ||
889 | int *len) /* buffer length */ | ||
890 | { | ||
891 | SK_VPD_PARA *p, vp; | ||
892 | |||
893 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("VPD read %s .. ", key)); | ||
894 | if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { | ||
895 | if (VpdInit(pAC, IoC) != 0) { | ||
896 | *len = 0; | ||
897 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, | ||
898 | ("VPD init error\n")); | ||
899 | return(6); | ||
900 | } | ||
901 | } | ||
902 | |||
903 | if ((p = vpd_find_para(pAC, key, &vp)) != NULL) { | ||
904 | if (p->p_len > (*(unsigned *)len)-1) { | ||
905 | p->p_len = *len - 1; | ||
906 | } | ||
907 | SK_MEMCPY(buf, p->p_val, p->p_len); | ||
908 | buf[p->p_len] = '\0'; | ||
909 | *len = p->p_len; | ||
910 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, | ||
911 | ("%c%c%c%c.., len = %d\n", | ||
912 | buf[0],buf[1],buf[2],buf[3],*len)); | ||
913 | } | ||
914 | else { | ||
915 | *len = 0; | ||
916 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("not found\n")); | ||
917 | return(1); | ||
918 | } | ||
919 | return(0); | ||
920 | } | ||
921 | |||
922 | |||
923 | /* | ||
924 | * Check whether a given key may be written | ||
925 | * | ||
926 | * returns | ||
927 | * SK_TRUE Yes it may be written | ||
928 | * SK_FALSE No it may be written | ||
929 | */ | ||
930 | SK_BOOL VpdMayWrite( | ||
931 | char *key) /* keyword to write (allowed values "Yx", "Vx") */ | ||
932 | { | ||
933 | if ((*key != 'Y' && *key != 'V') || | ||
934 | key[1] < '0' || key[1] > 'Z' || | ||
935 | (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) { | ||
936 | |||
937 | return(SK_FALSE); | ||
938 | } | ||
939 | return(SK_TRUE); | ||
940 | } | ||
941 | |||
942 | /* | ||
943 | * Read the contents of the VPD EEPROM and copy it to the VPD | ||
944 | * buffer if not already done. Insert/overwrite the keyword 'key' | ||
945 | * in the VPD buffer. Cut the keyword value if it does not fit | ||
946 | * into the VPD read / write area. | ||
947 | * | ||
948 | * returns 0: success | ||
949 | * 2: value string was cut | ||
950 | * 3: VPD transfer timeout | ||
951 | * 4: VPD full, keyword was not written | ||
952 | * 5: keyword cannot be written | ||
953 | * 6: fatal VPD error | ||
954 | */ | ||
955 | int VpdWrite( | ||
956 | SK_AC *pAC, /* common data base */ | ||
957 | SK_IOC IoC, /* IO Context */ | ||
958 | const char *key, /* keyword to write (allowed values "Yx", "Vx") */ | ||
959 | const char *buf) /* buffer where the keyword value can be read from */ | ||
960 | { | ||
961 | int len; /* length of the keyword to write */ | ||
962 | int rtv; /* return code */ | ||
963 | int rtv2; | ||
964 | |||
965 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, | ||
966 | ("VPD write %s = %s\n",key,buf)); | ||
967 | |||
968 | if ((*key != 'Y' && *key != 'V') || | ||
969 | key[1] < '0' || key[1] > 'Z' || | ||
970 | (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) { | ||
971 | |||
972 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, | ||
973 | ("illegal key tag, keyword not written\n")); | ||
974 | return(5); | ||
975 | } | ||
976 | |||
977 | if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { | ||
978 | if (VpdInit(pAC, IoC) != 0) { | ||
979 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, | ||
980 | ("VPD init error\n")); | ||
981 | return(6); | ||
982 | } | ||
983 | } | ||
984 | |||
985 | rtv = 0; | ||
986 | len = strlen(buf); | ||
987 | if (len > VPD_MAX_LEN) { | ||
988 | /* cut it */ | ||
989 | len = VPD_MAX_LEN; | ||
990 | rtv = 2; | ||
991 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, | ||
992 | ("keyword too long, cut after %d bytes\n",VPD_MAX_LEN)); | ||
993 | } | ||
994 | if ((rtv2 = VpdSetupPara(pAC, key, buf, len, VPD_RW_KEY, OWR_KEY)) != 0) { | ||
995 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, | ||
996 | ("VPD write error\n")); | ||
997 | return(rtv2); | ||
998 | } | ||
999 | |||
1000 | return(rtv); | ||
1001 | } | ||
1002 | |||
1003 | /* | ||
1004 | * Read the contents of the VPD EEPROM and copy it to the | ||
1005 | * VPD buffer if not already done. Remove the VPD keyword | ||
1006 | * 'key' from the VPD buffer. | ||
1007 | * Only the keywords in the read/write area can be deleted. | ||
1008 | * Keywords in the read only area cannot be deleted. | ||
1009 | * | ||
1010 | * returns 0: success, keyword was removed | ||
1011 | * 1: keyword not found | ||
1012 | * 5: keyword cannot be deleted | ||
1013 | * 6: fatal VPD error | ||
1014 | */ | ||
1015 | int VpdDelete( | ||
1016 | SK_AC *pAC, /* common data base */ | ||
1017 | SK_IOC IoC, /* IO Context */ | ||
1018 | char *key) /* keyword to read (e.g. "MN") */ | ||
1019 | { | ||
1020 | SK_VPD_PARA *p, vp; | ||
1021 | char *etp; | ||
1022 | int vpd_size; | ||
1023 | |||
1024 | vpd_size = pAC->vpd.vpd_size; | ||
1025 | |||
1026 | SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("VPD delete key %s\n",key)); | ||
1027 | if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { | ||
1028 | if (VpdInit(pAC, IoC) != 0) { | ||
1029 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, | ||
1030 | ("VPD init error\n")); | ||
1031 | return(6); | ||
1032 | } | ||
1033 | } | ||
1034 | |||
1035 | if ((p = vpd_find_para(pAC, key, &vp)) != NULL) { | ||
1036 | if (p->p_val < pAC->vpd.vpd_buf + vpd_size/2) { | ||
1037 | /* try to delete read only keyword */ | ||
1038 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, | ||
1039 | ("cannot delete RO keyword\n")); | ||
1040 | return(5); | ||
1041 | } | ||
1042 | |||
1043 | etp = pAC->vpd.vpd_buf + (vpd_size-pAC->vpd.v.vpd_free_rw-1-3); | ||
1044 | |||
1045 | vpd_move_para(vp.p_val+vp.p_len, etp+2, | ||
1046 | - ((int)(vp.p_len + 3))); | ||
1047 | if (vpd_mod_endtag(pAC, etp - vp.p_len - 3)) { | ||
1048 | pAC->vpd.v.vpd_status &= ~VPD_VALID; | ||
1049 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, | ||
1050 | ("VPD encoding error\n")); | ||
1051 | return(6); | ||
1052 | } | ||
1053 | } | ||
1054 | else { | ||
1055 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, | ||
1056 | ("keyword not found\n")); | ||
1057 | return(1); | ||
1058 | } | ||
1059 | |||
1060 | return(0); | ||
1061 | } | ||
1062 | |||
1063 | /* | ||
1064 | * If the VPD buffer contains valid data write the VPD | ||
1065 | * read/write area back to the VPD EEPROM. | ||
1066 | * | ||
1067 | * returns 0: success | ||
1068 | * 3: VPD transfer timeout | ||
1069 | */ | ||
1070 | int VpdUpdate( | ||
1071 | SK_AC *pAC, /* Adapters context */ | ||
1072 | SK_IOC IoC) /* IO Context */ | ||
1073 | { | ||
1074 | int vpd_size; | ||
1075 | |||
1076 | vpd_size = pAC->vpd.vpd_size; | ||
1077 | |||
1078 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("VPD update .. ")); | ||
1079 | if ((pAC->vpd.v.vpd_status & VPD_VALID) != 0) { | ||
1080 | if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf + vpd_size/2, | ||
1081 | vpd_size/2, vpd_size/2, VPD_WRITE) != vpd_size/2) { | ||
1082 | |||
1083 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, | ||
1084 | ("transfer timed out\n")); | ||
1085 | return(3); | ||
1086 | } | ||
1087 | } | ||
1088 | SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("done\n")); | ||
1089 | return(0); | ||
1090 | } | ||
1091 | |||
diff --git a/drivers/net/sk98lin/skxmac2.c b/drivers/net/sk98lin/skxmac2.c new file mode 100644 index 000000000000..b4e75022a657 --- /dev/null +++ b/drivers/net/sk98lin/skxmac2.c | |||
@@ -0,0 +1,4160 @@ | |||
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 | static 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 | static 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 | static 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 | #ifdef GENESIS | ||
1235 | /****************************************************************************** | ||
1236 | * | ||
1237 | * SkXmInitMac() - Initialize the XMAC II | ||
1238 | * | ||
1239 | * Description: | ||
1240 | * Initialize the XMAC of the specified port. | ||
1241 | * The XMAC must be reset or stopped before calling this function. | ||
1242 | * | ||
1243 | * Note: | ||
1244 | * The XMAC's Rx and Tx state machine is still disabled when returning. | ||
1245 | * | ||
1246 | * Returns: | ||
1247 | * nothing | ||
1248 | */ | ||
1249 | void SkXmInitMac( | ||
1250 | SK_AC *pAC, /* adapter context */ | ||
1251 | SK_IOC IoC, /* IO context */ | ||
1252 | int Port) /* Port Index (MAC_1 + n) */ | ||
1253 | { | ||
1254 | SK_GEPORT *pPrt; | ||
1255 | int i; | ||
1256 | SK_U16 SWord; | ||
1257 | |||
1258 | pPrt = &pAC->GIni.GP[Port]; | ||
1259 | |||
1260 | if (pPrt->PState == SK_PRT_STOP) { | ||
1261 | /* Port State: SK_PRT_STOP */ | ||
1262 | /* Verify that the reset bit is cleared */ | ||
1263 | SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord); | ||
1264 | |||
1265 | if ((SWord & MFF_SET_MAC_RST) != 0) { | ||
1266 | /* PState does not match HW state */ | ||
1267 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG); | ||
1268 | /* Correct it */ | ||
1269 | pPrt->PState = SK_PRT_RESET; | ||
1270 | } | ||
1271 | } | ||
1272 | |||
1273 | if (pPrt->PState == SK_PRT_RESET) { | ||
1274 | |||
1275 | SkXmClearRst(pAC, IoC, Port); | ||
1276 | |||
1277 | if (pPrt->PhyType != SK_PHY_XMAC) { | ||
1278 | /* read Id from external PHY (all have the same address) */ | ||
1279 | SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_ID1, &pPrt->PhyId1); | ||
1280 | |||
1281 | /* | ||
1282 | * Optimize MDIO transfer by suppressing preamble. | ||
1283 | * Must be done AFTER first access to BCOM chip. | ||
1284 | */ | ||
1285 | XM_IN16(IoC, Port, XM_MMU_CMD, &SWord); | ||
1286 | |||
1287 | XM_OUT16(IoC, Port, XM_MMU_CMD, SWord | XM_MMU_NO_PRE); | ||
1288 | |||
1289 | if (pPrt->PhyId1 == PHY_BCOM_ID1_C0) { | ||
1290 | /* | ||
1291 | * Workaround BCOM Errata for the C0 type. | ||
1292 | * Write magic patterns to reserved registers. | ||
1293 | */ | ||
1294 | i = 0; | ||
1295 | while (BcomRegC0Hack[i].PhyReg != 0) { | ||
1296 | SkXmPhyWrite(pAC, IoC, Port, BcomRegC0Hack[i].PhyReg, | ||
1297 | BcomRegC0Hack[i].PhyVal); | ||
1298 | i++; | ||
1299 | } | ||
1300 | } | ||
1301 | else if (pPrt->PhyId1 == PHY_BCOM_ID1_A1) { | ||
1302 | /* | ||
1303 | * Workaround BCOM Errata for the A1 type. | ||
1304 | * Write magic patterns to reserved registers. | ||
1305 | */ | ||
1306 | i = 0; | ||
1307 | while (BcomRegA1Hack[i].PhyReg != 0) { | ||
1308 | SkXmPhyWrite(pAC, IoC, Port, BcomRegA1Hack[i].PhyReg, | ||
1309 | BcomRegA1Hack[i].PhyVal); | ||
1310 | i++; | ||
1311 | } | ||
1312 | } | ||
1313 | |||
1314 | /* | ||
1315 | * Workaround BCOM Errata (#10523) for all BCom PHYs. | ||
1316 | * Disable Power Management after reset. | ||
1317 | */ | ||
1318 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord); | ||
1319 | |||
1320 | SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, | ||
1321 | (SK_U16)(SWord | PHY_B_AC_DIS_PM)); | ||
1322 | |||
1323 | /* PHY LED initialization is done in SkGeXmitLED() */ | ||
1324 | } | ||
1325 | |||
1326 | /* Dummy read the Interrupt source register */ | ||
1327 | XM_IN16(IoC, Port, XM_ISRC, &SWord); | ||
1328 | |||
1329 | /* | ||
1330 | * The auto-negotiation process starts immediately after | ||
1331 | * clearing the reset. The auto-negotiation process should be | ||
1332 | * started by the SIRQ, therefore stop it here immediately. | ||
1333 | */ | ||
1334 | SkMacInitPhy(pAC, IoC, Port, SK_FALSE); | ||
1335 | |||
1336 | #ifdef TEST_ONLY | ||
1337 | /* temp. code: enable signal detect */ | ||
1338 | /* WARNING: do not override GMII setting above */ | ||
1339 | XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_COM4SIG); | ||
1340 | #endif | ||
1341 | } | ||
1342 | |||
1343 | /* | ||
1344 | * configure the XMACs Station Address | ||
1345 | * B2_MAC_2 = xx xx xx xx xx x1 is programmed to XMAC A | ||
1346 | * B2_MAC_3 = xx xx xx xx xx x2 is programmed to XMAC B | ||
1347 | */ | ||
1348 | for (i = 0; i < 3; i++) { | ||
1349 | /* | ||
1350 | * The following 2 statements are together endianess | ||
1351 | * independent. Remember this when changing. | ||
1352 | */ | ||
1353 | SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord); | ||
1354 | |||
1355 | XM_OUT16(IoC, Port, (XM_SA + i * 2), SWord); | ||
1356 | } | ||
1357 | |||
1358 | /* Tx Inter Packet Gap (XM_TX_IPG): use default */ | ||
1359 | /* Tx High Water Mark (XM_TX_HI_WM): use default */ | ||
1360 | /* Tx Low Water Mark (XM_TX_LO_WM): use default */ | ||
1361 | /* Host Request Threshold (XM_HT_THR): use default */ | ||
1362 | /* Rx Request Threshold (XM_RX_THR): use default */ | ||
1363 | /* Rx Low Water Mark (XM_RX_LO_WM): use default */ | ||
1364 | |||
1365 | /* configure Rx High Water Mark (XM_RX_HI_WM) */ | ||
1366 | XM_OUT16(IoC, Port, XM_RX_HI_WM, SK_XM_RX_HI_WM); | ||
1367 | |||
1368 | /* Configure Tx Request Threshold */ | ||
1369 | SWord = SK_XM_THR_SL; /* for single port */ | ||
1370 | |||
1371 | if (pAC->GIni.GIMacsFound > 1) { | ||
1372 | switch (pAC->GIni.GIPortUsage) { | ||
1373 | case SK_RED_LINK: | ||
1374 | SWord = SK_XM_THR_REDL; /* redundant link */ | ||
1375 | break; | ||
1376 | case SK_MUL_LINK: | ||
1377 | SWord = SK_XM_THR_MULL; /* load balancing */ | ||
1378 | break; | ||
1379 | case SK_JUMBO_LINK: | ||
1380 | SWord = SK_XM_THR_JUMBO; /* jumbo frames */ | ||
1381 | break; | ||
1382 | default: | ||
1383 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E014, SKERR_HWI_E014MSG); | ||
1384 | break; | ||
1385 | } | ||
1386 | } | ||
1387 | XM_OUT16(IoC, Port, XM_TX_THR, SWord); | ||
1388 | |||
1389 | /* setup register defaults for the Tx Command Register */ | ||
1390 | XM_OUT16(IoC, Port, XM_TX_CMD, XM_TX_AUTO_PAD); | ||
1391 | |||
1392 | /* setup register defaults for the Rx Command Register */ | ||
1393 | SWord = XM_RX_STRIP_FCS | XM_RX_LENERR_OK; | ||
1394 | |||
1395 | if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { | ||
1396 | SWord |= XM_RX_BIG_PK_OK; | ||
1397 | } | ||
1398 | |||
1399 | if (pPrt->PLinkMode == SK_LMODE_HALF) { | ||
1400 | /* | ||
1401 | * If in manual half duplex mode the other side might be in | ||
1402 | * full duplex mode, so ignore if a carrier extension is not seen | ||
1403 | * on frames received | ||
1404 | */ | ||
1405 | SWord |= XM_RX_DIS_CEXT; | ||
1406 | } | ||
1407 | |||
1408 | XM_OUT16(IoC, Port, XM_RX_CMD, SWord); | ||
1409 | |||
1410 | /* | ||
1411 | * setup register defaults for the Mode Register | ||
1412 | * - Don't strip error frames to avoid Store & Forward | ||
1413 | * on the Rx side. | ||
1414 | * - Enable 'Check Station Address' bit | ||
1415 | * - Enable 'Check Address Array' bit | ||
1416 | */ | ||
1417 | XM_OUT32(IoC, Port, XM_MODE, XM_DEF_MODE); | ||
1418 | |||
1419 | /* | ||
1420 | * Initialize the Receive Counter Event Mask (XM_RX_EV_MSK) | ||
1421 | * - Enable all bits excepting 'Octets Rx OK Low CntOv' | ||
1422 | * and 'Octets Rx OK Hi Cnt Ov'. | ||
1423 | */ | ||
1424 | XM_OUT32(IoC, Port, XM_RX_EV_MSK, XMR_DEF_MSK); | ||
1425 | |||
1426 | /* | ||
1427 | * Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK) | ||
1428 | * - Enable all bits excepting 'Octets Tx OK Low CntOv' | ||
1429 | * and 'Octets Tx OK Hi Cnt Ov'. | ||
1430 | */ | ||
1431 | XM_OUT32(IoC, Port, XM_TX_EV_MSK, XMT_DEF_MSK); | ||
1432 | |||
1433 | /* | ||
1434 | * Do NOT init XMAC interrupt mask here. | ||
1435 | * All interrupts remain disable until link comes up! | ||
1436 | */ | ||
1437 | |||
1438 | /* | ||
1439 | * Any additional configuration changes may be done now. | ||
1440 | * The last action is to enable the Rx and Tx state machine. | ||
1441 | * This should be done after the auto-negotiation process | ||
1442 | * has been completed successfully. | ||
1443 | */ | ||
1444 | } /* SkXmInitMac */ | ||
1445 | #endif /* GENESIS */ | ||
1446 | |||
1447 | |||
1448 | #ifdef YUKON | ||
1449 | /****************************************************************************** | ||
1450 | * | ||
1451 | * SkGmInitMac() - Initialize the GMAC | ||
1452 | * | ||
1453 | * Description: | ||
1454 | * Initialize the GMAC of the specified port. | ||
1455 | * The GMAC must be reset or stopped before calling this function. | ||
1456 | * | ||
1457 | * Note: | ||
1458 | * The GMAC's Rx and Tx state machine is still disabled when returning. | ||
1459 | * | ||
1460 | * Returns: | ||
1461 | * nothing | ||
1462 | */ | ||
1463 | void SkGmInitMac( | ||
1464 | SK_AC *pAC, /* adapter context */ | ||
1465 | SK_IOC IoC, /* IO context */ | ||
1466 | int Port) /* Port Index (MAC_1 + n) */ | ||
1467 | { | ||
1468 | SK_GEPORT *pPrt; | ||
1469 | int i; | ||
1470 | SK_U16 SWord; | ||
1471 | SK_U32 DWord; | ||
1472 | |||
1473 | pPrt = &pAC->GIni.GP[Port]; | ||
1474 | |||
1475 | if (pPrt->PState == SK_PRT_STOP) { | ||
1476 | /* Port State: SK_PRT_STOP */ | ||
1477 | /* Verify that the reset bit is cleared */ | ||
1478 | SK_IN32(IoC, MR_ADDR(Port, GMAC_CTRL), &DWord); | ||
1479 | |||
1480 | if ((DWord & GMC_RST_SET) != 0) { | ||
1481 | /* PState does not match HW state */ | ||
1482 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG); | ||
1483 | /* Correct it */ | ||
1484 | pPrt->PState = SK_PRT_RESET; | ||
1485 | } | ||
1486 | } | ||
1487 | |||
1488 | if (pPrt->PState == SK_PRT_RESET) { | ||
1489 | |||
1490 | SkGmHardRst(pAC, IoC, Port); | ||
1491 | |||
1492 | SkGmClearRst(pAC, IoC, Port); | ||
1493 | |||
1494 | /* Auto-negotiation ? */ | ||
1495 | if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { | ||
1496 | /* Auto-negotiation disabled */ | ||
1497 | |||
1498 | /* get General Purpose Control */ | ||
1499 | GM_IN16(IoC, Port, GM_GP_CTRL, &SWord); | ||
1500 | |||
1501 | /* disable auto-update for speed, duplex and flow-control */ | ||
1502 | SWord |= GM_GPCR_AU_ALL_DIS; | ||
1503 | |||
1504 | /* setup General Purpose Control Register */ | ||
1505 | GM_OUT16(IoC, Port, GM_GP_CTRL, SWord); | ||
1506 | |||
1507 | SWord = GM_GPCR_AU_ALL_DIS; | ||
1508 | } | ||
1509 | else { | ||
1510 | SWord = 0; | ||
1511 | } | ||
1512 | |||
1513 | /* speed settings */ | ||
1514 | switch (pPrt->PLinkSpeed) { | ||
1515 | case SK_LSPEED_AUTO: | ||
1516 | case SK_LSPEED_1000MBPS: | ||
1517 | SWord |= GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100; | ||
1518 | break; | ||
1519 | case SK_LSPEED_100MBPS: | ||
1520 | SWord |= GM_GPCR_SPEED_100; | ||
1521 | break; | ||
1522 | case SK_LSPEED_10MBPS: | ||
1523 | break; | ||
1524 | } | ||
1525 | |||
1526 | /* duplex settings */ | ||
1527 | if (pPrt->PLinkMode != SK_LMODE_HALF) { | ||
1528 | /* set full duplex */ | ||
1529 | SWord |= GM_GPCR_DUP_FULL; | ||
1530 | } | ||
1531 | |||
1532 | /* flow-control settings */ | ||
1533 | switch (pPrt->PFlowCtrlMode) { | ||
1534 | case SK_FLOW_MODE_NONE: | ||
1535 | /* set Pause Off */ | ||
1536 | SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_OFF); | ||
1537 | /* disable Tx & Rx flow-control */ | ||
1538 | SWord |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS; | ||
1539 | break; | ||
1540 | case SK_FLOW_MODE_LOC_SEND: | ||
1541 | /* disable Rx flow-control */ | ||
1542 | SWord |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS; | ||
1543 | break; | ||
1544 | case SK_FLOW_MODE_SYMMETRIC: | ||
1545 | case SK_FLOW_MODE_SYM_OR_REM: | ||
1546 | /* enable Tx & Rx flow-control */ | ||
1547 | break; | ||
1548 | } | ||
1549 | |||
1550 | /* setup General Purpose Control Register */ | ||
1551 | GM_OUT16(IoC, Port, GM_GP_CTRL, SWord); | ||
1552 | |||
1553 | /* dummy read the Interrupt Source Register */ | ||
1554 | SK_IN16(IoC, GMAC_IRQ_SRC, &SWord); | ||
1555 | |||
1556 | #ifndef VCPU | ||
1557 | /* read Id from PHY */ | ||
1558 | SkGmPhyRead(pAC, IoC, Port, PHY_MARV_ID1, &pPrt->PhyId1); | ||
1559 | |||
1560 | SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE); | ||
1561 | #endif /* VCPU */ | ||
1562 | } | ||
1563 | |||
1564 | (void)SkGmResetCounter(pAC, IoC, Port); | ||
1565 | |||
1566 | /* setup Transmit Control Register */ | ||
1567 | GM_OUT16(IoC, Port, GM_TX_CTRL, TX_COL_THR(pPrt->PMacColThres)); | ||
1568 | |||
1569 | /* setup Receive Control Register */ | ||
1570 | GM_OUT16(IoC, Port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA | | ||
1571 | GM_RXCR_CRC_DIS); | ||
1572 | |||
1573 | /* setup Transmit Flow Control Register */ | ||
1574 | GM_OUT16(IoC, Port, GM_TX_FLOW_CTRL, 0xffff); | ||
1575 | |||
1576 | /* setup Transmit Parameter Register */ | ||
1577 | #ifdef VCPU | ||
1578 | GM_IN16(IoC, Port, GM_TX_PARAM, &SWord); | ||
1579 | #endif /* VCPU */ | ||
1580 | |||
1581 | SWord = TX_JAM_LEN_VAL(pPrt->PMacJamLen) | | ||
1582 | TX_JAM_IPG_VAL(pPrt->PMacJamIpgVal) | | ||
1583 | TX_IPG_JAM_DATA(pPrt->PMacJamIpgData); | ||
1584 | |||
1585 | GM_OUT16(IoC, Port, GM_TX_PARAM, SWord); | ||
1586 | |||
1587 | /* configure the Serial Mode Register */ | ||
1588 | #ifdef VCPU | ||
1589 | GM_IN16(IoC, Port, GM_SERIAL_MODE, &SWord); | ||
1590 | #endif /* VCPU */ | ||
1591 | |||
1592 | SWord = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(pPrt->PMacIpgData); | ||
1593 | |||
1594 | if (pPrt->PMacLimit4) { | ||
1595 | /* reset of collision counter after 4 consecutive collisions */ | ||
1596 | SWord |= GM_SMOD_LIMIT_4; | ||
1597 | } | ||
1598 | |||
1599 | if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { | ||
1600 | /* enable jumbo mode (Max. Frame Length = 9018) */ | ||
1601 | SWord |= GM_SMOD_JUMBO_ENA; | ||
1602 | } | ||
1603 | |||
1604 | GM_OUT16(IoC, Port, GM_SERIAL_MODE, SWord); | ||
1605 | |||
1606 | /* | ||
1607 | * configure the GMACs Station Addresses | ||
1608 | * in PROM you can find our addresses at: | ||
1609 | * B2_MAC_1 = xx xx xx xx xx x0 virtual address | ||
1610 | * B2_MAC_2 = xx xx xx xx xx x1 is programmed to GMAC A | ||
1611 | * B2_MAC_3 = xx xx xx xx xx x2 is reserved for DualPort | ||
1612 | */ | ||
1613 | |||
1614 | for (i = 0; i < 3; i++) { | ||
1615 | /* | ||
1616 | * The following 2 statements are together endianess | ||
1617 | * independent. Remember this when changing. | ||
1618 | */ | ||
1619 | /* physical address: will be used for pause frames */ | ||
1620 | SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord); | ||
1621 | |||
1622 | #ifdef WA_DEV_16 | ||
1623 | /* WA for deviation #16 */ | ||
1624 | if (pAC->GIni.GIChipId == CHIP_ID_YUKON && pAC->GIni.GIChipRev == 0) { | ||
1625 | /* swap the address bytes */ | ||
1626 | SWord = ((SWord & 0xff00) >> 8) | ((SWord & 0x00ff) << 8); | ||
1627 | |||
1628 | /* write to register in reversed order */ | ||
1629 | GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + (2 - i) * 4), SWord); | ||
1630 | } | ||
1631 | else { | ||
1632 | GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord); | ||
1633 | } | ||
1634 | #else | ||
1635 | GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord); | ||
1636 | #endif /* WA_DEV_16 */ | ||
1637 | |||
1638 | /* virtual address: will be used for data */ | ||
1639 | SK_IN16(IoC, (B2_MAC_1 + Port * 8 + i * 2), &SWord); | ||
1640 | |||
1641 | GM_OUT16(IoC, Port, (GM_SRC_ADDR_2L + i * 4), SWord); | ||
1642 | |||
1643 | /* reset Multicast filtering Hash registers 1-3 */ | ||
1644 | GM_OUT16(IoC, Port, GM_MC_ADDR_H1 + 4*i, 0); | ||
1645 | } | ||
1646 | |||
1647 | /* reset Multicast filtering Hash register 4 */ | ||
1648 | GM_OUT16(IoC, Port, GM_MC_ADDR_H4, 0); | ||
1649 | |||
1650 | /* enable interrupt mask for counter overflows */ | ||
1651 | GM_OUT16(IoC, Port, GM_TX_IRQ_MSK, 0); | ||
1652 | GM_OUT16(IoC, Port, GM_RX_IRQ_MSK, 0); | ||
1653 | GM_OUT16(IoC, Port, GM_TR_IRQ_MSK, 0); | ||
1654 | |||
1655 | #if defined(SK_DIAG) || defined(DEBUG) | ||
1656 | /* read General Purpose Status */ | ||
1657 | GM_IN16(IoC, Port, GM_GP_STAT, &SWord); | ||
1658 | |||
1659 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1660 | ("MAC Stat Reg.=0x%04X\n", SWord)); | ||
1661 | #endif /* SK_DIAG || DEBUG */ | ||
1662 | |||
1663 | #ifdef SK_DIAG | ||
1664 | c_print("MAC Stat Reg=0x%04X\n", SWord); | ||
1665 | #endif /* SK_DIAG */ | ||
1666 | |||
1667 | } /* SkGmInitMac */ | ||
1668 | #endif /* YUKON */ | ||
1669 | |||
1670 | |||
1671 | #ifdef GENESIS | ||
1672 | /****************************************************************************** | ||
1673 | * | ||
1674 | * SkXmInitDupMd() - Initialize the XMACs Duplex Mode | ||
1675 | * | ||
1676 | * Description: | ||
1677 | * This function initializes the XMACs Duplex Mode. | ||
1678 | * It should be called after successfully finishing | ||
1679 | * the Auto-negotiation Process | ||
1680 | * | ||
1681 | * Returns: | ||
1682 | * nothing | ||
1683 | */ | ||
1684 | static void SkXmInitDupMd( | ||
1685 | SK_AC *pAC, /* adapter context */ | ||
1686 | SK_IOC IoC, /* IO context */ | ||
1687 | int Port) /* Port Index (MAC_1 + n) */ | ||
1688 | { | ||
1689 | switch (pAC->GIni.GP[Port].PLinkModeStatus) { | ||
1690 | case SK_LMODE_STAT_AUTOHALF: | ||
1691 | case SK_LMODE_STAT_HALF: | ||
1692 | /* Configuration Actions for Half Duplex Mode */ | ||
1693 | /* | ||
1694 | * XM_BURST = default value. We are probable not quick | ||
1695 | * enough at the 'XMAC' bus to burst 8kB. | ||
1696 | * The XMAC stops bursting if no transmit frames | ||
1697 | * are available or the burst limit is exceeded. | ||
1698 | */ | ||
1699 | /* XM_TX_RT_LIM = default value (15) */ | ||
1700 | /* XM_TX_STIME = default value (0xff = 4096 bit times) */ | ||
1701 | break; | ||
1702 | case SK_LMODE_STAT_AUTOFULL: | ||
1703 | case SK_LMODE_STAT_FULL: | ||
1704 | /* Configuration Actions for Full Duplex Mode */ | ||
1705 | /* | ||
1706 | * The duplex mode is configured by the PHY, | ||
1707 | * therefore it seems to be that there is nothing | ||
1708 | * to do here. | ||
1709 | */ | ||
1710 | break; | ||
1711 | case SK_LMODE_STAT_UNKNOWN: | ||
1712 | default: | ||
1713 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E007, SKERR_HWI_E007MSG); | ||
1714 | break; | ||
1715 | } | ||
1716 | } /* SkXmInitDupMd */ | ||
1717 | |||
1718 | |||
1719 | /****************************************************************************** | ||
1720 | * | ||
1721 | * SkXmInitPauseMd() - initialize the Pause Mode to be used for this port | ||
1722 | * | ||
1723 | * Description: | ||
1724 | * This function initializes the Pause Mode which should | ||
1725 | * be used for this port. | ||
1726 | * It should be called after successfully finishing | ||
1727 | * the Auto-negotiation Process | ||
1728 | * | ||
1729 | * Returns: | ||
1730 | * nothing | ||
1731 | */ | ||
1732 | static void SkXmInitPauseMd( | ||
1733 | SK_AC *pAC, /* adapter context */ | ||
1734 | SK_IOC IoC, /* IO context */ | ||
1735 | int Port) /* Port Index (MAC_1 + n) */ | ||
1736 | { | ||
1737 | SK_GEPORT *pPrt; | ||
1738 | SK_U32 DWord; | ||
1739 | SK_U16 Word; | ||
1740 | |||
1741 | pPrt = &pAC->GIni.GP[Port]; | ||
1742 | |||
1743 | XM_IN16(IoC, Port, XM_MMU_CMD, &Word); | ||
1744 | |||
1745 | if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_NONE || | ||
1746 | pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) { | ||
1747 | |||
1748 | /* Disable Pause Frame Reception */ | ||
1749 | Word |= XM_MMU_IGN_PF; | ||
1750 | } | ||
1751 | else { | ||
1752 | /* | ||
1753 | * enabling pause frame reception is required for 1000BT | ||
1754 | * because the XMAC is not reset if the link is going down | ||
1755 | */ | ||
1756 | /* Enable Pause Frame Reception */ | ||
1757 | Word &= ~XM_MMU_IGN_PF; | ||
1758 | } | ||
1759 | |||
1760 | XM_OUT16(IoC, Port, XM_MMU_CMD, Word); | ||
1761 | |||
1762 | XM_IN32(IoC, Port, XM_MODE, &DWord); | ||
1763 | |||
1764 | if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_SYMMETRIC || | ||
1765 | pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) { | ||
1766 | |||
1767 | /* | ||
1768 | * Configure Pause Frame Generation | ||
1769 | * Use internal and external Pause Frame Generation. | ||
1770 | * Sending pause frames is edge triggered. | ||
1771 | * Send a Pause frame with the maximum pause time if | ||
1772 | * internal oder external FIFO full condition occurs. | ||
1773 | * Send a zero pause time frame to re-start transmission. | ||
1774 | */ | ||
1775 | |||
1776 | /* XM_PAUSE_DA = '010000C28001' (default) */ | ||
1777 | |||
1778 | /* XM_MAC_PTIME = 0xffff (maximum) */ | ||
1779 | /* remember this value is defined in big endian (!) */ | ||
1780 | XM_OUT16(IoC, Port, XM_MAC_PTIME, 0xffff); | ||
1781 | |||
1782 | /* Set Pause Mode in Mode Register */ | ||
1783 | DWord |= XM_PAUSE_MODE; | ||
1784 | |||
1785 | /* Set Pause Mode in MAC Rx FIFO */ | ||
1786 | SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_PAUSE); | ||
1787 | } | ||
1788 | else { | ||
1789 | /* | ||
1790 | * disable pause frame generation is required for 1000BT | ||
1791 | * because the XMAC is not reset if the link is going down | ||
1792 | */ | ||
1793 | /* Disable Pause Mode in Mode Register */ | ||
1794 | DWord &= ~XM_PAUSE_MODE; | ||
1795 | |||
1796 | /* Disable Pause Mode in MAC Rx FIFO */ | ||
1797 | SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_DIS_PAUSE); | ||
1798 | } | ||
1799 | |||
1800 | XM_OUT32(IoC, Port, XM_MODE, DWord); | ||
1801 | } /* SkXmInitPauseMd*/ | ||
1802 | |||
1803 | |||
1804 | /****************************************************************************** | ||
1805 | * | ||
1806 | * SkXmInitPhyXmac() - Initialize the XMAC Phy registers | ||
1807 | * | ||
1808 | * Description: initializes all the XMACs Phy registers | ||
1809 | * | ||
1810 | * Note: | ||
1811 | * | ||
1812 | * Returns: | ||
1813 | * nothing | ||
1814 | */ | ||
1815 | static void SkXmInitPhyXmac( | ||
1816 | SK_AC *pAC, /* adapter context */ | ||
1817 | SK_IOC IoC, /* IO context */ | ||
1818 | int Port, /* Port Index (MAC_1 + n) */ | ||
1819 | SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ | ||
1820 | { | ||
1821 | SK_GEPORT *pPrt; | ||
1822 | SK_U16 Ctrl; | ||
1823 | |||
1824 | pPrt = &pAC->GIni.GP[Port]; | ||
1825 | Ctrl = 0; | ||
1826 | |||
1827 | /* Auto-negotiation ? */ | ||
1828 | if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { | ||
1829 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1830 | ("InitPhyXmac: no auto-negotiation Port %d\n", Port)); | ||
1831 | /* Set DuplexMode in Config register */ | ||
1832 | if (pPrt->PLinkMode == SK_LMODE_FULL) { | ||
1833 | Ctrl |= PHY_CT_DUP_MD; | ||
1834 | } | ||
1835 | |||
1836 | /* | ||
1837 | * Do NOT enable Auto-negotiation here. This would hold | ||
1838 | * the link down because no IDLEs are transmitted | ||
1839 | */ | ||
1840 | } | ||
1841 | else { | ||
1842 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1843 | ("InitPhyXmac: with auto-negotiation Port %d\n", Port)); | ||
1844 | /* Set Auto-negotiation advertisement */ | ||
1845 | |||
1846 | /* Set Full/half duplex capabilities */ | ||
1847 | switch (pPrt->PLinkMode) { | ||
1848 | case SK_LMODE_AUTOHALF: | ||
1849 | Ctrl |= PHY_X_AN_HD; | ||
1850 | break; | ||
1851 | case SK_LMODE_AUTOFULL: | ||
1852 | Ctrl |= PHY_X_AN_FD; | ||
1853 | break; | ||
1854 | case SK_LMODE_AUTOBOTH: | ||
1855 | Ctrl |= PHY_X_AN_FD | PHY_X_AN_HD; | ||
1856 | break; | ||
1857 | default: | ||
1858 | SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015, | ||
1859 | SKERR_HWI_E015MSG); | ||
1860 | } | ||
1861 | |||
1862 | /* Set Flow-control capabilities */ | ||
1863 | switch (pPrt->PFlowCtrlMode) { | ||
1864 | case SK_FLOW_MODE_NONE: | ||
1865 | Ctrl |= PHY_X_P_NO_PAUSE; | ||
1866 | break; | ||
1867 | case SK_FLOW_MODE_LOC_SEND: | ||
1868 | Ctrl |= PHY_X_P_ASYM_MD; | ||
1869 | break; | ||
1870 | case SK_FLOW_MODE_SYMMETRIC: | ||
1871 | Ctrl |= PHY_X_P_SYM_MD; | ||
1872 | break; | ||
1873 | case SK_FLOW_MODE_SYM_OR_REM: | ||
1874 | Ctrl |= PHY_X_P_BOTH_MD; | ||
1875 | break; | ||
1876 | default: | ||
1877 | SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, | ||
1878 | SKERR_HWI_E016MSG); | ||
1879 | } | ||
1880 | |||
1881 | /* Write AutoNeg Advertisement Register */ | ||
1882 | SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_AUNE_ADV, Ctrl); | ||
1883 | |||
1884 | /* Restart Auto-negotiation */ | ||
1885 | Ctrl = PHY_CT_ANE | PHY_CT_RE_CFG; | ||
1886 | } | ||
1887 | |||
1888 | if (DoLoop) { | ||
1889 | /* Set the Phy Loopback bit, too */ | ||
1890 | Ctrl |= PHY_CT_LOOP; | ||
1891 | } | ||
1892 | |||
1893 | /* Write to the Phy control register */ | ||
1894 | SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_CTRL, Ctrl); | ||
1895 | } /* SkXmInitPhyXmac */ | ||
1896 | |||
1897 | |||
1898 | /****************************************************************************** | ||
1899 | * | ||
1900 | * SkXmInitPhyBcom() - Initialize the Broadcom Phy registers | ||
1901 | * | ||
1902 | * Description: initializes all the Broadcom Phy registers | ||
1903 | * | ||
1904 | * Note: | ||
1905 | * | ||
1906 | * Returns: | ||
1907 | * nothing | ||
1908 | */ | ||
1909 | static void SkXmInitPhyBcom( | ||
1910 | SK_AC *pAC, /* adapter context */ | ||
1911 | SK_IOC IoC, /* IO context */ | ||
1912 | int Port, /* Port Index (MAC_1 + n) */ | ||
1913 | SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ | ||
1914 | { | ||
1915 | SK_GEPORT *pPrt; | ||
1916 | SK_U16 Ctrl1; | ||
1917 | SK_U16 Ctrl2; | ||
1918 | SK_U16 Ctrl3; | ||
1919 | SK_U16 Ctrl4; | ||
1920 | SK_U16 Ctrl5; | ||
1921 | |||
1922 | Ctrl1 = PHY_CT_SP1000; | ||
1923 | Ctrl2 = 0; | ||
1924 | Ctrl3 = PHY_SEL_TYPE; | ||
1925 | Ctrl4 = PHY_B_PEC_EN_LTR; | ||
1926 | Ctrl5 = PHY_B_AC_TX_TST; | ||
1927 | |||
1928 | pPrt = &pAC->GIni.GP[Port]; | ||
1929 | |||
1930 | /* manually Master/Slave ? */ | ||
1931 | if (pPrt->PMSMode != SK_MS_MODE_AUTO) { | ||
1932 | Ctrl2 |= PHY_B_1000C_MSE; | ||
1933 | |||
1934 | if (pPrt->PMSMode == SK_MS_MODE_MASTER) { | ||
1935 | Ctrl2 |= PHY_B_1000C_MSC; | ||
1936 | } | ||
1937 | } | ||
1938 | /* Auto-negotiation ? */ | ||
1939 | if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { | ||
1940 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1941 | ("InitPhyBcom: no auto-negotiation Port %d\n", Port)); | ||
1942 | /* Set DuplexMode in Config register */ | ||
1943 | if (pPrt->PLinkMode == SK_LMODE_FULL) { | ||
1944 | Ctrl1 |= PHY_CT_DUP_MD; | ||
1945 | } | ||
1946 | |||
1947 | /* Determine Master/Slave manually if not already done */ | ||
1948 | if (pPrt->PMSMode == SK_MS_MODE_AUTO) { | ||
1949 | Ctrl2 |= PHY_B_1000C_MSE; /* set it to Slave */ | ||
1950 | } | ||
1951 | |||
1952 | /* | ||
1953 | * Do NOT enable Auto-negotiation here. This would hold | ||
1954 | * the link down because no IDLES are transmitted | ||
1955 | */ | ||
1956 | } | ||
1957 | else { | ||
1958 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
1959 | ("InitPhyBcom: with auto-negotiation Port %d\n", Port)); | ||
1960 | /* Set Auto-negotiation advertisement */ | ||
1961 | |||
1962 | /* | ||
1963 | * Workaround BCOM Errata #1 for the C5 type. | ||
1964 | * 1000Base-T Link Acquisition Failure in Slave Mode | ||
1965 | * Set Repeater/DTE bit 10 of the 1000Base-T Control Register | ||
1966 | */ | ||
1967 | Ctrl2 |= PHY_B_1000C_RD; | ||
1968 | |||
1969 | /* Set Full/half duplex capabilities */ | ||
1970 | switch (pPrt->PLinkMode) { | ||
1971 | case SK_LMODE_AUTOHALF: | ||
1972 | Ctrl2 |= PHY_B_1000C_AHD; | ||
1973 | break; | ||
1974 | case SK_LMODE_AUTOFULL: | ||
1975 | Ctrl2 |= PHY_B_1000C_AFD; | ||
1976 | break; | ||
1977 | case SK_LMODE_AUTOBOTH: | ||
1978 | Ctrl2 |= PHY_B_1000C_AFD | PHY_B_1000C_AHD; | ||
1979 | break; | ||
1980 | default: | ||
1981 | SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015, | ||
1982 | SKERR_HWI_E015MSG); | ||
1983 | } | ||
1984 | |||
1985 | /* Set Flow-control capabilities */ | ||
1986 | switch (pPrt->PFlowCtrlMode) { | ||
1987 | case SK_FLOW_MODE_NONE: | ||
1988 | Ctrl3 |= PHY_B_P_NO_PAUSE; | ||
1989 | break; | ||
1990 | case SK_FLOW_MODE_LOC_SEND: | ||
1991 | Ctrl3 |= PHY_B_P_ASYM_MD; | ||
1992 | break; | ||
1993 | case SK_FLOW_MODE_SYMMETRIC: | ||
1994 | Ctrl3 |= PHY_B_P_SYM_MD; | ||
1995 | break; | ||
1996 | case SK_FLOW_MODE_SYM_OR_REM: | ||
1997 | Ctrl3 |= PHY_B_P_BOTH_MD; | ||
1998 | break; | ||
1999 | default: | ||
2000 | SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, | ||
2001 | SKERR_HWI_E016MSG); | ||
2002 | } | ||
2003 | |||
2004 | /* Restart Auto-negotiation */ | ||
2005 | Ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG; | ||
2006 | } | ||
2007 | |||
2008 | /* Initialize LED register here? */ | ||
2009 | /* No. Please do it in SkDgXmitLed() (if required) and swap | ||
2010 | init order of LEDs and XMAC. (MAl) */ | ||
2011 | |||
2012 | /* Write 1000Base-T Control Register */ | ||
2013 | SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, Ctrl2); | ||
2014 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2015 | ("Set 1000B-T Ctrl Reg=0x%04X\n", Ctrl2)); | ||
2016 | |||
2017 | /* Write AutoNeg Advertisement Register */ | ||
2018 | SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, Ctrl3); | ||
2019 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2020 | ("Set Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3)); | ||
2021 | |||
2022 | if (DoLoop) { | ||
2023 | /* Set the Phy Loopback bit, too */ | ||
2024 | Ctrl1 |= PHY_CT_LOOP; | ||
2025 | } | ||
2026 | |||
2027 | if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { | ||
2028 | /* configure FIFO to high latency for transmission of ext. packets */ | ||
2029 | Ctrl4 |= PHY_B_PEC_HIGH_LA; | ||
2030 | |||
2031 | /* configure reception of extended packets */ | ||
2032 | Ctrl5 |= PHY_B_AC_LONG_PACK; | ||
2033 | |||
2034 | SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, Ctrl5); | ||
2035 | } | ||
2036 | |||
2037 | /* Configure LED Traffic Mode and Jumbo Frame usage if specified */ | ||
2038 | SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, Ctrl4); | ||
2039 | |||
2040 | /* Write to the Phy control register */ | ||
2041 | SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL, Ctrl1); | ||
2042 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2043 | ("PHY Control Reg=0x%04X\n", Ctrl1)); | ||
2044 | } /* SkXmInitPhyBcom */ | ||
2045 | #endif /* GENESIS */ | ||
2046 | |||
2047 | #ifdef YUKON | ||
2048 | /****************************************************************************** | ||
2049 | * | ||
2050 | * SkGmInitPhyMarv() - Initialize the Marvell Phy registers | ||
2051 | * | ||
2052 | * Description: initializes all the Marvell Phy registers | ||
2053 | * | ||
2054 | * Note: | ||
2055 | * | ||
2056 | * Returns: | ||
2057 | * nothing | ||
2058 | */ | ||
2059 | static void SkGmInitPhyMarv( | ||
2060 | SK_AC *pAC, /* adapter context */ | ||
2061 | SK_IOC IoC, /* IO context */ | ||
2062 | int Port, /* Port Index (MAC_1 + n) */ | ||
2063 | SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ | ||
2064 | { | ||
2065 | SK_GEPORT *pPrt; | ||
2066 | SK_U16 PhyCtrl; | ||
2067 | SK_U16 C1000BaseT; | ||
2068 | SK_U16 AutoNegAdv; | ||
2069 | SK_U16 ExtPhyCtrl; | ||
2070 | SK_U16 LedCtrl; | ||
2071 | SK_BOOL AutoNeg; | ||
2072 | #if defined(SK_DIAG) || defined(DEBUG) | ||
2073 | SK_U16 PhyStat; | ||
2074 | SK_U16 PhyStat1; | ||
2075 | SK_U16 PhySpecStat; | ||
2076 | #endif /* SK_DIAG || DEBUG */ | ||
2077 | |||
2078 | pPrt = &pAC->GIni.GP[Port]; | ||
2079 | |||
2080 | /* Auto-negotiation ? */ | ||
2081 | if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { | ||
2082 | AutoNeg = SK_FALSE; | ||
2083 | } | ||
2084 | else { | ||
2085 | AutoNeg = SK_TRUE; | ||
2086 | } | ||
2087 | |||
2088 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2089 | ("InitPhyMarv: Port %d, auto-negotiation %s\n", | ||
2090 | Port, AutoNeg ? "ON" : "OFF")); | ||
2091 | |||
2092 | #ifdef VCPU | ||
2093 | VCPUprintf(0, "SkGmInitPhyMarv(), Port=%u, DoLoop=%u\n", | ||
2094 | Port, DoLoop); | ||
2095 | #else /* VCPU */ | ||
2096 | if (DoLoop) { | ||
2097 | /* Set 'MAC Power up'-bit, set Manual MDI configuration */ | ||
2098 | SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, | ||
2099 | PHY_M_PC_MAC_POW_UP); | ||
2100 | } | ||
2101 | else if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO) { | ||
2102 | /* Read Ext. PHY Specific Control */ | ||
2103 | SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl); | ||
2104 | |||
2105 | ExtPhyCtrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | | ||
2106 | PHY_M_EC_MAC_S_MSK); | ||
2107 | |||
2108 | ExtPhyCtrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ) | | ||
2109 | PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1); | ||
2110 | |||
2111 | SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl); | ||
2112 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2113 | ("Set Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl)); | ||
2114 | } | ||
2115 | |||
2116 | /* Read PHY Control */ | ||
2117 | SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl); | ||
2118 | |||
2119 | if (!AutoNeg) { | ||
2120 | /* Disable Auto-negotiation */ | ||
2121 | PhyCtrl &= ~PHY_CT_ANE; | ||
2122 | } | ||
2123 | |||
2124 | PhyCtrl |= PHY_CT_RESET; | ||
2125 | /* Assert software reset */ | ||
2126 | SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl); | ||
2127 | #endif /* VCPU */ | ||
2128 | |||
2129 | PhyCtrl = 0 /* PHY_CT_COL_TST */; | ||
2130 | C1000BaseT = 0; | ||
2131 | AutoNegAdv = PHY_SEL_TYPE; | ||
2132 | |||
2133 | /* manually Master/Slave ? */ | ||
2134 | if (pPrt->PMSMode != SK_MS_MODE_AUTO) { | ||
2135 | /* enable Manual Master/Slave */ | ||
2136 | C1000BaseT |= PHY_M_1000C_MSE; | ||
2137 | |||
2138 | if (pPrt->PMSMode == SK_MS_MODE_MASTER) { | ||
2139 | C1000BaseT |= PHY_M_1000C_MSC; /* set it to Master */ | ||
2140 | } | ||
2141 | } | ||
2142 | |||
2143 | /* Auto-negotiation ? */ | ||
2144 | if (!AutoNeg) { | ||
2145 | |||
2146 | if (pPrt->PLinkMode == SK_LMODE_FULL) { | ||
2147 | /* Set Full Duplex Mode */ | ||
2148 | PhyCtrl |= PHY_CT_DUP_MD; | ||
2149 | } | ||
2150 | |||
2151 | /* Set Master/Slave manually if not already done */ | ||
2152 | if (pPrt->PMSMode == SK_MS_MODE_AUTO) { | ||
2153 | C1000BaseT |= PHY_M_1000C_MSE; /* set it to Slave */ | ||
2154 | } | ||
2155 | |||
2156 | /* Set Speed */ | ||
2157 | switch (pPrt->PLinkSpeed) { | ||
2158 | case SK_LSPEED_AUTO: | ||
2159 | case SK_LSPEED_1000MBPS: | ||
2160 | PhyCtrl |= PHY_CT_SP1000; | ||
2161 | break; | ||
2162 | case SK_LSPEED_100MBPS: | ||
2163 | PhyCtrl |= PHY_CT_SP100; | ||
2164 | break; | ||
2165 | case SK_LSPEED_10MBPS: | ||
2166 | break; | ||
2167 | default: | ||
2168 | SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019, | ||
2169 | SKERR_HWI_E019MSG); | ||
2170 | } | ||
2171 | |||
2172 | if (!DoLoop) { | ||
2173 | PhyCtrl |= PHY_CT_RESET; | ||
2174 | } | ||
2175 | } | ||
2176 | else { | ||
2177 | /* Set Auto-negotiation advertisement */ | ||
2178 | |||
2179 | if (pAC->GIni.GICopperType) { | ||
2180 | /* Set Speed capabilities */ | ||
2181 | switch (pPrt->PLinkSpeed) { | ||
2182 | case SK_LSPEED_AUTO: | ||
2183 | C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD; | ||
2184 | AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD | | ||
2185 | PHY_M_AN_10_FD | PHY_M_AN_10_HD; | ||
2186 | break; | ||
2187 | case SK_LSPEED_1000MBPS: | ||
2188 | C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD; | ||
2189 | break; | ||
2190 | case SK_LSPEED_100MBPS: | ||
2191 | AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD | | ||
2192 | /* advertise 10Base-T also */ | ||
2193 | PHY_M_AN_10_FD | PHY_M_AN_10_HD; | ||
2194 | break; | ||
2195 | case SK_LSPEED_10MBPS: | ||
2196 | AutoNegAdv |= PHY_M_AN_10_FD | PHY_M_AN_10_HD; | ||
2197 | break; | ||
2198 | default: | ||
2199 | SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019, | ||
2200 | SKERR_HWI_E019MSG); | ||
2201 | } | ||
2202 | |||
2203 | /* Set Full/half duplex capabilities */ | ||
2204 | switch (pPrt->PLinkMode) { | ||
2205 | case SK_LMODE_AUTOHALF: | ||
2206 | C1000BaseT &= ~PHY_M_1000C_AFD; | ||
2207 | AutoNegAdv &= ~(PHY_M_AN_100_FD | PHY_M_AN_10_FD); | ||
2208 | break; | ||
2209 | case SK_LMODE_AUTOFULL: | ||
2210 | C1000BaseT &= ~PHY_M_1000C_AHD; | ||
2211 | AutoNegAdv &= ~(PHY_M_AN_100_HD | PHY_M_AN_10_HD); | ||
2212 | break; | ||
2213 | case SK_LMODE_AUTOBOTH: | ||
2214 | break; | ||
2215 | default: | ||
2216 | SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015, | ||
2217 | SKERR_HWI_E015MSG); | ||
2218 | } | ||
2219 | |||
2220 | /* Set Flow-control capabilities */ | ||
2221 | switch (pPrt->PFlowCtrlMode) { | ||
2222 | case SK_FLOW_MODE_NONE: | ||
2223 | AutoNegAdv |= PHY_B_P_NO_PAUSE; | ||
2224 | break; | ||
2225 | case SK_FLOW_MODE_LOC_SEND: | ||
2226 | AutoNegAdv |= PHY_B_P_ASYM_MD; | ||
2227 | break; | ||
2228 | case SK_FLOW_MODE_SYMMETRIC: | ||
2229 | AutoNegAdv |= PHY_B_P_SYM_MD; | ||
2230 | break; | ||
2231 | case SK_FLOW_MODE_SYM_OR_REM: | ||
2232 | AutoNegAdv |= PHY_B_P_BOTH_MD; | ||
2233 | break; | ||
2234 | default: | ||
2235 | SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, | ||
2236 | SKERR_HWI_E016MSG); | ||
2237 | } | ||
2238 | } | ||
2239 | else { /* special defines for FIBER (88E1011S only) */ | ||
2240 | |||
2241 | /* Set Full/half duplex capabilities */ | ||
2242 | switch (pPrt->PLinkMode) { | ||
2243 | case SK_LMODE_AUTOHALF: | ||
2244 | AutoNegAdv |= PHY_M_AN_1000X_AHD; | ||
2245 | break; | ||
2246 | case SK_LMODE_AUTOFULL: | ||
2247 | AutoNegAdv |= PHY_M_AN_1000X_AFD; | ||
2248 | break; | ||
2249 | case SK_LMODE_AUTOBOTH: | ||
2250 | AutoNegAdv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD; | ||
2251 | break; | ||
2252 | default: | ||
2253 | SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015, | ||
2254 | SKERR_HWI_E015MSG); | ||
2255 | } | ||
2256 | |||
2257 | /* Set Flow-control capabilities */ | ||
2258 | switch (pPrt->PFlowCtrlMode) { | ||
2259 | case SK_FLOW_MODE_NONE: | ||
2260 | AutoNegAdv |= PHY_M_P_NO_PAUSE_X; | ||
2261 | break; | ||
2262 | case SK_FLOW_MODE_LOC_SEND: | ||
2263 | AutoNegAdv |= PHY_M_P_ASYM_MD_X; | ||
2264 | break; | ||
2265 | case SK_FLOW_MODE_SYMMETRIC: | ||
2266 | AutoNegAdv |= PHY_M_P_SYM_MD_X; | ||
2267 | break; | ||
2268 | case SK_FLOW_MODE_SYM_OR_REM: | ||
2269 | AutoNegAdv |= PHY_M_P_BOTH_MD_X; | ||
2270 | break; | ||
2271 | default: | ||
2272 | SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, | ||
2273 | SKERR_HWI_E016MSG); | ||
2274 | } | ||
2275 | } | ||
2276 | |||
2277 | if (!DoLoop) { | ||
2278 | /* Restart Auto-negotiation */ | ||
2279 | PhyCtrl |= PHY_CT_ANE | PHY_CT_RE_CFG; | ||
2280 | } | ||
2281 | } | ||
2282 | |||
2283 | #ifdef VCPU | ||
2284 | /* | ||
2285 | * E-mail from Gu Lin (08-03-2002): | ||
2286 | */ | ||
2287 | |||
2288 | /* Program PHY register 30 as 16'h0708 for simulation speed up */ | ||
2289 | SkGmPhyWrite(pAC, IoC, Port, 30, 0x0700 /* 0x0708 */); | ||
2290 | |||
2291 | VCpuWait(2000); | ||
2292 | |||
2293 | #else /* VCPU */ | ||
2294 | |||
2295 | /* Write 1000Base-T Control Register */ | ||
2296 | SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT); | ||
2297 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2298 | ("Set 1000B-T Ctrl =0x%04X\n", C1000BaseT)); | ||
2299 | |||
2300 | /* Write AutoNeg Advertisement Register */ | ||
2301 | SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, AutoNegAdv); | ||
2302 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2303 | ("Set Auto-Neg.Adv.=0x%04X\n", AutoNegAdv)); | ||
2304 | #endif /* VCPU */ | ||
2305 | |||
2306 | if (DoLoop) { | ||
2307 | /* Set the PHY Loopback bit */ | ||
2308 | PhyCtrl |= PHY_CT_LOOP; | ||
2309 | |||
2310 | #ifdef XXX | ||
2311 | /* Program PHY register 16 as 16'h0400 to force link good */ | ||
2312 | SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_FL_GOOD); | ||
2313 | #endif /* XXX */ | ||
2314 | |||
2315 | #ifndef VCPU | ||
2316 | if (pPrt->PLinkSpeed != SK_LSPEED_AUTO) { | ||
2317 | /* Write Ext. PHY Specific Control */ | ||
2318 | SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, | ||
2319 | (SK_U16)((pPrt->PLinkSpeed + 2) << 4)); | ||
2320 | } | ||
2321 | #endif /* VCPU */ | ||
2322 | } | ||
2323 | #ifdef TEST_ONLY | ||
2324 | else if (pPrt->PLinkSpeed == SK_LSPEED_10MBPS) { | ||
2325 | /* Write PHY Specific Control */ | ||
2326 | SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, | ||
2327 | PHY_M_PC_EN_DET_MSK); | ||
2328 | } | ||
2329 | #endif | ||
2330 | |||
2331 | /* Write to the PHY Control register */ | ||
2332 | SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl); | ||
2333 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2334 | ("Set PHY Ctrl Reg.=0x%04X\n", PhyCtrl)); | ||
2335 | |||
2336 | #ifdef VCPU | ||
2337 | VCpuWait(2000); | ||
2338 | #else | ||
2339 | |||
2340 | LedCtrl = PHY_M_LED_PULS_DUR(PULS_170MS) | PHY_M_LED_BLINK_RT(BLINK_84MS); | ||
2341 | |||
2342 | if ((pAC->GIni.GILedBlinkCtrl & SK_ACT_LED_BLINK) != 0) { | ||
2343 | LedCtrl |= PHY_M_LEDC_RX_CTRL | PHY_M_LEDC_TX_CTRL; | ||
2344 | } | ||
2345 | |||
2346 | if ((pAC->GIni.GILedBlinkCtrl & SK_DUP_LED_NORMAL) != 0) { | ||
2347 | LedCtrl |= PHY_M_LEDC_DP_CTRL; | ||
2348 | } | ||
2349 | |||
2350 | SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_CTRL, LedCtrl); | ||
2351 | |||
2352 | if ((pAC->GIni.GILedBlinkCtrl & SK_LED_LINK100_ON) != 0) { | ||
2353 | /* only in forced 100 Mbps mode */ | ||
2354 | if (!AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_100MBPS) { | ||
2355 | |||
2356 | SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_OVER, | ||
2357 | PHY_M_LED_MO_100(MO_LED_ON)); | ||
2358 | } | ||
2359 | } | ||
2360 | |||
2361 | #ifdef SK_DIAG | ||
2362 | c_print("Set PHY Ctrl=0x%04X\n", PhyCtrl); | ||
2363 | c_print("Set 1000 B-T=0x%04X\n", C1000BaseT); | ||
2364 | c_print("Set Auto-Neg=0x%04X\n", AutoNegAdv); | ||
2365 | c_print("Set Ext Ctrl=0x%04X\n", ExtPhyCtrl); | ||
2366 | #endif /* SK_DIAG */ | ||
2367 | |||
2368 | #if defined(SK_DIAG) || defined(DEBUG) | ||
2369 | /* Read PHY Control */ | ||
2370 | SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl); | ||
2371 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2372 | ("PHY Ctrl Reg.=0x%04X\n", PhyCtrl)); | ||
2373 | |||
2374 | /* Read 1000Base-T Control Register */ | ||
2375 | SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_CTRL, &C1000BaseT); | ||
2376 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2377 | ("1000B-T Ctrl =0x%04X\n", C1000BaseT)); | ||
2378 | |||
2379 | /* Read AutoNeg Advertisement Register */ | ||
2380 | SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &AutoNegAdv); | ||
2381 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2382 | ("Auto-Neg.Adv.=0x%04X\n", AutoNegAdv)); | ||
2383 | |||
2384 | /* Read Ext. PHY Specific Control */ | ||
2385 | SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl); | ||
2386 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2387 | ("Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl)); | ||
2388 | |||
2389 | /* Read PHY Status */ | ||
2390 | SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat); | ||
2391 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2392 | ("PHY Stat Reg.=0x%04X\n", PhyStat)); | ||
2393 | SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat1); | ||
2394 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2395 | ("PHY Stat Reg.=0x%04X\n", PhyStat1)); | ||
2396 | |||
2397 | /* Read PHY Specific Status */ | ||
2398 | SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat); | ||
2399 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2400 | ("PHY Spec Stat=0x%04X\n", PhySpecStat)); | ||
2401 | #endif /* SK_DIAG || DEBUG */ | ||
2402 | |||
2403 | #ifdef SK_DIAG | ||
2404 | c_print("PHY Ctrl Reg=0x%04X\n", PhyCtrl); | ||
2405 | c_print("PHY 1000 Reg=0x%04X\n", C1000BaseT); | ||
2406 | c_print("PHY AnAd Reg=0x%04X\n", AutoNegAdv); | ||
2407 | c_print("Ext Ctrl Reg=0x%04X\n", ExtPhyCtrl); | ||
2408 | c_print("PHY Stat Reg=0x%04X\n", PhyStat); | ||
2409 | c_print("PHY Stat Reg=0x%04X\n", PhyStat1); | ||
2410 | c_print("PHY Spec Reg=0x%04X\n", PhySpecStat); | ||
2411 | #endif /* SK_DIAG */ | ||
2412 | |||
2413 | #endif /* VCPU */ | ||
2414 | |||
2415 | } /* SkGmInitPhyMarv */ | ||
2416 | #endif /* YUKON */ | ||
2417 | |||
2418 | |||
2419 | #ifdef OTHER_PHY | ||
2420 | /****************************************************************************** | ||
2421 | * | ||
2422 | * SkXmInitPhyLone() - Initialize the Level One Phy registers | ||
2423 | * | ||
2424 | * Description: initializes all the Level One Phy registers | ||
2425 | * | ||
2426 | * Note: | ||
2427 | * | ||
2428 | * Returns: | ||
2429 | * nothing | ||
2430 | */ | ||
2431 | static void SkXmInitPhyLone( | ||
2432 | SK_AC *pAC, /* adapter context */ | ||
2433 | SK_IOC IoC, /* IO context */ | ||
2434 | int Port, /* Port Index (MAC_1 + n) */ | ||
2435 | SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ | ||
2436 | { | ||
2437 | SK_GEPORT *pPrt; | ||
2438 | SK_U16 Ctrl1; | ||
2439 | SK_U16 Ctrl2; | ||
2440 | SK_U16 Ctrl3; | ||
2441 | |||
2442 | Ctrl1 = PHY_CT_SP1000; | ||
2443 | Ctrl2 = 0; | ||
2444 | Ctrl3 = PHY_SEL_TYPE; | ||
2445 | |||
2446 | pPrt = &pAC->GIni.GP[Port]; | ||
2447 | |||
2448 | /* manually Master/Slave ? */ | ||
2449 | if (pPrt->PMSMode != SK_MS_MODE_AUTO) { | ||
2450 | Ctrl2 |= PHY_L_1000C_MSE; | ||
2451 | |||
2452 | if (pPrt->PMSMode == SK_MS_MODE_MASTER) { | ||
2453 | Ctrl2 |= PHY_L_1000C_MSC; | ||
2454 | } | ||
2455 | } | ||
2456 | /* Auto-negotiation ? */ | ||
2457 | if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { | ||
2458 | /* | ||
2459 | * level one spec say: "1000 Mbps: manual mode not allowed" | ||
2460 | * but lets see what happens... | ||
2461 | */ | ||
2462 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2463 | ("InitPhyLone: no auto-negotiation Port %d\n", Port)); | ||
2464 | /* Set DuplexMode in Config register */ | ||
2465 | if (pPrt->PLinkMode == SK_LMODE_FULL) { | ||
2466 | Ctrl1 |= PHY_CT_DUP_MD; | ||
2467 | } | ||
2468 | |||
2469 | /* Determine Master/Slave manually if not already done */ | ||
2470 | if (pPrt->PMSMode == SK_MS_MODE_AUTO) { | ||
2471 | Ctrl2 |= PHY_L_1000C_MSE; /* set it to Slave */ | ||
2472 | } | ||
2473 | |||
2474 | /* | ||
2475 | * Do NOT enable Auto-negotiation here. This would hold | ||
2476 | * the link down because no IDLES are transmitted | ||
2477 | */ | ||
2478 | } | ||
2479 | else { | ||
2480 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2481 | ("InitPhyLone: with auto-negotiation Port %d\n", Port)); | ||
2482 | /* Set Auto-negotiation advertisement */ | ||
2483 | |||
2484 | /* Set Full/half duplex capabilities */ | ||
2485 | switch (pPrt->PLinkMode) { | ||
2486 | case SK_LMODE_AUTOHALF: | ||
2487 | Ctrl2 |= PHY_L_1000C_AHD; | ||
2488 | break; | ||
2489 | case SK_LMODE_AUTOFULL: | ||
2490 | Ctrl2 |= PHY_L_1000C_AFD; | ||
2491 | break; | ||
2492 | case SK_LMODE_AUTOBOTH: | ||
2493 | Ctrl2 |= PHY_L_1000C_AFD | PHY_L_1000C_AHD; | ||
2494 | break; | ||
2495 | default: | ||
2496 | SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015, | ||
2497 | SKERR_HWI_E015MSG); | ||
2498 | } | ||
2499 | |||
2500 | /* Set Flow-control capabilities */ | ||
2501 | switch (pPrt->PFlowCtrlMode) { | ||
2502 | case SK_FLOW_MODE_NONE: | ||
2503 | Ctrl3 |= PHY_L_P_NO_PAUSE; | ||
2504 | break; | ||
2505 | case SK_FLOW_MODE_LOC_SEND: | ||
2506 | Ctrl3 |= PHY_L_P_ASYM_MD; | ||
2507 | break; | ||
2508 | case SK_FLOW_MODE_SYMMETRIC: | ||
2509 | Ctrl3 |= PHY_L_P_SYM_MD; | ||
2510 | break; | ||
2511 | case SK_FLOW_MODE_SYM_OR_REM: | ||
2512 | Ctrl3 |= PHY_L_P_BOTH_MD; | ||
2513 | break; | ||
2514 | default: | ||
2515 | SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, | ||
2516 | SKERR_HWI_E016MSG); | ||
2517 | } | ||
2518 | |||
2519 | /* Restart Auto-negotiation */ | ||
2520 | Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG; | ||
2521 | } | ||
2522 | |||
2523 | /* Write 1000Base-T Control Register */ | ||
2524 | SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_1000T_CTRL, Ctrl2); | ||
2525 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2526 | ("1000B-T Ctrl Reg=0x%04X\n", Ctrl2)); | ||
2527 | |||
2528 | /* Write AutoNeg Advertisement Register */ | ||
2529 | SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_AUNE_ADV, Ctrl3); | ||
2530 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2531 | ("Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3)); | ||
2532 | |||
2533 | if (DoLoop) { | ||
2534 | /* Set the Phy Loopback bit, too */ | ||
2535 | Ctrl1 |= PHY_CT_LOOP; | ||
2536 | } | ||
2537 | |||
2538 | /* Write to the Phy control register */ | ||
2539 | SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_CTRL, Ctrl1); | ||
2540 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2541 | ("PHY Control Reg=0x%04X\n", Ctrl1)); | ||
2542 | } /* SkXmInitPhyLone */ | ||
2543 | |||
2544 | |||
2545 | /****************************************************************************** | ||
2546 | * | ||
2547 | * SkXmInitPhyNat() - Initialize the National Phy registers | ||
2548 | * | ||
2549 | * Description: initializes all the National Phy registers | ||
2550 | * | ||
2551 | * Note: | ||
2552 | * | ||
2553 | * Returns: | ||
2554 | * nothing | ||
2555 | */ | ||
2556 | static void SkXmInitPhyNat( | ||
2557 | SK_AC *pAC, /* adapter context */ | ||
2558 | SK_IOC IoC, /* IO context */ | ||
2559 | int Port, /* Port Index (MAC_1 + n) */ | ||
2560 | SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ | ||
2561 | { | ||
2562 | /* todo: National */ | ||
2563 | } /* SkXmInitPhyNat */ | ||
2564 | #endif /* OTHER_PHY */ | ||
2565 | |||
2566 | |||
2567 | /****************************************************************************** | ||
2568 | * | ||
2569 | * SkMacInitPhy() - Initialize the PHY registers | ||
2570 | * | ||
2571 | * Description: calls the Init PHY routines dep. on board type | ||
2572 | * | ||
2573 | * Note: | ||
2574 | * | ||
2575 | * Returns: | ||
2576 | * nothing | ||
2577 | */ | ||
2578 | void SkMacInitPhy( | ||
2579 | SK_AC *pAC, /* adapter context */ | ||
2580 | SK_IOC IoC, /* IO context */ | ||
2581 | int Port, /* Port Index (MAC_1 + n) */ | ||
2582 | SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ | ||
2583 | { | ||
2584 | SK_GEPORT *pPrt; | ||
2585 | |||
2586 | pPrt = &pAC->GIni.GP[Port]; | ||
2587 | |||
2588 | #ifdef GENESIS | ||
2589 | if (pAC->GIni.GIGenesis) { | ||
2590 | |||
2591 | switch (pPrt->PhyType) { | ||
2592 | case SK_PHY_XMAC: | ||
2593 | SkXmInitPhyXmac(pAC, IoC, Port, DoLoop); | ||
2594 | break; | ||
2595 | case SK_PHY_BCOM: | ||
2596 | SkXmInitPhyBcom(pAC, IoC, Port, DoLoop); | ||
2597 | break; | ||
2598 | #ifdef OTHER_PHY | ||
2599 | case SK_PHY_LONE: | ||
2600 | SkXmInitPhyLone(pAC, IoC, Port, DoLoop); | ||
2601 | break; | ||
2602 | case SK_PHY_NAT: | ||
2603 | SkXmInitPhyNat(pAC, IoC, Port, DoLoop); | ||
2604 | break; | ||
2605 | #endif /* OTHER_PHY */ | ||
2606 | } | ||
2607 | } | ||
2608 | #endif /* GENESIS */ | ||
2609 | |||
2610 | #ifdef YUKON | ||
2611 | if (pAC->GIni.GIYukon) { | ||
2612 | |||
2613 | SkGmInitPhyMarv(pAC, IoC, Port, DoLoop); | ||
2614 | } | ||
2615 | #endif /* YUKON */ | ||
2616 | |||
2617 | } /* SkMacInitPhy */ | ||
2618 | |||
2619 | |||
2620 | #ifdef GENESIS | ||
2621 | /****************************************************************************** | ||
2622 | * | ||
2623 | * SkXmAutoNegDoneXmac() - Auto-negotiation handling | ||
2624 | * | ||
2625 | * Description: | ||
2626 | * This function handles the auto-negotiation if the Done bit is set. | ||
2627 | * | ||
2628 | * Returns: | ||
2629 | * SK_AND_OK o.k. | ||
2630 | * SK_AND_DUP_CAP Duplex capability error happened | ||
2631 | * SK_AND_OTHER Other error happened | ||
2632 | */ | ||
2633 | static int SkXmAutoNegDoneXmac( | ||
2634 | SK_AC *pAC, /* adapter context */ | ||
2635 | SK_IOC IoC, /* IO context */ | ||
2636 | int Port) /* Port Index (MAC_1 + n) */ | ||
2637 | { | ||
2638 | SK_GEPORT *pPrt; | ||
2639 | SK_U16 ResAb; /* Resolved Ability */ | ||
2640 | SK_U16 LPAb; /* Link Partner Ability */ | ||
2641 | |||
2642 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2643 | ("AutoNegDoneXmac, Port %d\n", Port)); | ||
2644 | |||
2645 | pPrt = &pAC->GIni.GP[Port]; | ||
2646 | |||
2647 | /* Get PHY parameters */ | ||
2648 | SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LPAb); | ||
2649 | SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb); | ||
2650 | |||
2651 | if ((LPAb & PHY_X_AN_RFB) != 0) { | ||
2652 | /* At least one of the remote fault bit is set */ | ||
2653 | /* Error */ | ||
2654 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2655 | ("AutoNegFail: Remote fault bit set Port %d\n", Port)); | ||
2656 | pPrt->PAutoNegFail = SK_TRUE; | ||
2657 | return(SK_AND_OTHER); | ||
2658 | } | ||
2659 | |||
2660 | /* Check Duplex mismatch */ | ||
2661 | if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_FD) { | ||
2662 | pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL; | ||
2663 | } | ||
2664 | else if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_HD) { | ||
2665 | pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF; | ||
2666 | } | ||
2667 | else { | ||
2668 | /* Error */ | ||
2669 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2670 | ("AutoNegFail: Duplex mode mismatch Port %d\n", Port)); | ||
2671 | pPrt->PAutoNegFail = SK_TRUE; | ||
2672 | return(SK_AND_DUP_CAP); | ||
2673 | } | ||
2674 | |||
2675 | /* Check PAUSE mismatch */ | ||
2676 | /* We are NOT using chapter 4.23 of the Xaqti manual */ | ||
2677 | /* We are using IEEE 802.3z/D5.0 Table 37-4 */ | ||
2678 | if ((pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC || | ||
2679 | pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) && | ||
2680 | (LPAb & PHY_X_P_SYM_MD) != 0) { | ||
2681 | /* Symmetric PAUSE */ | ||
2682 | pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; | ||
2683 | } | ||
2684 | else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM && | ||
2685 | (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) { | ||
2686 | /* Enable PAUSE receive, disable PAUSE transmit */ | ||
2687 | pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND; | ||
2688 | } | ||
2689 | else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND && | ||
2690 | (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) { | ||
2691 | /* Disable PAUSE receive, enable PAUSE transmit */ | ||
2692 | pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND; | ||
2693 | } | ||
2694 | else { | ||
2695 | /* PAUSE mismatch -> no PAUSE */ | ||
2696 | pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; | ||
2697 | } | ||
2698 | pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; | ||
2699 | |||
2700 | return(SK_AND_OK); | ||
2701 | } /* SkXmAutoNegDoneXmac */ | ||
2702 | |||
2703 | |||
2704 | /****************************************************************************** | ||
2705 | * | ||
2706 | * SkXmAutoNegDoneBcom() - Auto-negotiation handling | ||
2707 | * | ||
2708 | * Description: | ||
2709 | * This function handles the auto-negotiation if the Done bit is set. | ||
2710 | * | ||
2711 | * Returns: | ||
2712 | * SK_AND_OK o.k. | ||
2713 | * SK_AND_DUP_CAP Duplex capability error happened | ||
2714 | * SK_AND_OTHER Other error happened | ||
2715 | */ | ||
2716 | static int SkXmAutoNegDoneBcom( | ||
2717 | SK_AC *pAC, /* adapter context */ | ||
2718 | SK_IOC IoC, /* IO context */ | ||
2719 | int Port) /* Port Index (MAC_1 + n) */ | ||
2720 | { | ||
2721 | SK_GEPORT *pPrt; | ||
2722 | SK_U16 LPAb; /* Link Partner Ability */ | ||
2723 | SK_U16 AuxStat; /* Auxiliary Status */ | ||
2724 | |||
2725 | #ifdef TEST_ONLY | ||
2726 | 01-Sep-2000 RA;:;: | ||
2727 | SK_U16 ResAb; /* Resolved Ability */ | ||
2728 | #endif /* 0 */ | ||
2729 | |||
2730 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2731 | ("AutoNegDoneBcom, Port %d\n", Port)); | ||
2732 | pPrt = &pAC->GIni.GP[Port]; | ||
2733 | |||
2734 | /* Get PHY parameters */ | ||
2735 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LPAb); | ||
2736 | #ifdef TEST_ONLY | ||
2737 | 01-Sep-2000 RA;:;: | ||
2738 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb); | ||
2739 | #endif /* 0 */ | ||
2740 | |||
2741 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &AuxStat); | ||
2742 | |||
2743 | if ((LPAb & PHY_B_AN_RF) != 0) { | ||
2744 | /* Remote fault bit is set: Error */ | ||
2745 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2746 | ("AutoNegFail: Remote fault bit set Port %d\n", Port)); | ||
2747 | pPrt->PAutoNegFail = SK_TRUE; | ||
2748 | return(SK_AND_OTHER); | ||
2749 | } | ||
2750 | |||
2751 | /* Check Duplex mismatch */ | ||
2752 | if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000FD) { | ||
2753 | pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL; | ||
2754 | } | ||
2755 | else if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000HD) { | ||
2756 | pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF; | ||
2757 | } | ||
2758 | else { | ||
2759 | /* Error */ | ||
2760 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2761 | ("AutoNegFail: Duplex mode mismatch Port %d\n", Port)); | ||
2762 | pPrt->PAutoNegFail = SK_TRUE; | ||
2763 | return(SK_AND_DUP_CAP); | ||
2764 | } | ||
2765 | |||
2766 | #ifdef TEST_ONLY | ||
2767 | 01-Sep-2000 RA;:;: | ||
2768 | /* Check Master/Slave resolution */ | ||
2769 | if ((ResAb & PHY_B_1000S_MSF) != 0) { | ||
2770 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2771 | ("Master/Slave Fault Port %d\n", Port)); | ||
2772 | pPrt->PAutoNegFail = SK_TRUE; | ||
2773 | pPrt->PMSStatus = SK_MS_STAT_FAULT; | ||
2774 | return(SK_AND_OTHER); | ||
2775 | } | ||
2776 | |||
2777 | pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? | ||
2778 | SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE; | ||
2779 | #endif /* 0 */ | ||
2780 | |||
2781 | /* Check PAUSE mismatch ??? */ | ||
2782 | /* We are using IEEE 802.3z/D5.0 Table 37-4 */ | ||
2783 | if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PAUSE_MSK) { | ||
2784 | /* Symmetric PAUSE */ | ||
2785 | pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; | ||
2786 | } | ||
2787 | else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRR) { | ||
2788 | /* Enable PAUSE receive, disable PAUSE transmit */ | ||
2789 | pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND; | ||
2790 | } | ||
2791 | else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRT) { | ||
2792 | /* Disable PAUSE receive, enable PAUSE transmit */ | ||
2793 | pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND; | ||
2794 | } | ||
2795 | else { | ||
2796 | /* PAUSE mismatch -> no PAUSE */ | ||
2797 | pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; | ||
2798 | } | ||
2799 | pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; | ||
2800 | |||
2801 | return(SK_AND_OK); | ||
2802 | } /* SkXmAutoNegDoneBcom */ | ||
2803 | #endif /* GENESIS */ | ||
2804 | |||
2805 | |||
2806 | #ifdef YUKON | ||
2807 | /****************************************************************************** | ||
2808 | * | ||
2809 | * SkGmAutoNegDoneMarv() - Auto-negotiation handling | ||
2810 | * | ||
2811 | * Description: | ||
2812 | * This function handles the auto-negotiation if the Done bit is set. | ||
2813 | * | ||
2814 | * Returns: | ||
2815 | * SK_AND_OK o.k. | ||
2816 | * SK_AND_DUP_CAP Duplex capability error happened | ||
2817 | * SK_AND_OTHER Other error happened | ||
2818 | */ | ||
2819 | static int SkGmAutoNegDoneMarv( | ||
2820 | SK_AC *pAC, /* adapter context */ | ||
2821 | SK_IOC IoC, /* IO context */ | ||
2822 | int Port) /* Port Index (MAC_1 + n) */ | ||
2823 | { | ||
2824 | SK_GEPORT *pPrt; | ||
2825 | SK_U16 LPAb; /* Link Partner Ability */ | ||
2826 | SK_U16 ResAb; /* Resolved Ability */ | ||
2827 | SK_U16 AuxStat; /* Auxiliary Status */ | ||
2828 | |||
2829 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2830 | ("AutoNegDoneMarv, Port %d\n", Port)); | ||
2831 | pPrt = &pAC->GIni.GP[Port]; | ||
2832 | |||
2833 | /* Get PHY parameters */ | ||
2834 | SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_LP, &LPAb); | ||
2835 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2836 | ("Link P.Abil.=0x%04X\n", LPAb)); | ||
2837 | |||
2838 | if ((LPAb & PHY_M_AN_RF) != 0) { | ||
2839 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2840 | ("AutoNegFail: Remote fault bit set Port %d\n", Port)); | ||
2841 | pPrt->PAutoNegFail = SK_TRUE; | ||
2842 | return(SK_AND_OTHER); | ||
2843 | } | ||
2844 | |||
2845 | SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb); | ||
2846 | |||
2847 | /* Check Master/Slave resolution */ | ||
2848 | if ((ResAb & PHY_B_1000S_MSF) != 0) { | ||
2849 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2850 | ("Master/Slave Fault Port %d\n", Port)); | ||
2851 | pPrt->PAutoNegFail = SK_TRUE; | ||
2852 | pPrt->PMSStatus = SK_MS_STAT_FAULT; | ||
2853 | return(SK_AND_OTHER); | ||
2854 | } | ||
2855 | |||
2856 | pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? | ||
2857 | (SK_U8)SK_MS_STAT_MASTER : (SK_U8)SK_MS_STAT_SLAVE; | ||
2858 | |||
2859 | /* Read PHY Specific Status */ | ||
2860 | SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &AuxStat); | ||
2861 | |||
2862 | /* Check Speed & Duplex resolved */ | ||
2863 | if ((AuxStat & PHY_M_PS_SPDUP_RES) == 0) { | ||
2864 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2865 | ("AutoNegFail: Speed & Duplex not resolved, Port %d\n", Port)); | ||
2866 | pPrt->PAutoNegFail = SK_TRUE; | ||
2867 | pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN; | ||
2868 | return(SK_AND_DUP_CAP); | ||
2869 | } | ||
2870 | |||
2871 | if ((AuxStat & PHY_M_PS_FULL_DUP) != 0) { | ||
2872 | pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL; | ||
2873 | } | ||
2874 | else { | ||
2875 | pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF; | ||
2876 | } | ||
2877 | |||
2878 | /* Check PAUSE mismatch ??? */ | ||
2879 | /* We are using IEEE 802.3z/D5.0 Table 37-4 */ | ||
2880 | if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_PAUSE_MSK) { | ||
2881 | /* Symmetric PAUSE */ | ||
2882 | pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; | ||
2883 | } | ||
2884 | else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_RX_P_EN) { | ||
2885 | /* Enable PAUSE receive, disable PAUSE transmit */ | ||
2886 | pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND; | ||
2887 | } | ||
2888 | else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_TX_P_EN) { | ||
2889 | /* Disable PAUSE receive, enable PAUSE transmit */ | ||
2890 | pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND; | ||
2891 | } | ||
2892 | else { | ||
2893 | /* PAUSE mismatch -> no PAUSE */ | ||
2894 | pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; | ||
2895 | } | ||
2896 | |||
2897 | /* set used link speed */ | ||
2898 | switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) { | ||
2899 | case (unsigned)PHY_M_PS_SPEED_1000: | ||
2900 | pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; | ||
2901 | break; | ||
2902 | case PHY_M_PS_SPEED_100: | ||
2903 | pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS; | ||
2904 | break; | ||
2905 | default: | ||
2906 | pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS; | ||
2907 | } | ||
2908 | |||
2909 | return(SK_AND_OK); | ||
2910 | } /* SkGmAutoNegDoneMarv */ | ||
2911 | #endif /* YUKON */ | ||
2912 | |||
2913 | |||
2914 | #ifdef OTHER_PHY | ||
2915 | /****************************************************************************** | ||
2916 | * | ||
2917 | * SkXmAutoNegDoneLone() - Auto-negotiation handling | ||
2918 | * | ||
2919 | * Description: | ||
2920 | * This function handles the auto-negotiation if the Done bit is set. | ||
2921 | * | ||
2922 | * Returns: | ||
2923 | * SK_AND_OK o.k. | ||
2924 | * SK_AND_DUP_CAP Duplex capability error happened | ||
2925 | * SK_AND_OTHER Other error happened | ||
2926 | */ | ||
2927 | static int SkXmAutoNegDoneLone( | ||
2928 | SK_AC *pAC, /* adapter context */ | ||
2929 | SK_IOC IoC, /* IO context */ | ||
2930 | int Port) /* Port Index (MAC_1 + n) */ | ||
2931 | { | ||
2932 | SK_GEPORT *pPrt; | ||
2933 | SK_U16 ResAb; /* Resolved Ability */ | ||
2934 | SK_U16 LPAb; /* Link Partner Ability */ | ||
2935 | SK_U16 QuickStat; /* Auxiliary Status */ | ||
2936 | |||
2937 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2938 | ("AutoNegDoneLone, Port %d\n", Port)); | ||
2939 | pPrt = &pAC->GIni.GP[Port]; | ||
2940 | |||
2941 | /* Get PHY parameters */ | ||
2942 | SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LPAb); | ||
2943 | SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ResAb); | ||
2944 | SkXmPhyRead(pAC, IoC, Port, PHY_LONE_Q_STAT, &QuickStat); | ||
2945 | |||
2946 | if ((LPAb & PHY_L_AN_RF) != 0) { | ||
2947 | /* Remote fault bit is set */ | ||
2948 | /* Error */ | ||
2949 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2950 | ("AutoNegFail: Remote fault bit set Port %d\n", Port)); | ||
2951 | pPrt->PAutoNegFail = SK_TRUE; | ||
2952 | return(SK_AND_OTHER); | ||
2953 | } | ||
2954 | |||
2955 | /* Check Duplex mismatch */ | ||
2956 | if ((QuickStat & PHY_L_QS_DUP_MOD) != 0) { | ||
2957 | pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL; | ||
2958 | } | ||
2959 | else { | ||
2960 | pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF; | ||
2961 | } | ||
2962 | |||
2963 | /* Check Master/Slave resolution */ | ||
2964 | if ((ResAb & PHY_L_1000S_MSF) != 0) { | ||
2965 | /* Error */ | ||
2966 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
2967 | ("Master/Slave Fault Port %d\n", Port)); | ||
2968 | pPrt->PAutoNegFail = SK_TRUE; | ||
2969 | pPrt->PMSStatus = SK_MS_STAT_FAULT; | ||
2970 | return(SK_AND_OTHER); | ||
2971 | } | ||
2972 | else if (ResAb & PHY_L_1000S_MSR) { | ||
2973 | pPrt->PMSStatus = SK_MS_STAT_MASTER; | ||
2974 | } | ||
2975 | else { | ||
2976 | pPrt->PMSStatus = SK_MS_STAT_SLAVE; | ||
2977 | } | ||
2978 | |||
2979 | /* Check PAUSE mismatch */ | ||
2980 | /* We are using IEEE 802.3z/D5.0 Table 37-4 */ | ||
2981 | /* we must manually resolve the abilities here */ | ||
2982 | pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; | ||
2983 | |||
2984 | switch (pPrt->PFlowCtrlMode) { | ||
2985 | case SK_FLOW_MODE_NONE: | ||
2986 | /* default */ | ||
2987 | break; | ||
2988 | case SK_FLOW_MODE_LOC_SEND: | ||
2989 | if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) == | ||
2990 | (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) { | ||
2991 | /* Disable PAUSE receive, enable PAUSE transmit */ | ||
2992 | pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND; | ||
2993 | } | ||
2994 | break; | ||
2995 | case SK_FLOW_MODE_SYMMETRIC: | ||
2996 | if ((QuickStat & PHY_L_QS_PAUSE) != 0) { | ||
2997 | /* Symmetric PAUSE */ | ||
2998 | pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; | ||
2999 | } | ||
3000 | break; | ||
3001 | case SK_FLOW_MODE_SYM_OR_REM: | ||
3002 | if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) == | ||
3003 | PHY_L_QS_AS_PAUSE) { | ||
3004 | /* Enable PAUSE receive, disable PAUSE transmit */ | ||
3005 | pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND; | ||
3006 | } | ||
3007 | else if ((QuickStat & PHY_L_QS_PAUSE) != 0) { | ||
3008 | /* Symmetric PAUSE */ | ||
3009 | pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; | ||
3010 | } | ||
3011 | break; | ||
3012 | default: | ||
3013 | SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, | ||
3014 | SKERR_HWI_E016MSG); | ||
3015 | } | ||
3016 | |||
3017 | return(SK_AND_OK); | ||
3018 | } /* SkXmAutoNegDoneLone */ | ||
3019 | |||
3020 | |||
3021 | /****************************************************************************** | ||
3022 | * | ||
3023 | * SkXmAutoNegDoneNat() - Auto-negotiation handling | ||
3024 | * | ||
3025 | * Description: | ||
3026 | * This function handles the auto-negotiation if the Done bit is set. | ||
3027 | * | ||
3028 | * Returns: | ||
3029 | * SK_AND_OK o.k. | ||
3030 | * SK_AND_DUP_CAP Duplex capability error happened | ||
3031 | * SK_AND_OTHER Other error happened | ||
3032 | */ | ||
3033 | static int SkXmAutoNegDoneNat( | ||
3034 | SK_AC *pAC, /* adapter context */ | ||
3035 | SK_IOC IoC, /* IO context */ | ||
3036 | int Port) /* Port Index (MAC_1 + n) */ | ||
3037 | { | ||
3038 | /* todo: National */ | ||
3039 | return(SK_AND_OK); | ||
3040 | } /* SkXmAutoNegDoneNat */ | ||
3041 | #endif /* OTHER_PHY */ | ||
3042 | |||
3043 | |||
3044 | /****************************************************************************** | ||
3045 | * | ||
3046 | * SkMacAutoNegDone() - Auto-negotiation handling | ||
3047 | * | ||
3048 | * Description: calls the auto-negotiation done routines dep. on board type | ||
3049 | * | ||
3050 | * Returns: | ||
3051 | * SK_AND_OK o.k. | ||
3052 | * SK_AND_DUP_CAP Duplex capability error happened | ||
3053 | * SK_AND_OTHER Other error happened | ||
3054 | */ | ||
3055 | int SkMacAutoNegDone( | ||
3056 | SK_AC *pAC, /* adapter context */ | ||
3057 | SK_IOC IoC, /* IO context */ | ||
3058 | int Port) /* Port Index (MAC_1 + n) */ | ||
3059 | { | ||
3060 | SK_GEPORT *pPrt; | ||
3061 | int Rtv; | ||
3062 | |||
3063 | Rtv = SK_AND_OK; | ||
3064 | |||
3065 | pPrt = &pAC->GIni.GP[Port]; | ||
3066 | |||
3067 | #ifdef GENESIS | ||
3068 | if (pAC->GIni.GIGenesis) { | ||
3069 | |||
3070 | switch (pPrt->PhyType) { | ||
3071 | |||
3072 | case SK_PHY_XMAC: | ||
3073 | Rtv = SkXmAutoNegDoneXmac(pAC, IoC, Port); | ||
3074 | break; | ||
3075 | case SK_PHY_BCOM: | ||
3076 | Rtv = SkXmAutoNegDoneBcom(pAC, IoC, Port); | ||
3077 | break; | ||
3078 | #ifdef OTHER_PHY | ||
3079 | case SK_PHY_LONE: | ||
3080 | Rtv = SkXmAutoNegDoneLone(pAC, IoC, Port); | ||
3081 | break; | ||
3082 | case SK_PHY_NAT: | ||
3083 | Rtv = SkXmAutoNegDoneNat(pAC, IoC, Port); | ||
3084 | break; | ||
3085 | #endif /* OTHER_PHY */ | ||
3086 | default: | ||
3087 | return(SK_AND_OTHER); | ||
3088 | } | ||
3089 | } | ||
3090 | #endif /* GENESIS */ | ||
3091 | |||
3092 | #ifdef YUKON | ||
3093 | if (pAC->GIni.GIYukon) { | ||
3094 | |||
3095 | Rtv = SkGmAutoNegDoneMarv(pAC, IoC, Port); | ||
3096 | } | ||
3097 | #endif /* YUKON */ | ||
3098 | |||
3099 | if (Rtv != SK_AND_OK) { | ||
3100 | return(Rtv); | ||
3101 | } | ||
3102 | |||
3103 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
3104 | ("AutoNeg done Port %d\n", Port)); | ||
3105 | |||
3106 | /* We checked everything and may now enable the link */ | ||
3107 | pPrt->PAutoNegFail = SK_FALSE; | ||
3108 | |||
3109 | SkMacRxTxEnable(pAC, IoC, Port); | ||
3110 | |||
3111 | return(SK_AND_OK); | ||
3112 | } /* SkMacAutoNegDone */ | ||
3113 | |||
3114 | |||
3115 | /****************************************************************************** | ||
3116 | * | ||
3117 | * SkMacRxTxEnable() - Enable Rx/Tx activity if port is up | ||
3118 | * | ||
3119 | * Description: enables Rx/Tx dep. on board type | ||
3120 | * | ||
3121 | * Returns: | ||
3122 | * 0 o.k. | ||
3123 | * != 0 Error happened | ||
3124 | */ | ||
3125 | int SkMacRxTxEnable( | ||
3126 | SK_AC *pAC, /* adapter context */ | ||
3127 | SK_IOC IoC, /* IO context */ | ||
3128 | int Port) /* Port Index (MAC_1 + n) */ | ||
3129 | { | ||
3130 | SK_GEPORT *pPrt; | ||
3131 | SK_U16 Reg; /* 16-bit register value */ | ||
3132 | SK_U16 IntMask; /* MAC interrupt mask */ | ||
3133 | #ifdef GENESIS | ||
3134 | SK_U16 SWord; | ||
3135 | #endif | ||
3136 | |||
3137 | pPrt = &pAC->GIni.GP[Port]; | ||
3138 | |||
3139 | if (!pPrt->PHWLinkUp) { | ||
3140 | /* The Hardware link is NOT up */ | ||
3141 | return(0); | ||
3142 | } | ||
3143 | |||
3144 | if ((pPrt->PLinkMode == SK_LMODE_AUTOHALF || | ||
3145 | pPrt->PLinkMode == SK_LMODE_AUTOFULL || | ||
3146 | pPrt->PLinkMode == SK_LMODE_AUTOBOTH) && | ||
3147 | pPrt->PAutoNegFail) { | ||
3148 | /* Auto-negotiation is not done or failed */ | ||
3149 | return(0); | ||
3150 | } | ||
3151 | |||
3152 | #ifdef GENESIS | ||
3153 | if (pAC->GIni.GIGenesis) { | ||
3154 | /* set Duplex Mode and Pause Mode */ | ||
3155 | SkXmInitDupMd(pAC, IoC, Port); | ||
3156 | |||
3157 | SkXmInitPauseMd(pAC, IoC, Port); | ||
3158 | |||
3159 | /* | ||
3160 | * Initialize the Interrupt Mask Register. Default IRQs are... | ||
3161 | * - Link Asynchronous Event | ||
3162 | * - Link Partner requests config | ||
3163 | * - Auto Negotiation Done | ||
3164 | * - Rx Counter Event Overflow | ||
3165 | * - Tx Counter Event Overflow | ||
3166 | * - Transmit FIFO Underrun | ||
3167 | */ | ||
3168 | IntMask = XM_DEF_MSK; | ||
3169 | |||
3170 | #ifdef DEBUG | ||
3171 | /* add IRQ for Receive FIFO Overflow */ | ||
3172 | IntMask &= ~XM_IS_RXF_OV; | ||
3173 | #endif /* DEBUG */ | ||
3174 | |||
3175 | if (pPrt->PhyType != SK_PHY_XMAC) { | ||
3176 | /* disable GP0 interrupt bit */ | ||
3177 | IntMask |= XM_IS_INP_ASS; | ||
3178 | } | ||
3179 | XM_OUT16(IoC, Port, XM_IMSK, IntMask); | ||
3180 | |||
3181 | /* get MMU Command Reg. */ | ||
3182 | XM_IN16(IoC, Port, XM_MMU_CMD, &Reg); | ||
3183 | |||
3184 | if (pPrt->PhyType != SK_PHY_XMAC && | ||
3185 | (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL || | ||
3186 | pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL)) { | ||
3187 | /* set to Full Duplex */ | ||
3188 | Reg |= XM_MMU_GMII_FD; | ||
3189 | } | ||
3190 | |||
3191 | switch (pPrt->PhyType) { | ||
3192 | case SK_PHY_BCOM: | ||
3193 | /* | ||
3194 | * Workaround BCOM Errata (#10523) for all BCom Phys | ||
3195 | * Enable Power Management after link up | ||
3196 | */ | ||
3197 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord); | ||
3198 | SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, | ||
3199 | (SK_U16)(SWord & ~PHY_B_AC_DIS_PM)); | ||
3200 | SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, | ||
3201 | (SK_U16)PHY_B_DEF_MSK); | ||
3202 | break; | ||
3203 | #ifdef OTHER_PHY | ||
3204 | case SK_PHY_LONE: | ||
3205 | SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, PHY_L_DEF_MSK); | ||
3206 | break; | ||
3207 | case SK_PHY_NAT: | ||
3208 | /* todo National: | ||
3209 | SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, PHY_N_DEF_MSK); */ | ||
3210 | /* no interrupts possible from National ??? */ | ||
3211 | break; | ||
3212 | #endif /* OTHER_PHY */ | ||
3213 | } | ||
3214 | |||
3215 | /* enable Rx/Tx */ | ||
3216 | XM_OUT16(IoC, Port, XM_MMU_CMD, Reg | XM_MMU_ENA_RX | XM_MMU_ENA_TX); | ||
3217 | } | ||
3218 | #endif /* GENESIS */ | ||
3219 | |||
3220 | #ifdef YUKON | ||
3221 | if (pAC->GIni.GIYukon) { | ||
3222 | /* | ||
3223 | * Initialize the Interrupt Mask Register. Default IRQs are... | ||
3224 | * - Rx Counter Event Overflow | ||
3225 | * - Tx Counter Event Overflow | ||
3226 | * - Transmit FIFO Underrun | ||
3227 | */ | ||
3228 | IntMask = GMAC_DEF_MSK; | ||
3229 | |||
3230 | #ifdef DEBUG | ||
3231 | /* add IRQ for Receive FIFO Overrun */ | ||
3232 | IntMask |= GM_IS_RX_FF_OR; | ||
3233 | #endif /* DEBUG */ | ||
3234 | |||
3235 | SK_OUT8(IoC, GMAC_IRQ_MSK, (SK_U8)IntMask); | ||
3236 | |||
3237 | /* get General Purpose Control */ | ||
3238 | GM_IN16(IoC, Port, GM_GP_CTRL, &Reg); | ||
3239 | |||
3240 | if (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL || | ||
3241 | pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) { | ||
3242 | /* set to Full Duplex */ | ||
3243 | Reg |= GM_GPCR_DUP_FULL; | ||
3244 | } | ||
3245 | |||
3246 | /* enable Rx/Tx */ | ||
3247 | GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Reg | GM_GPCR_RX_ENA | | ||
3248 | GM_GPCR_TX_ENA)); | ||
3249 | |||
3250 | #ifndef VCPU | ||
3251 | /* Enable all PHY interrupts */ | ||
3252 | SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, | ||
3253 | (SK_U16)PHY_M_DEF_MSK); | ||
3254 | #endif /* VCPU */ | ||
3255 | } | ||
3256 | #endif /* YUKON */ | ||
3257 | |||
3258 | return(0); | ||
3259 | |||
3260 | } /* SkMacRxTxEnable */ | ||
3261 | |||
3262 | |||
3263 | /****************************************************************************** | ||
3264 | * | ||
3265 | * SkMacRxTxDisable() - Disable Receiver and Transmitter | ||
3266 | * | ||
3267 | * Description: disables Rx/Tx dep. on board type | ||
3268 | * | ||
3269 | * Returns: N/A | ||
3270 | */ | ||
3271 | void SkMacRxTxDisable( | ||
3272 | SK_AC *pAC, /* Adapter Context */ | ||
3273 | SK_IOC IoC, /* IO context */ | ||
3274 | int Port) /* Port Index (MAC_1 + n) */ | ||
3275 | { | ||
3276 | SK_U16 Word; | ||
3277 | |||
3278 | #ifdef GENESIS | ||
3279 | if (pAC->GIni.GIGenesis) { | ||
3280 | |||
3281 | XM_IN16(IoC, Port, XM_MMU_CMD, &Word); | ||
3282 | |||
3283 | XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX)); | ||
3284 | |||
3285 | /* dummy read to ensure writing */ | ||
3286 | XM_IN16(IoC, Port, XM_MMU_CMD, &Word); | ||
3287 | } | ||
3288 | #endif /* GENESIS */ | ||
3289 | |||
3290 | #ifdef YUKON | ||
3291 | if (pAC->GIni.GIYukon) { | ||
3292 | |||
3293 | GM_IN16(IoC, Port, GM_GP_CTRL, &Word); | ||
3294 | |||
3295 | GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Word & ~(GM_GPCR_RX_ENA | | ||
3296 | GM_GPCR_TX_ENA))); | ||
3297 | |||
3298 | /* dummy read to ensure writing */ | ||
3299 | GM_IN16(IoC, Port, GM_GP_CTRL, &Word); | ||
3300 | } | ||
3301 | #endif /* YUKON */ | ||
3302 | |||
3303 | } /* SkMacRxTxDisable */ | ||
3304 | |||
3305 | |||
3306 | /****************************************************************************** | ||
3307 | * | ||
3308 | * SkMacIrqDisable() - Disable IRQ from MAC | ||
3309 | * | ||
3310 | * Description: sets the IRQ-mask to disable IRQ dep. on board type | ||
3311 | * | ||
3312 | * Returns: N/A | ||
3313 | */ | ||
3314 | void SkMacIrqDisable( | ||
3315 | SK_AC *pAC, /* Adapter Context */ | ||
3316 | SK_IOC IoC, /* IO context */ | ||
3317 | int Port) /* Port Index (MAC_1 + n) */ | ||
3318 | { | ||
3319 | SK_GEPORT *pPrt; | ||
3320 | #ifdef GENESIS | ||
3321 | SK_U16 Word; | ||
3322 | #endif | ||
3323 | |||
3324 | pPrt = &pAC->GIni.GP[Port]; | ||
3325 | |||
3326 | #ifdef GENESIS | ||
3327 | if (pAC->GIni.GIGenesis) { | ||
3328 | |||
3329 | /* disable all XMAC IRQs */ | ||
3330 | XM_OUT16(IoC, Port, XM_IMSK, 0xffff); | ||
3331 | |||
3332 | /* Disable all PHY interrupts */ | ||
3333 | switch (pPrt->PhyType) { | ||
3334 | case SK_PHY_BCOM: | ||
3335 | /* Make sure that PHY is initialized */ | ||
3336 | if (pPrt->PState != SK_PRT_RESET) { | ||
3337 | /* NOT allowed if BCOM is in RESET state */ | ||
3338 | /* Workaround BCOM Errata (#10523) all BCom */ | ||
3339 | /* Disable Power Management if link is down */ | ||
3340 | SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Word); | ||
3341 | SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, | ||
3342 | (SK_U16)(Word | PHY_B_AC_DIS_PM)); | ||
3343 | SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, 0xffff); | ||
3344 | } | ||
3345 | break; | ||
3346 | #ifdef OTHER_PHY | ||
3347 | case SK_PHY_LONE: | ||
3348 | SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, 0); | ||
3349 | break; | ||
3350 | case SK_PHY_NAT: | ||
3351 | /* todo: National | ||
3352 | SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, 0xffff); */ | ||
3353 | break; | ||
3354 | #endif /* OTHER_PHY */ | ||
3355 | } | ||
3356 | } | ||
3357 | #endif /* GENESIS */ | ||
3358 | |||
3359 | #ifdef YUKON | ||
3360 | if (pAC->GIni.GIYukon) { | ||
3361 | /* disable all GMAC IRQs */ | ||
3362 | SK_OUT8(IoC, GMAC_IRQ_MSK, 0); | ||
3363 | |||
3364 | #ifndef VCPU | ||
3365 | /* Disable all PHY interrupts */ | ||
3366 | SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0); | ||
3367 | #endif /* VCPU */ | ||
3368 | } | ||
3369 | #endif /* YUKON */ | ||
3370 | |||
3371 | } /* SkMacIrqDisable */ | ||
3372 | |||
3373 | |||
3374 | #ifdef SK_DIAG | ||
3375 | /****************************************************************************** | ||
3376 | * | ||
3377 | * SkXmSendCont() - Enable / Disable Send Continuous Mode | ||
3378 | * | ||
3379 | * Description: enable / disable Send Continuous Mode on XMAC | ||
3380 | * | ||
3381 | * Returns: | ||
3382 | * nothing | ||
3383 | */ | ||
3384 | void SkXmSendCont( | ||
3385 | SK_AC *pAC, /* adapter context */ | ||
3386 | SK_IOC IoC, /* IO context */ | ||
3387 | int Port, /* Port Index (MAC_1 + n) */ | ||
3388 | SK_BOOL Enable) /* Enable / Disable */ | ||
3389 | { | ||
3390 | SK_U32 MdReg; | ||
3391 | |||
3392 | XM_IN32(IoC, Port, XM_MODE, &MdReg); | ||
3393 | |||
3394 | if (Enable) { | ||
3395 | MdReg |= XM_MD_TX_CONT; | ||
3396 | } | ||
3397 | else { | ||
3398 | MdReg &= ~XM_MD_TX_CONT; | ||
3399 | } | ||
3400 | /* setup Mode Register */ | ||
3401 | XM_OUT32(IoC, Port, XM_MODE, MdReg); | ||
3402 | |||
3403 | } /* SkXmSendCont */ | ||
3404 | |||
3405 | |||
3406 | /****************************************************************************** | ||
3407 | * | ||
3408 | * SkMacTimeStamp() - Enable / Disable Time Stamp | ||
3409 | * | ||
3410 | * Description: enable / disable Time Stamp generation for Rx packets | ||
3411 | * | ||
3412 | * Returns: | ||
3413 | * nothing | ||
3414 | */ | ||
3415 | void SkMacTimeStamp( | ||
3416 | SK_AC *pAC, /* adapter context */ | ||
3417 | SK_IOC IoC, /* IO context */ | ||
3418 | int Port, /* Port Index (MAC_1 + n) */ | ||
3419 | SK_BOOL Enable) /* Enable / Disable */ | ||
3420 | { | ||
3421 | SK_U32 MdReg; | ||
3422 | SK_U8 TimeCtrl; | ||
3423 | |||
3424 | if (pAC->GIni.GIGenesis) { | ||
3425 | |||
3426 | XM_IN32(IoC, Port, XM_MODE, &MdReg); | ||
3427 | |||
3428 | if (Enable) { | ||
3429 | MdReg |= XM_MD_ATS; | ||
3430 | } | ||
3431 | else { | ||
3432 | MdReg &= ~XM_MD_ATS; | ||
3433 | } | ||
3434 | /* setup Mode Register */ | ||
3435 | XM_OUT32(IoC, Port, XM_MODE, MdReg); | ||
3436 | } | ||
3437 | else { | ||
3438 | if (Enable) { | ||
3439 | TimeCtrl = GMT_ST_START | GMT_ST_CLR_IRQ; | ||
3440 | } | ||
3441 | else { | ||
3442 | TimeCtrl = GMT_ST_STOP | GMT_ST_CLR_IRQ; | ||
3443 | } | ||
3444 | /* Start/Stop Time Stamp Timer */ | ||
3445 | SK_OUT8(IoC, GMAC_TI_ST_CTRL, TimeCtrl); | ||
3446 | } | ||
3447 | |||
3448 | } /* SkMacTimeStamp*/ | ||
3449 | |||
3450 | #else /* !SK_DIAG */ | ||
3451 | |||
3452 | #ifdef GENESIS | ||
3453 | /****************************************************************************** | ||
3454 | * | ||
3455 | * SkXmAutoNegLipaXmac() - Decides whether Link Partner could do auto-neg | ||
3456 | * | ||
3457 | * This function analyses the Interrupt status word. If any of the | ||
3458 | * Auto-negotiating interrupt bits are set, the PLipaAutoNeg variable | ||
3459 | * is set true. | ||
3460 | */ | ||
3461 | void SkXmAutoNegLipaXmac( | ||
3462 | SK_AC *pAC, /* adapter context */ | ||
3463 | SK_IOC IoC, /* IO context */ | ||
3464 | int Port, /* Port Index (MAC_1 + n) */ | ||
3465 | SK_U16 IStatus) /* Interrupt Status word to analyse */ | ||
3466 | { | ||
3467 | SK_GEPORT *pPrt; | ||
3468 | |||
3469 | pPrt = &pAC->GIni.GP[Port]; | ||
3470 | |||
3471 | if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO && | ||
3472 | (IStatus & (XM_IS_LIPA_RC | XM_IS_RX_PAGE | XM_IS_AND)) != 0) { | ||
3473 | |||
3474 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
3475 | ("AutoNegLipa: AutoNeg detected on Port %d, IStatus=0x%04X\n", | ||
3476 | Port, IStatus)); | ||
3477 | pPrt->PLipaAutoNeg = SK_LIPA_AUTO; | ||
3478 | } | ||
3479 | } /* SkXmAutoNegLipaXmac */ | ||
3480 | #endif /* GENESIS */ | ||
3481 | |||
3482 | |||
3483 | /****************************************************************************** | ||
3484 | * | ||
3485 | * SkMacAutoNegLipaPhy() - Decides whether Link Partner could do auto-neg | ||
3486 | * | ||
3487 | * This function analyses the PHY status word. | ||
3488 | * If any of the Auto-negotiating bits are set, the PLipaAutoNeg variable | ||
3489 | * is set true. | ||
3490 | */ | ||
3491 | void SkMacAutoNegLipaPhy( | ||
3492 | SK_AC *pAC, /* adapter context */ | ||
3493 | SK_IOC IoC, /* IO context */ | ||
3494 | int Port, /* Port Index (MAC_1 + n) */ | ||
3495 | SK_U16 PhyStat) /* PHY Status word to analyse */ | ||
3496 | { | ||
3497 | SK_GEPORT *pPrt; | ||
3498 | |||
3499 | pPrt = &pAC->GIni.GP[Port]; | ||
3500 | |||
3501 | if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO && | ||
3502 | (PhyStat & PHY_ST_AN_OVER) != 0) { | ||
3503 | |||
3504 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
3505 | ("AutoNegLipa: AutoNeg detected on Port %d, PhyStat=0x%04X\n", | ||
3506 | Port, PhyStat)); | ||
3507 | pPrt->PLipaAutoNeg = SK_LIPA_AUTO; | ||
3508 | } | ||
3509 | } /* SkMacAutoNegLipaPhy */ | ||
3510 | |||
3511 | |||
3512 | #ifdef GENESIS | ||
3513 | /****************************************************************************** | ||
3514 | * | ||
3515 | * SkXmIrq() - Interrupt Service Routine | ||
3516 | * | ||
3517 | * Description: services an Interrupt Request of the XMAC | ||
3518 | * | ||
3519 | * Note: | ||
3520 | * With an external PHY, some interrupt bits are not meaningfull any more: | ||
3521 | * - LinkAsyncEvent (bit #14) XM_IS_LNK_AE | ||
3522 | * - LinkPartnerReqConfig (bit #10) XM_IS_LIPA_RC | ||
3523 | * - Page Received (bit #9) XM_IS_RX_PAGE | ||
3524 | * - NextPageLoadedForXmt (bit #8) XM_IS_TX_PAGE | ||
3525 | * - AutoNegDone (bit #7) XM_IS_AND | ||
3526 | * Also probably not valid any more is the GP0 input bit: | ||
3527 | * - GPRegisterBit0set XM_IS_INP_ASS | ||
3528 | * | ||
3529 | * Returns: | ||
3530 | * nothing | ||
3531 | */ | ||
3532 | static void SkXmIrq( | ||
3533 | SK_AC *pAC, /* adapter context */ | ||
3534 | SK_IOC IoC, /* IO context */ | ||
3535 | int Port) /* Port Index (MAC_1 + n) */ | ||
3536 | { | ||
3537 | SK_GEPORT *pPrt; | ||
3538 | SK_EVPARA Para; | ||
3539 | SK_U16 IStatus; /* Interrupt status read from the XMAC */ | ||
3540 | SK_U16 IStatus2; | ||
3541 | #ifdef SK_SLIM | ||
3542 | SK_U64 OverflowStatus; | ||
3543 | #endif | ||
3544 | |||
3545 | pPrt = &pAC->GIni.GP[Port]; | ||
3546 | |||
3547 | XM_IN16(IoC, Port, XM_ISRC, &IStatus); | ||
3548 | |||
3549 | /* LinkPartner Auto-negable? */ | ||
3550 | if (pPrt->PhyType == SK_PHY_XMAC) { | ||
3551 | SkXmAutoNegLipaXmac(pAC, IoC, Port, IStatus); | ||
3552 | } | ||
3553 | else { | ||
3554 | /* mask bits that are not used with ext. PHY */ | ||
3555 | IStatus &= ~(XM_IS_LNK_AE | XM_IS_LIPA_RC | | ||
3556 | XM_IS_RX_PAGE | XM_IS_TX_PAGE | | ||
3557 | XM_IS_AND | XM_IS_INP_ASS); | ||
3558 | } | ||
3559 | |||
3560 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, | ||
3561 | ("XmacIrq Port %d Isr 0x%04X\n", Port, IStatus)); | ||
3562 | |||
3563 | if (!pPrt->PHWLinkUp) { | ||
3564 | /* Spurious XMAC interrupt */ | ||
3565 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, | ||
3566 | ("SkXmIrq: spurious interrupt on Port %d\n", Port)); | ||
3567 | return; | ||
3568 | } | ||
3569 | |||
3570 | if ((IStatus & XM_IS_INP_ASS) != 0) { | ||
3571 | /* Reread ISR Register if link is not in sync */ | ||
3572 | XM_IN16(IoC, Port, XM_ISRC, &IStatus2); | ||
3573 | |||
3574 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, | ||
3575 | ("SkXmIrq: Link async. Double check Port %d 0x%04X 0x%04X\n", | ||
3576 | Port, IStatus, IStatus2)); | ||
3577 | IStatus &= ~XM_IS_INP_ASS; | ||
3578 | IStatus |= IStatus2; | ||
3579 | } | ||
3580 | |||
3581 | if ((IStatus & XM_IS_LNK_AE) != 0) { | ||
3582 | /* not used, GP0 is used instead */ | ||
3583 | } | ||
3584 | |||
3585 | if ((IStatus & XM_IS_TX_ABORT) != 0) { | ||
3586 | /* not used */ | ||
3587 | } | ||
3588 | |||
3589 | if ((IStatus & XM_IS_FRC_INT) != 0) { | ||
3590 | /* not used, use ASIC IRQ instead if needed */ | ||
3591 | } | ||
3592 | |||
3593 | if ((IStatus & (XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE)) != 0) { | ||
3594 | SkHWLinkDown(pAC, IoC, Port); | ||
3595 | |||
3596 | /* Signal to RLMT */ | ||
3597 | Para.Para32[0] = (SK_U32)Port; | ||
3598 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); | ||
3599 | |||
3600 | /* Start workaround Errata #2 timer */ | ||
3601 | SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME, | ||
3602 | SKGE_HWAC, SK_HWEV_WATIM, Para); | ||
3603 | } | ||
3604 | |||
3605 | if ((IStatus & XM_IS_RX_PAGE) != 0) { | ||
3606 | /* not used */ | ||
3607 | } | ||
3608 | |||
3609 | if ((IStatus & XM_IS_TX_PAGE) != 0) { | ||
3610 | /* not used */ | ||
3611 | } | ||
3612 | |||
3613 | if ((IStatus & XM_IS_AND) != 0) { | ||
3614 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, | ||
3615 | ("SkXmIrq: AND on link that is up Port %d\n", Port)); | ||
3616 | } | ||
3617 | |||
3618 | if ((IStatus & XM_IS_TSC_OV) != 0) { | ||
3619 | /* not used */ | ||
3620 | } | ||
3621 | |||
3622 | /* Combined Tx & Rx Counter Overflow SIRQ Event */ | ||
3623 | if ((IStatus & (XM_IS_RXC_OV | XM_IS_TXC_OV)) != 0) { | ||
3624 | #ifdef SK_SLIM | ||
3625 | SkXmOverflowStatus(pAC, IoC, Port, IStatus, &OverflowStatus); | ||
3626 | #else | ||
3627 | Para.Para32[0] = (SK_U32)Port; | ||
3628 | Para.Para32[1] = (SK_U32)IStatus; | ||
3629 | SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para); | ||
3630 | #endif /* SK_SLIM */ | ||
3631 | } | ||
3632 | |||
3633 | if ((IStatus & XM_IS_RXF_OV) != 0) { | ||
3634 | /* normal situation -> no effect */ | ||
3635 | #ifdef DEBUG | ||
3636 | pPrt->PRxOverCnt++; | ||
3637 | #endif /* DEBUG */ | ||
3638 | } | ||
3639 | |||
3640 | if ((IStatus & XM_IS_TXF_UR) != 0) { | ||
3641 | /* may NOT happen -> error log */ | ||
3642 | SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E020, SKERR_SIRQ_E020MSG); | ||
3643 | } | ||
3644 | |||
3645 | if ((IStatus & XM_IS_TX_COMP) != 0) { | ||
3646 | /* not served here */ | ||
3647 | } | ||
3648 | |||
3649 | if ((IStatus & XM_IS_RX_COMP) != 0) { | ||
3650 | /* not served here */ | ||
3651 | } | ||
3652 | } /* SkXmIrq */ | ||
3653 | #endif /* GENESIS */ | ||
3654 | |||
3655 | |||
3656 | #ifdef YUKON | ||
3657 | /****************************************************************************** | ||
3658 | * | ||
3659 | * SkGmIrq() - Interrupt Service Routine | ||
3660 | * | ||
3661 | * Description: services an Interrupt Request of the GMAC | ||
3662 | * | ||
3663 | * Note: | ||
3664 | * | ||
3665 | * Returns: | ||
3666 | * nothing | ||
3667 | */ | ||
3668 | static void SkGmIrq( | ||
3669 | SK_AC *pAC, /* adapter context */ | ||
3670 | SK_IOC IoC, /* IO context */ | ||
3671 | int Port) /* Port Index (MAC_1 + n) */ | ||
3672 | { | ||
3673 | SK_GEPORT *pPrt; | ||
3674 | SK_U8 IStatus; /* Interrupt status */ | ||
3675 | #ifdef SK_SLIM | ||
3676 | SK_U64 OverflowStatus; | ||
3677 | #else | ||
3678 | SK_EVPARA Para; | ||
3679 | #endif | ||
3680 | |||
3681 | pPrt = &pAC->GIni.GP[Port]; | ||
3682 | |||
3683 | SK_IN8(IoC, GMAC_IRQ_SRC, &IStatus); | ||
3684 | |||
3685 | #ifdef XXX | ||
3686 | /* LinkPartner Auto-negable? */ | ||
3687 | SkMacAutoNegLipaPhy(pAC, IoC, Port, IStatus); | ||
3688 | #endif /* XXX */ | ||
3689 | |||
3690 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, | ||
3691 | ("GmacIrq Port %d Isr 0x%04X\n", Port, IStatus)); | ||
3692 | |||
3693 | /* Combined Tx & Rx Counter Overflow SIRQ Event */ | ||
3694 | if (IStatus & (GM_IS_RX_CO_OV | GM_IS_TX_CO_OV)) { | ||
3695 | /* these IRQs will be cleared by reading GMACs register */ | ||
3696 | #ifdef SK_SLIM | ||
3697 | SkGmOverflowStatus(pAC, IoC, Port, IStatus, &OverflowStatus); | ||
3698 | #else | ||
3699 | Para.Para32[0] = (SK_U32)Port; | ||
3700 | Para.Para32[1] = (SK_U32)IStatus; | ||
3701 | SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para); | ||
3702 | #endif | ||
3703 | } | ||
3704 | |||
3705 | if (IStatus & GM_IS_RX_FF_OR) { | ||
3706 | /* clear GMAC Rx FIFO Overrun IRQ */ | ||
3707 | SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_CLI_RX_FO); | ||
3708 | #ifdef DEBUG | ||
3709 | pPrt->PRxOverCnt++; | ||
3710 | #endif /* DEBUG */ | ||
3711 | } | ||
3712 | |||
3713 | if (IStatus & GM_IS_TX_FF_UR) { | ||
3714 | /* clear GMAC Tx FIFO Underrun IRQ */ | ||
3715 | SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_CLI_TX_FU); | ||
3716 | /* may NOT happen -> error log */ | ||
3717 | SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E020, SKERR_SIRQ_E020MSG); | ||
3718 | } | ||
3719 | |||
3720 | if (IStatus & GM_IS_TX_COMPL) { | ||
3721 | /* not served here */ | ||
3722 | } | ||
3723 | |||
3724 | if (IStatus & GM_IS_RX_COMPL) { | ||
3725 | /* not served here */ | ||
3726 | } | ||
3727 | } /* SkGmIrq */ | ||
3728 | #endif /* YUKON */ | ||
3729 | |||
3730 | |||
3731 | /****************************************************************************** | ||
3732 | * | ||
3733 | * SkMacIrq() - Interrupt Service Routine for MAC | ||
3734 | * | ||
3735 | * Description: calls the Interrupt Service Routine dep. on board type | ||
3736 | * | ||
3737 | * Returns: | ||
3738 | * nothing | ||
3739 | */ | ||
3740 | void SkMacIrq( | ||
3741 | SK_AC *pAC, /* adapter context */ | ||
3742 | SK_IOC IoC, /* IO context */ | ||
3743 | int Port) /* Port Index (MAC_1 + n) */ | ||
3744 | { | ||
3745 | #ifdef GENESIS | ||
3746 | if (pAC->GIni.GIGenesis) { | ||
3747 | /* IRQ from XMAC */ | ||
3748 | SkXmIrq(pAC, IoC, Port); | ||
3749 | } | ||
3750 | #endif /* GENESIS */ | ||
3751 | |||
3752 | #ifdef YUKON | ||
3753 | if (pAC->GIni.GIYukon) { | ||
3754 | /* IRQ from GMAC */ | ||
3755 | SkGmIrq(pAC, IoC, Port); | ||
3756 | } | ||
3757 | #endif /* YUKON */ | ||
3758 | |||
3759 | } /* SkMacIrq */ | ||
3760 | |||
3761 | #endif /* !SK_DIAG */ | ||
3762 | |||
3763 | #ifdef GENESIS | ||
3764 | /****************************************************************************** | ||
3765 | * | ||
3766 | * SkXmUpdateStats() - Force the XMAC to output the current statistic | ||
3767 | * | ||
3768 | * Description: | ||
3769 | * The XMAC holds its statistic internally. To obtain the current | ||
3770 | * values a command must be sent so that the statistic data will | ||
3771 | * be written to a predefined memory area on the adapter. | ||
3772 | * | ||
3773 | * Returns: | ||
3774 | * 0: success | ||
3775 | * 1: something went wrong | ||
3776 | */ | ||
3777 | int SkXmUpdateStats( | ||
3778 | SK_AC *pAC, /* adapter context */ | ||
3779 | SK_IOC IoC, /* IO context */ | ||
3780 | unsigned int Port) /* Port Index (MAC_1 + n) */ | ||
3781 | { | ||
3782 | SK_GEPORT *pPrt; | ||
3783 | SK_U16 StatReg; | ||
3784 | int WaitIndex; | ||
3785 | |||
3786 | pPrt = &pAC->GIni.GP[Port]; | ||
3787 | WaitIndex = 0; | ||
3788 | |||
3789 | /* Send an update command to XMAC specified */ | ||
3790 | XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_SNP_TXC | XM_SC_SNP_RXC); | ||
3791 | |||
3792 | /* | ||
3793 | * It is an auto-clearing register. If the command bits | ||
3794 | * went to zero again, the statistics are transferred. | ||
3795 | * Normally the command should be executed immediately. | ||
3796 | * But just to be sure we execute a loop. | ||
3797 | */ | ||
3798 | do { | ||
3799 | |||
3800 | XM_IN16(IoC, Port, XM_STAT_CMD, &StatReg); | ||
3801 | |||
3802 | if (++WaitIndex > 10) { | ||
3803 | |||
3804 | SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E021, SKERR_HWI_E021MSG); | ||
3805 | |||
3806 | return(1); | ||
3807 | } | ||
3808 | } while ((StatReg & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) != 0); | ||
3809 | |||
3810 | return(0); | ||
3811 | } /* SkXmUpdateStats */ | ||
3812 | |||
3813 | |||
3814 | /****************************************************************************** | ||
3815 | * | ||
3816 | * SkXmMacStatistic() - Get XMAC counter value | ||
3817 | * | ||
3818 | * Description: | ||
3819 | * Gets the 32bit counter value. Except for the octet counters | ||
3820 | * the lower 32bit are counted in hardware and the upper 32bit | ||
3821 | * must be counted in software by monitoring counter overflow interrupts. | ||
3822 | * | ||
3823 | * Returns: | ||
3824 | * 0: success | ||
3825 | * 1: something went wrong | ||
3826 | */ | ||
3827 | int SkXmMacStatistic( | ||
3828 | SK_AC *pAC, /* adapter context */ | ||
3829 | SK_IOC IoC, /* IO context */ | ||
3830 | unsigned int Port, /* Port Index (MAC_1 + n) */ | ||
3831 | SK_U16 StatAddr, /* MIB counter base address */ | ||
3832 | SK_U32 SK_FAR *pVal) /* ptr to return statistic value */ | ||
3833 | { | ||
3834 | if ((StatAddr < XM_TXF_OK) || (StatAddr > XM_RXF_MAX_SZ)) { | ||
3835 | |||
3836 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG); | ||
3837 | |||
3838 | return(1); | ||
3839 | } | ||
3840 | |||
3841 | XM_IN32(IoC, Port, StatAddr, pVal); | ||
3842 | |||
3843 | return(0); | ||
3844 | } /* SkXmMacStatistic */ | ||
3845 | |||
3846 | |||
3847 | /****************************************************************************** | ||
3848 | * | ||
3849 | * SkXmResetCounter() - Clear MAC statistic counter | ||
3850 | * | ||
3851 | * Description: | ||
3852 | * Force the XMAC to clear its statistic counter. | ||
3853 | * | ||
3854 | * Returns: | ||
3855 | * 0: success | ||
3856 | * 1: something went wrong | ||
3857 | */ | ||
3858 | int SkXmResetCounter( | ||
3859 | SK_AC *pAC, /* adapter context */ | ||
3860 | SK_IOC IoC, /* IO context */ | ||
3861 | unsigned int Port) /* Port Index (MAC_1 + n) */ | ||
3862 | { | ||
3863 | XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC); | ||
3864 | /* Clear two times according to Errata #3 */ | ||
3865 | XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC); | ||
3866 | |||
3867 | return(0); | ||
3868 | } /* SkXmResetCounter */ | ||
3869 | |||
3870 | |||
3871 | /****************************************************************************** | ||
3872 | * | ||
3873 | * SkXmOverflowStatus() - Gets the status of counter overflow interrupt | ||
3874 | * | ||
3875 | * Description: | ||
3876 | * Checks the source causing an counter overflow interrupt. On success the | ||
3877 | * resulting counter overflow status is written to <pStatus>, whereas the | ||
3878 | * upper dword stores the XMAC ReceiveCounterEvent register and the lower | ||
3879 | * dword the XMAC TransmitCounterEvent register. | ||
3880 | * | ||
3881 | * Note: | ||
3882 | * For XMAC the interrupt source is a self-clearing register, so the source | ||
3883 | * must be checked only once. SIRQ module does another check to be sure | ||
3884 | * that no interrupt get lost during process time. | ||
3885 | * | ||
3886 | * Returns: | ||
3887 | * 0: success | ||
3888 | * 1: something went wrong | ||
3889 | */ | ||
3890 | int SkXmOverflowStatus( | ||
3891 | SK_AC *pAC, /* adapter context */ | ||
3892 | SK_IOC IoC, /* IO context */ | ||
3893 | unsigned int Port, /* Port Index (MAC_1 + n) */ | ||
3894 | SK_U16 IStatus, /* Interupt Status from MAC */ | ||
3895 | SK_U64 SK_FAR *pStatus) /* ptr for return overflow status value */ | ||
3896 | { | ||
3897 | SK_U64 Status; /* Overflow status */ | ||
3898 | SK_U32 RegVal; | ||
3899 | |||
3900 | Status = 0; | ||
3901 | |||
3902 | if ((IStatus & XM_IS_RXC_OV) != 0) { | ||
3903 | |||
3904 | XM_IN32(IoC, Port, XM_RX_CNT_EV, &RegVal); | ||
3905 | Status |= (SK_U64)RegVal << 32; | ||
3906 | } | ||
3907 | |||
3908 | if ((IStatus & XM_IS_TXC_OV) != 0) { | ||
3909 | |||
3910 | XM_IN32(IoC, Port, XM_TX_CNT_EV, &RegVal); | ||
3911 | Status |= (SK_U64)RegVal; | ||
3912 | } | ||
3913 | |||
3914 | *pStatus = Status; | ||
3915 | |||
3916 | return(0); | ||
3917 | } /* SkXmOverflowStatus */ | ||
3918 | #endif /* GENESIS */ | ||
3919 | |||
3920 | |||
3921 | #ifdef YUKON | ||
3922 | /****************************************************************************** | ||
3923 | * | ||
3924 | * SkGmUpdateStats() - Force the GMAC to output the current statistic | ||
3925 | * | ||
3926 | * Description: | ||
3927 | * Empty function for GMAC. Statistic data is accessible in direct way. | ||
3928 | * | ||
3929 | * Returns: | ||
3930 | * 0: success | ||
3931 | * 1: something went wrong | ||
3932 | */ | ||
3933 | int SkGmUpdateStats( | ||
3934 | SK_AC *pAC, /* adapter context */ | ||
3935 | SK_IOC IoC, /* IO context */ | ||
3936 | unsigned int Port) /* Port Index (MAC_1 + n) */ | ||
3937 | { | ||
3938 | return(0); | ||
3939 | } | ||
3940 | |||
3941 | |||
3942 | /****************************************************************************** | ||
3943 | * | ||
3944 | * SkGmMacStatistic() - Get GMAC counter value | ||
3945 | * | ||
3946 | * Description: | ||
3947 | * Gets the 32bit counter value. Except for the octet counters | ||
3948 | * the lower 32bit are counted in hardware and the upper 32bit | ||
3949 | * must be counted in software by monitoring counter overflow interrupts. | ||
3950 | * | ||
3951 | * Returns: | ||
3952 | * 0: success | ||
3953 | * 1: something went wrong | ||
3954 | */ | ||
3955 | int SkGmMacStatistic( | ||
3956 | SK_AC *pAC, /* adapter context */ | ||
3957 | SK_IOC IoC, /* IO context */ | ||
3958 | unsigned int Port, /* Port Index (MAC_1 + n) */ | ||
3959 | SK_U16 StatAddr, /* MIB counter base address */ | ||
3960 | SK_U32 SK_FAR *pVal) /* ptr to return statistic value */ | ||
3961 | { | ||
3962 | |||
3963 | if ((StatAddr < GM_RXF_UC_OK) || (StatAddr > GM_TXE_FIFO_UR)) { | ||
3964 | |||
3965 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG); | ||
3966 | |||
3967 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
3968 | ("SkGmMacStat: wrong MIB counter 0x%04X\n", StatAddr)); | ||
3969 | return(1); | ||
3970 | } | ||
3971 | |||
3972 | GM_IN32(IoC, Port, StatAddr, pVal); | ||
3973 | |||
3974 | return(0); | ||
3975 | } /* SkGmMacStatistic */ | ||
3976 | |||
3977 | |||
3978 | /****************************************************************************** | ||
3979 | * | ||
3980 | * SkGmResetCounter() - Clear MAC statistic counter | ||
3981 | * | ||
3982 | * Description: | ||
3983 | * Force GMAC to clear its statistic counter. | ||
3984 | * | ||
3985 | * Returns: | ||
3986 | * 0: success | ||
3987 | * 1: something went wrong | ||
3988 | */ | ||
3989 | int SkGmResetCounter( | ||
3990 | SK_AC *pAC, /* adapter context */ | ||
3991 | SK_IOC IoC, /* IO context */ | ||
3992 | unsigned int Port) /* Port Index (MAC_1 + n) */ | ||
3993 | { | ||
3994 | SK_U16 Reg; /* Phy Address Register */ | ||
3995 | SK_U16 Word; | ||
3996 | int i; | ||
3997 | |||
3998 | GM_IN16(IoC, Port, GM_PHY_ADDR, &Reg); | ||
3999 | |||
4000 | /* set MIB Clear Counter Mode */ | ||
4001 | GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg | GM_PAR_MIB_CLR); | ||
4002 | |||
4003 | /* read all MIB Counters with Clear Mode set */ | ||
4004 | for (i = 0; i < GM_MIB_CNT_SIZE; i++) { | ||
4005 | /* the reset is performed only when the lower 16 bits are read */ | ||
4006 | GM_IN16(IoC, Port, GM_MIB_CNT_BASE + 8*i, &Word); | ||
4007 | } | ||
4008 | |||
4009 | /* clear MIB Clear Counter Mode */ | ||
4010 | GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg); | ||
4011 | |||
4012 | return(0); | ||
4013 | } /* SkGmResetCounter */ | ||
4014 | |||
4015 | |||
4016 | /****************************************************************************** | ||
4017 | * | ||
4018 | * SkGmOverflowStatus() - Gets the status of counter overflow interrupt | ||
4019 | * | ||
4020 | * Description: | ||
4021 | * Checks the source causing an counter overflow interrupt. On success the | ||
4022 | * resulting counter overflow status is written to <pStatus>, whereas the | ||
4023 | * the following bit coding is used: | ||
4024 | * 63:56 - unused | ||
4025 | * 55:48 - TxRx interrupt register bit7:0 | ||
4026 | * 32:47 - Rx interrupt register | ||
4027 | * 31:24 - unused | ||
4028 | * 23:16 - TxRx interrupt register bit15:8 | ||
4029 | * 15:0 - Tx interrupt register | ||
4030 | * | ||
4031 | * Returns: | ||
4032 | * 0: success | ||
4033 | * 1: something went wrong | ||
4034 | */ | ||
4035 | int SkGmOverflowStatus( | ||
4036 | SK_AC *pAC, /* adapter context */ | ||
4037 | SK_IOC IoC, /* IO context */ | ||
4038 | unsigned int Port, /* Port Index (MAC_1 + n) */ | ||
4039 | SK_U16 IStatus, /* Interupt Status from MAC */ | ||
4040 | SK_U64 SK_FAR *pStatus) /* ptr for return overflow status value */ | ||
4041 | { | ||
4042 | SK_U64 Status; /* Overflow status */ | ||
4043 | SK_U16 RegVal; | ||
4044 | |||
4045 | Status = 0; | ||
4046 | |||
4047 | if ((IStatus & GM_IS_RX_CO_OV) != 0) { | ||
4048 | /* this register is self-clearing after read */ | ||
4049 | GM_IN16(IoC, Port, GM_RX_IRQ_SRC, &RegVal); | ||
4050 | Status |= (SK_U64)RegVal << 32; | ||
4051 | } | ||
4052 | |||
4053 | if ((IStatus & GM_IS_TX_CO_OV) != 0) { | ||
4054 | /* this register is self-clearing after read */ | ||
4055 | GM_IN16(IoC, Port, GM_TX_IRQ_SRC, &RegVal); | ||
4056 | Status |= (SK_U64)RegVal; | ||
4057 | } | ||
4058 | |||
4059 | /* this register is self-clearing after read */ | ||
4060 | GM_IN16(IoC, Port, GM_TR_IRQ_SRC, &RegVal); | ||
4061 | /* Rx overflow interrupt register bits (LoByte)*/ | ||
4062 | Status |= (SK_U64)((SK_U8)RegVal) << 48; | ||
4063 | /* Tx overflow interrupt register bits (HiByte)*/ | ||
4064 | Status |= (SK_U64)(RegVal >> 8) << 16; | ||
4065 | |||
4066 | *pStatus = Status; | ||
4067 | |||
4068 | return(0); | ||
4069 | } /* SkGmOverflowStatus */ | ||
4070 | |||
4071 | |||
4072 | #ifndef SK_SLIM | ||
4073 | /****************************************************************************** | ||
4074 | * | ||
4075 | * SkGmCableDiagStatus() - Starts / Gets status of cable diagnostic test | ||
4076 | * | ||
4077 | * Description: | ||
4078 | * starts the cable diagnostic test if 'StartTest' is true | ||
4079 | * gets the results if 'StartTest' is true | ||
4080 | * | ||
4081 | * NOTE: this test is meaningful only when link is down | ||
4082 | * | ||
4083 | * Returns: | ||
4084 | * 0: success | ||
4085 | * 1: no YUKON copper | ||
4086 | * 2: test in progress | ||
4087 | */ | ||
4088 | int SkGmCableDiagStatus( | ||
4089 | SK_AC *pAC, /* adapter context */ | ||
4090 | SK_IOC IoC, /* IO context */ | ||
4091 | int Port, /* Port Index (MAC_1 + n) */ | ||
4092 | SK_BOOL StartTest) /* flag for start / get result */ | ||
4093 | { | ||
4094 | int i; | ||
4095 | SK_U16 RegVal; | ||
4096 | SK_GEPORT *pPrt; | ||
4097 | |||
4098 | pPrt = &pAC->GIni.GP[Port]; | ||
4099 | |||
4100 | if (pPrt->PhyType != SK_PHY_MARV_COPPER) { | ||
4101 | |||
4102 | return(1); | ||
4103 | } | ||
4104 | |||
4105 | if (StartTest) { | ||
4106 | /* only start the cable test */ | ||
4107 | if ((pPrt->PhyId1 & PHY_I1_REV_MSK) < 4) { | ||
4108 | /* apply TDR workaround from Marvell */ | ||
4109 | SkGmPhyWrite(pAC, IoC, Port, 29, 0x001e); | ||
4110 | |||
4111 | SkGmPhyWrite(pAC, IoC, Port, 30, 0xcc00); | ||
4112 | SkGmPhyWrite(pAC, IoC, Port, 30, 0xc800); | ||
4113 | SkGmPhyWrite(pAC, IoC, Port, 30, 0xc400); | ||
4114 | SkGmPhyWrite(pAC, IoC, Port, 30, 0xc000); | ||
4115 | SkGmPhyWrite(pAC, IoC, Port, 30, 0xc100); | ||
4116 | } | ||
4117 | |||
4118 | /* set address to 0 for MDI[0] */ | ||
4119 | SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0); | ||
4120 | |||
4121 | /* Read Cable Diagnostic Reg */ | ||
4122 | SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal); | ||
4123 | |||
4124 | /* start Cable Diagnostic Test */ | ||
4125 | SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, | ||
4126 | (SK_U16)(RegVal | PHY_M_CABD_ENA_TEST)); | ||
4127 | |||
4128 | return(0); | ||
4129 | } | ||
4130 | |||
4131 | /* Read Cable Diagnostic Reg */ | ||
4132 | SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal); | ||
4133 | |||
4134 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, | ||
4135 | ("PHY Cable Diag.=0x%04X\n", RegVal)); | ||
4136 | |||
4137 | if ((RegVal & PHY_M_CABD_ENA_TEST) != 0) { | ||
4138 | /* test is running */ | ||
4139 | return(2); | ||
4140 | } | ||
4141 | |||
4142 | /* get the test results */ | ||
4143 | for (i = 0; i < 4; i++) { | ||
4144 | /* set address to i for MDI[i] */ | ||
4145 | SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, (SK_U16)i); | ||
4146 | |||
4147 | /* get Cable Diagnostic values */ | ||
4148 | SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal); | ||
4149 | |||
4150 | pPrt->PMdiPairLen[i] = (SK_U8)(RegVal & PHY_M_CABD_DIST_MSK); | ||
4151 | |||
4152 | pPrt->PMdiPairSts[i] = (SK_U8)((RegVal & PHY_M_CABD_STAT_MSK) >> 13); | ||
4153 | } | ||
4154 | |||
4155 | return(0); | ||
4156 | } /* SkGmCableDiagStatus */ | ||
4157 | #endif /* !SK_SLIM */ | ||
4158 | #endif /* YUKON */ | ||
4159 | |||
4160 | /* End of file */ | ||